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 {
Image Image
Image Image
Transform [9]float64
}
type ImagePattern interface {

View file

@ -432,13 +432,19 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle) (vertexLoc uint32)
return b.rgr.Vertex
}
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.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, img.tex)
gl.Uniform2f(b.ipr.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.ipr.ImageSize, float32(img.w), float32(img.h))
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)
return b.ipr.Vertex
}
@ -489,13 +495,19 @@ func (b *GoGLBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot
return b.rgar.Vertex, b.rgar.AlphaTexCoord
}
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.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, img.tex)
gl.Uniform2f(b.ipar.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.ipar.ImageSize, float32(img.w), float32(img.h))
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.Uniform1f(b.ipar.GlobalAlpha, float32(style.Color.A)/255)
return b.ipar.Vertex, b.ipar.AlphaTexCoord

View file

@ -132,9 +132,11 @@ precision mediump float;
varying vec2 v_cp;
uniform vec2 imageSize;
uniform sampler2D image;
uniform mat3 imageTransform;
uniform float globalAlpha;
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;
gl_FragColor = col;
}`
@ -259,10 +261,12 @@ varying vec2 v_cp;
varying vec2 v_atc;
uniform vec2 imageSize;
uniform sampler2D image;
uniform mat3 imageTransform;
uniform sampler2D alphaTex;
uniform float globalAlpha;
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;
gl_FragColor = col;
}`
@ -400,11 +404,12 @@ type radialGradientShader struct {
type imagePatternShader struct {
shaderProgram
Vertex uint32
CanvasSize int32
ImageSize int32
Image int32
GlobalAlpha int32
Vertex uint32
CanvasSize int32
ImageSize int32
Image int32
ImageTransform int32
GlobalAlpha int32
}
type solidAlphaShader struct {
@ -446,13 +451,14 @@ type radialGradientAlphaShader struct {
type imagePatternAlphaShader struct {
shaderProgram
Vertex uint32
AlphaTexCoord uint32
CanvasSize int32
ImageSize int32
Image int32
AlphaTex int32
GlobalAlpha int32
Vertex uint32
AlphaTexCoord uint32
CanvasSize int32
ImageSize int32
Image int32
ImageTransform int32
AlphaTex int32
GlobalAlpha int32
}
type gaussianShader struct {

View file

@ -189,15 +189,29 @@ func (cv *Canvas) PutImageData(img *image.RGBA, x, y int) {
type ImagePattern struct {
cv *Canvas
img *Image
tf [9]float64
ip backendbase.ImagePattern
}
func (ip *ImagePattern) data() 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
// image and repetition
func (cv *Canvas) CreatePattern(src interface{}, repetition string) *ImagePattern {