implemented image pattern transformation
This commit is contained in:
parent
3a749132e2
commit
a5d921223f
4 changed files with 51 additions and 18 deletions
|
@ -108,6 +108,7 @@ type Image interface {
|
||||||
|
|
||||||
type ImagePatternData struct {
|
type ImagePatternData struct {
|
||||||
Image Image
|
Image Image
|
||||||
|
Transform [9]float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImagePattern interface {
|
type ImagePattern interface {
|
||||||
|
|
|
@ -432,13 +432,19 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle) (vertexLoc uint32)
|
||||||
return b.rgr.Vertex
|
return b.rgr.Vertex
|
||||||
}
|
}
|
||||||
if ip := style.ImagePattern; ip != nil {
|
if ip := style.ImagePattern; ip != nil {
|
||||||
img := ip.(*ImagePattern).data.Image.(*Image)
|
ipd := ip.(*ImagePattern).data
|
||||||
|
img := ipd.Image.(*Image)
|
||||||
gl.UseProgram(b.ipr.ID)
|
gl.UseProgram(b.ipr.ID)
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, img.tex)
|
gl.BindTexture(gl.TEXTURE_2D, img.tex)
|
||||||
gl.Uniform2f(b.ipr.CanvasSize, float32(b.fw), float32(b.fh))
|
gl.Uniform2f(b.ipr.CanvasSize, float32(b.fw), float32(b.fh))
|
||||||
gl.Uniform2f(b.ipr.ImageSize, float32(img.w), float32(img.h))
|
gl.Uniform2f(b.ipr.ImageSize, float32(img.w), float32(img.h))
|
||||||
gl.Uniform1i(b.ipr.Image, 0)
|
gl.Uniform1i(b.ipr.Image, 0)
|
||||||
|
var f32mat [9]float32
|
||||||
|
for i, v := range ipd.Transform {
|
||||||
|
f32mat[i] = float32(v)
|
||||||
|
}
|
||||||
|
gl.UniformMatrix3fv(b.ipr.ImageTransform, 1, false, &f32mat[0])
|
||||||
gl.Uniform1f(b.ipr.GlobalAlpha, float32(style.Color.A)/255)
|
gl.Uniform1f(b.ipr.GlobalAlpha, float32(style.Color.A)/255)
|
||||||
return b.ipr.Vertex
|
return b.ipr.Vertex
|
||||||
}
|
}
|
||||||
|
@ -489,13 +495,19 @@ func (b *GoGLBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot
|
||||||
return b.rgar.Vertex, b.rgar.AlphaTexCoord
|
return b.rgar.Vertex, b.rgar.AlphaTexCoord
|
||||||
}
|
}
|
||||||
if ip := style.ImagePattern; ip != nil {
|
if ip := style.ImagePattern; ip != nil {
|
||||||
img := ip.(*ImagePattern).data.Image.(*Image)
|
ipd := ip.(*ImagePattern).data
|
||||||
|
img := ipd.Image.(*Image)
|
||||||
gl.UseProgram(b.ipar.ID)
|
gl.UseProgram(b.ipar.ID)
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, img.tex)
|
gl.BindTexture(gl.TEXTURE_2D, img.tex)
|
||||||
gl.Uniform2f(b.ipar.CanvasSize, float32(b.fw), float32(b.fh))
|
gl.Uniform2f(b.ipar.CanvasSize, float32(b.fw), float32(b.fh))
|
||||||
gl.Uniform2f(b.ipar.ImageSize, float32(img.w), float32(img.h))
|
gl.Uniform2f(b.ipar.ImageSize, float32(img.w), float32(img.h))
|
||||||
gl.Uniform1i(b.ipar.Image, 0)
|
gl.Uniform1i(b.ipar.Image, 0)
|
||||||
|
var f32mat [9]float32
|
||||||
|
for i, v := range ipd.Transform {
|
||||||
|
f32mat[i] = float32(v)
|
||||||
|
}
|
||||||
|
gl.UniformMatrix3fv(b.ipr.ImageTransform, 1, false, &f32mat[0])
|
||||||
gl.Uniform1i(b.ipar.AlphaTex, alphaTexSlot)
|
gl.Uniform1i(b.ipar.AlphaTex, alphaTexSlot)
|
||||||
gl.Uniform1f(b.ipar.GlobalAlpha, float32(style.Color.A)/255)
|
gl.Uniform1f(b.ipar.GlobalAlpha, float32(style.Color.A)/255)
|
||||||
return b.ipar.Vertex, b.ipar.AlphaTexCoord
|
return b.ipar.Vertex, b.ipar.AlphaTexCoord
|
||||||
|
|
|
@ -132,9 +132,11 @@ precision mediump float;
|
||||||
varying vec2 v_cp;
|
varying vec2 v_cp;
|
||||||
uniform vec2 imageSize;
|
uniform vec2 imageSize;
|
||||||
uniform sampler2D image;
|
uniform sampler2D image;
|
||||||
|
uniform mat3 imageTransform;
|
||||||
uniform float globalAlpha;
|
uniform float globalAlpha;
|
||||||
void main() {
|
void main() {
|
||||||
vec4 col = texture2D(image, mod(v_cp / imageSize, 1.0));
|
vec3 tfp = vec3(v_cp, 1.0) * imageTransform;
|
||||||
|
vec4 col = texture2D(image, mod(tfp.xy / imageSize, 1.0));
|
||||||
col.a *= globalAlpha;
|
col.a *= globalAlpha;
|
||||||
gl_FragColor = col;
|
gl_FragColor = col;
|
||||||
}`
|
}`
|
||||||
|
@ -259,10 +261,12 @@ varying vec2 v_cp;
|
||||||
varying vec2 v_atc;
|
varying vec2 v_atc;
|
||||||
uniform vec2 imageSize;
|
uniform vec2 imageSize;
|
||||||
uniform sampler2D image;
|
uniform sampler2D image;
|
||||||
|
uniform mat3 imageTransform;
|
||||||
uniform sampler2D alphaTex;
|
uniform sampler2D alphaTex;
|
||||||
uniform float globalAlpha;
|
uniform float globalAlpha;
|
||||||
void main() {
|
void main() {
|
||||||
vec4 col = texture2D(image, mod(v_cp / imageSize, 1.0));
|
vec3 tfp = vec3(v_cp, 1.0) * imageTransform;
|
||||||
|
vec4 col = texture2D(image, mod(tfp.xy / imageSize, 1.0));
|
||||||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||||
gl_FragColor = col;
|
gl_FragColor = col;
|
||||||
}`
|
}`
|
||||||
|
@ -404,6 +408,7 @@ type imagePatternShader struct {
|
||||||
CanvasSize int32
|
CanvasSize int32
|
||||||
ImageSize int32
|
ImageSize int32
|
||||||
Image int32
|
Image int32
|
||||||
|
ImageTransform int32
|
||||||
GlobalAlpha int32
|
GlobalAlpha int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,6 +456,7 @@ type imagePatternAlphaShader struct {
|
||||||
CanvasSize int32
|
CanvasSize int32
|
||||||
ImageSize int32
|
ImageSize int32
|
||||||
Image int32
|
Image int32
|
||||||
|
ImageTransform int32
|
||||||
AlphaTex int32
|
AlphaTex int32
|
||||||
GlobalAlpha int32
|
GlobalAlpha int32
|
||||||
}
|
}
|
||||||
|
|
14
images.go
14
images.go
|
@ -189,15 +189,29 @@ func (cv *Canvas) PutImageData(img *image.RGBA, x, y int) {
|
||||||
type ImagePattern struct {
|
type ImagePattern struct {
|
||||||
cv *Canvas
|
cv *Canvas
|
||||||
img *Image
|
img *Image
|
||||||
|
tf [9]float64
|
||||||
ip backendbase.ImagePattern
|
ip backendbase.ImagePattern
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ip *ImagePattern) data() backendbase.ImagePatternData {
|
func (ip *ImagePattern) data() backendbase.ImagePatternData {
|
||||||
return backendbase.ImagePatternData{
|
return backendbase.ImagePatternData{
|
||||||
Image: ip.img.img,
|
Image: ip.img.img,
|
||||||
|
Transform: ip.tf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTransform changes the transformation of the image pattern
|
||||||
|
// to the given matrix. The matrix is a 3x3 matrix, but three
|
||||||
|
// of the values are always identity values
|
||||||
|
func (ip *ImagePattern) SetTransform(tf [6]float64) {
|
||||||
|
ip.tf = [9]float64{
|
||||||
|
tf[0], tf[1], 0,
|
||||||
|
tf[2], tf[3], 0,
|
||||||
|
tf[4], tf[5], 1,
|
||||||
|
}
|
||||||
|
ip.ip.Replace(ip.data())
|
||||||
|
}
|
||||||
|
|
||||||
// CreatePattern creates a new image pattern with the specified
|
// CreatePattern creates a new image pattern with the specified
|
||||||
// image and repetition
|
// image and repetition
|
||||||
func (cv *Canvas) CreatePattern(src interface{}, repetition string) *ImagePattern {
|
func (cv *Canvas) CreatePattern(src interface{}, repetition string) *ImagePattern {
|
||||||
|
|
Loading…
Reference in a new issue