implemented imapge pattern repeat types

This commit is contained in:
Thomas Friedel 2019-04-25 17:58:21 +02:00
parent a5d921223f
commit f89b3eccdc
5 changed files with 69 additions and 6 deletions

View file

@ -109,8 +109,19 @@ type Image interface {
type ImagePatternData struct { type ImagePatternData struct {
Image Image Image Image
Transform [9]float64 Transform [9]float64
Repeat ImagePatternRepeat
} }
type ImagePatternRepeat uint8
// Image pattern repeat constants
const (
Repeat ImagePatternRepeat = iota
RepeatX
RepeatY
NoRepeat
)
type ImagePattern interface { type ImagePattern interface {
Delete() Delete()
Replace(data ImagePatternData) Replace(data ImagePatternData)

View file

@ -445,6 +445,16 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle) (vertexLoc uint32)
f32mat[i] = float32(v) f32mat[i] = float32(v)
} }
gl.UniformMatrix3fv(b.ipr.ImageTransform, 1, false, &f32mat[0]) gl.UniformMatrix3fv(b.ipr.ImageTransform, 1, false, &f32mat[0])
switch ipd.Repeat {
case backendbase.Repeat:
gl.Uniform2f(b.ipr.Repeat, 1, 1)
case backendbase.RepeatX:
gl.Uniform2f(b.ipr.Repeat, 1, 0)
case backendbase.RepeatY:
gl.Uniform2f(b.ipr.Repeat, 0, 1)
case backendbase.NoRepeat:
gl.Uniform2f(b.ipr.Repeat, 0, 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
} }
@ -508,6 +518,16 @@ func (b *GoGLBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot
f32mat[i] = float32(v) f32mat[i] = float32(v)
} }
gl.UniformMatrix3fv(b.ipr.ImageTransform, 1, false, &f32mat[0]) gl.UniformMatrix3fv(b.ipr.ImageTransform, 1, false, &f32mat[0])
switch ipd.Repeat {
case backendbase.Repeat:
gl.Uniform2f(b.ipr.Repeat, 1, 1)
case backendbase.RepeatX:
gl.Uniform2f(b.ipr.Repeat, 1, 0)
case backendbase.RepeatY:
gl.Uniform2f(b.ipr.Repeat, 0, 1)
case backendbase.NoRepeat:
gl.Uniform2f(b.ipr.Repeat, 0, 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

@ -133,10 +133,18 @@ varying vec2 v_cp;
uniform vec2 imageSize; uniform vec2 imageSize;
uniform sampler2D image; uniform sampler2D image;
uniform mat3 imageTransform; uniform mat3 imageTransform;
uniform vec2 repeat;
uniform float globalAlpha; uniform float globalAlpha;
void main() { void main() {
vec3 tfp = vec3(v_cp, 1.0) * imageTransform; vec3 tfpt = vec3(v_cp, 1.0) * imageTransform;
vec4 col = texture2D(image, mod(tfp.xy / imageSize, 1.0)); vec2 imgpt = tfpt.xy / imageSize;
vec4 col = texture2D(image, mod(imgpt, 1.0));
if (imgpt.x < 0.0 || imgpt.x > 1.0) {
col *= repeat.x;
}
if (imgpt.y < 0.0 || imgpt.y > 1.0) {
col *= repeat.y;
}
col.a *= globalAlpha; col.a *= globalAlpha;
gl_FragColor = col; gl_FragColor = col;
}` }`
@ -262,11 +270,19 @@ varying vec2 v_atc;
uniform vec2 imageSize; uniform vec2 imageSize;
uniform sampler2D image; uniform sampler2D image;
uniform mat3 imageTransform; uniform mat3 imageTransform;
uniform vec2 repeat;
uniform sampler2D alphaTex; uniform sampler2D alphaTex;
uniform float globalAlpha; uniform float globalAlpha;
void main() { void main() {
vec3 tfp = vec3(v_cp, 1.0) * imageTransform; vec3 tfpt = vec3(v_cp, 1.0) * imageTransform;
vec4 col = texture2D(image, mod(tfp.xy / imageSize, 1.0)); vec2 imgpt = tfpt.xy / imageSize;
vec4 col = texture2D(image, mod(imgpt, 1.0));
if (imgpt.x < 0.0 || imgpt.x > 1.0) {
col *= repeat.x;
}
if (imgpt.y < 0.0 || imgpt.y > 1.0) {
col *= repeat.y;
}
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha; col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
gl_FragColor = col; gl_FragColor = col;
}` }`
@ -409,6 +425,7 @@ type imagePatternShader struct {
ImageSize int32 ImageSize int32
Image int32 Image int32
ImageTransform int32 ImageTransform int32
Repeat int32
GlobalAlpha int32 GlobalAlpha int32
} }
@ -457,6 +474,7 @@ type imagePatternAlphaShader struct {
ImageSize int32 ImageSize int32
Image int32 Image int32
ImageTransform int32 ImageTransform int32
Repeat int32
AlphaTex int32 AlphaTex int32
GlobalAlpha int32 GlobalAlpha int32
} }

View file

@ -223,7 +223,7 @@ func (cv *Canvas) parseStyle(value ...interface{}) drawStyle {
switch v := value[0].(type) { switch v := value[0].(type) {
case *Image, string: case *Image, string:
if _, ok := imagePatterns[v]; !ok { if _, ok := imagePatterns[v]; !ok {
imagePatterns[v] = cv.CreatePattern(v, "") imagePatterns[v] = cv.CreatePattern(v, Repeat)
} }
style.imagePattern = imagePatterns[v] style.imagePattern = imagePatterns[v]
case *ImagePattern: case *ImagePattern:

View file

@ -190,13 +190,25 @@ type ImagePattern struct {
cv *Canvas cv *Canvas
img *Image img *Image
tf [9]float64 tf [9]float64
rep imagePatternRepeat
ip backendbase.ImagePattern ip backendbase.ImagePattern
} }
type imagePatternRepeat uint8
// Image pattern repeat constants
const (
Repeat imagePatternRepeat = imagePatternRepeat(backendbase.Repeat)
RepeatX = imagePatternRepeat(backendbase.RepeatX)
RepeatY = imagePatternRepeat(backendbase.RepeatY)
NoRepeat = imagePatternRepeat(backendbase.NoRepeat)
)
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, Transform: ip.tf,
Repeat: backendbase.ImagePatternRepeat(ip.rep),
} }
} }
@ -214,10 +226,12 @@ func (ip *ImagePattern) SetTransform(tf [6]float64) {
// 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{}, repeat imagePatternRepeat) *ImagePattern {
ip := &ImagePattern{ ip := &ImagePattern{
cv: cv, cv: cv,
img: cv.getImage(src), img: cv.getImage(src),
rep: repeat,
tf: [9]float64{1, 0, 0, 0, 1, 0, 0, 0, 1},
} }
if ip.img != nil { if ip.img != nil {
ip.ip = cv.b.LoadImagePattern(ip.data()) ip.ip = cv.b.LoadImagePattern(ip.data())