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

@ -107,7 +107,8 @@ 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;
}` }`
@ -400,11 +404,12 @@ type radialGradientShader struct {
type imagePatternShader struct { type imagePatternShader struct {
shaderProgram shaderProgram
Vertex uint32 Vertex uint32
CanvasSize int32 CanvasSize int32
ImageSize int32 ImageSize int32
Image int32 Image int32
GlobalAlpha int32 ImageTransform int32
GlobalAlpha int32
} }
type solidAlphaShader struct { type solidAlphaShader struct {
@ -446,13 +451,14 @@ type radialGradientAlphaShader struct {
type imagePatternAlphaShader struct { type imagePatternAlphaShader struct {
shaderProgram shaderProgram
Vertex uint32 Vertex uint32
AlphaTexCoord uint32 AlphaTexCoord uint32
CanvasSize int32 CanvasSize int32
ImageSize int32 ImageSize int32
Image int32 Image int32
AlphaTex int32 ImageTransform int32
GlobalAlpha int32 AlphaTex int32
GlobalAlpha int32
} }
type gaussianShader struct { type gaussianShader struct {

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 {