implemented image pattern transformation

This commit is contained in:
Thomas Friedel 2019-04-25 17:46:53 +02:00
parent 3a749132e2
commit a5d921223f
4 changed files with 51 additions and 18 deletions

View file

@ -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 {

View file

@ -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

View file

@ -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
} }

View file

@ -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 {