added some tests; improved gradient and image pattern transformations

This commit is contained in:
Thomas Friedel 2019-02-22 16:37:48 +01:00
parent 65ebe6af69
commit 6091afb755
7 changed files with 60 additions and 34 deletions

View file

@ -501,8 +501,6 @@ func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
length := dir.len()
dir = dir.divf(length)
gli.Uniform2f(lgr.canvasSize, float32(cv.fw), float32(cv.fh))
inv := cv.state.transform.invert().f32()
gli.UniformMatrix3fv(lgr.invmat, 1, false, &inv[0])
gli.Uniform2f(lgr.from, float32(from[0]), float32(from[1]))
gli.Uniform2f(lgr.dir, float32(dir[0]), float32(dir[1]))
gli.Uniform1f(lgr.len, float32(length))
@ -521,8 +519,6 @@ func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
length := dir.len()
dir = dir.divf(length)
gli.Uniform2f(rgr.canvasSize, float32(cv.fw), float32(cv.fh))
inv := cv.state.transform.invert().f32()
gli.UniformMatrix3fv(rgr.invmat, 1, false, &inv[0])
gli.Uniform2f(rgr.from, float32(from[0]), float32(from[1]))
gli.Uniform2f(rgr.to, float32(to[0]), float32(to[1]))
gli.Uniform2f(rgr.dir, float32(dir[0]), float32(dir[1]))
@ -538,8 +534,6 @@ func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_2D, img.tex)
gli.Uniform2f(ipr.canvasSize, float32(cv.fw), float32(cv.fh))
inv := cv.state.transform.invert().f32()
gli.UniformMatrix3fv(ipr.invmat, 1, false, &inv[0])
gli.Uniform2f(ipr.imageSize, float32(img.w), float32(img.h))
gli.Uniform1i(ipr.image, 0)
gli.Uniform1f(ipr.globalAlpha, float32(cv.state.globalAlpha))
@ -566,8 +560,6 @@ func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLo
length := dir.len()
dir = dir.divf(length)
gli.Uniform2f(lgar.canvasSize, float32(cv.fw), float32(cv.fh))
inv := cv.state.transform.invert().f32()
gli.UniformMatrix3fv(lgar.invmat, 1, false, &inv[0])
gli.Uniform2f(lgar.from, float32(from[0]), float32(from[1]))
gli.Uniform2f(lgar.dir, float32(dir[0]), float32(dir[1]))
gli.Uniform1f(lgar.len, float32(length))
@ -587,8 +579,6 @@ func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLo
length := dir.len()
dir = dir.divf(length)
gli.Uniform2f(rgar.canvasSize, float32(cv.fw), float32(cv.fh))
inv := cv.state.transform.invert().f32()
gli.UniformMatrix3fv(rgar.invmat, 1, false, &inv[0])
gli.Uniform2f(rgar.from, float32(from[0]), float32(from[1]))
gli.Uniform2f(rgar.to, float32(to[0]), float32(to[1]))
gli.Uniform2f(rgar.dir, float32(dir[0]), float32(dir[1]))
@ -605,8 +595,6 @@ func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLo
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_2D, img.tex)
gli.Uniform2f(ipar.canvasSize, float32(cv.fw), float32(cv.fh))
inv := cv.state.transform.invert().f32()
gli.UniformMatrix3fv(ipar.invmat, 1, false, &inv[0])
gli.Uniform2f(ipar.imageSize, float32(img.w), float32(img.h))
gli.Uniform1i(ipar.image, 0)
gli.Uniform1i(ipar.alphaTex, alphaTexSlot)

View file

@ -3,6 +3,7 @@ package canvas_test
import (
"fmt"
"image/png"
"math"
"os"
"runtime"
"strings"
@ -519,3 +520,52 @@ func TestTransform2(t *testing.T) {
cv.Stroke()
})
}
func TestImage(t *testing.T) {
run(t, func(cv *canvas.Canvas) {
cv.DrawImage("testdata/cat.jpg", 5, 5, 40, 40)
cv.DrawImage("testdata/cat.jpg", 100, 100, 100, 100, 55, 55, 40, 40)
cv.Save()
cv.Translate(75, 25)
cv.Rotate(math.Pi / 2)
cv.Translate(-20, -20)
cv.DrawImage("testdata/cat.jpg", 0, 0, 40, 40)
cv.Restore()
cv.SetTransform(1, 0, 0.2, 1, 0, 0)
cv.DrawImage("testdata/cat.jpg", -8, 55, 40, 40)
})
}
func TestGradient(t *testing.T) {
run(t, func(cv *canvas.Canvas) {
cv.Translate(50, 50)
cv.Scale(0.8, 0.7)
cv.Rotate(math.Pi * 0.1)
cv.Translate(-50, -50)
lg := canvas.NewLinearGradient(10, 10, 40, 20)
lg.AddColorStop(0, 0.5, 0, 0)
lg.AddColorStop(0.5, "#008000")
lg.AddColorStop(1, 0, 0, 128)
cv.SetFillStyle(lg)
cv.FillRect(0, 0, 50, 100)
rg := canvas.NewRadialGradient(75, 15, 10, 75, 75, 20)
rg.AddColorStop(0, 1.0, 0, 0, 0.5)
rg.AddColorStop(0.5, "#00FF0080")
rg.AddColorStop(1, 0, 0, 255, 128)
cv.SetFillStyle(rg)
cv.FillRect(50, 0, 50, 100)
})
}
func TestImagePattern(t *testing.T) {
run(t, func(cv *canvas.Canvas) {
cv.Translate(50, 50)
cv.Scale(0.95, 1.05)
cv.Rotate(-math.Pi * 0.1)
cv.SetFillStyle("testdata/cat.jpg")
cv.FillRect(-40, -40, 80, 80)
})
}

View file

@ -61,14 +61,12 @@ var linearGradientFS = `
precision mediump float;
#endif
varying vec2 v_cp;
uniform mat3 invmat;
uniform sampler2D gradient;
uniform vec2 from, dir;
uniform float len;
uniform float globalAlpha;
void main() {
vec3 untf = vec3(v_cp, 1.0) * invmat;
vec2 v = untf.xy - from;
vec2 v = v_cp - from;
float r = dot(v, dir) / len;
r = clamp(r, 0.0, 1.0);
vec4 col = texture2D(gradient, vec2(r, 0.0));
@ -90,7 +88,6 @@ var radialGradientFS = `
precision mediump float;
#endif
varying vec2 v_cp;
uniform mat3 invmat;
uniform sampler2D gradient;
uniform vec2 from, to, dir;
uniform float radFrom, radTo;
@ -100,13 +97,12 @@ bool isNaN(float v) {
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
}
void main() {
vec3 untf = vec3(v_cp, 1.0) * invmat;
float o_a = 0.5 * sqrt(
pow(-2.0*from.x*from.x+2.0*from.x*to.x+2.0*from.x*untf.x-2.0*to.x*untf.x-2.0*from.y*from.y+2.0*from.y*to.y+2.0*from.y*untf.y-2.0*to.y*untf.y+2.0*radFrom*radFrom-2.0*radFrom*radTo, 2.0)
-4.0*(from.x*from.x-2.0*from.x*untf.x+untf.x*untf.x+from.y*from.y-2.0*from.y*untf.y+untf.y*untf.y-radFrom*radFrom)
pow(-2.0*from.x*from.x+2.0*from.x*to.x+2.0*from.x*v_cp.x-2.0*to.x*v_cp.x-2.0*from.y*from.y+2.0*from.y*to.y+2.0*from.y*v_cp.y-2.0*to.y*v_cp.y+2.0*radFrom*radFrom-2.0*radFrom*radTo, 2.0)
-4.0*(from.x*from.x-2.0*from.x*v_cp.x+v_cp.x*v_cp.x+from.y*from.y-2.0*from.y*v_cp.y+v_cp.y*v_cp.y-radFrom*radFrom)
*(from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo)
);
float o_b = (from.x*from.x-from.x*to.x-from.x*untf.x+to.x*untf.x+from.y*from.y-from.y*to.y-from.y*untf.y+to.y*untf.y-radFrom*radFrom+radFrom*radTo);
float o_b = (from.x*from.x-from.x*to.x-from.x*v_cp.x+to.x*v_cp.x+from.y*from.y-from.y*to.y-from.y*v_cp.y+to.y*v_cp.y-radFrom*radFrom+radFrom*radTo);
float o_c = (from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo);
float o1 = (-o_a + o_b) / o_c;
float o2 = (o_a + o_b) / o_c;
@ -136,12 +132,10 @@ precision mediump float;
#endif
varying vec2 v_cp;
uniform vec2 imageSize;
uniform mat3 invmat;
uniform sampler2D image;
uniform float globalAlpha;
void main() {
vec3 untf = vec3(v_cp, 1.0) * invmat;
vec4 col = texture2D(image, mod(untf.xy / imageSize, 1.0));
vec4 col = texture2D(image, mod(v_cp / imageSize, 1.0));
col.a *= globalAlpha;
gl_FragColor = col;
}`
@ -187,15 +181,13 @@ precision mediump float;
varying vec2 v_cp;
varying vec2 v_atc;
varying vec2 v_texCoord;
uniform mat3 invmat;
uniform sampler2D gradient;
uniform vec2 from, dir;
uniform float len;
uniform sampler2D alphaTex;
uniform float globalAlpha;
void main() {
vec3 untf = vec3(v_cp, 1.0) * invmat;
vec2 v = untf.xy - from;
vec2 v = v_cp.xy - from;
float r = dot(v, dir) / len;
r = clamp(r, 0.0, 1.0);
vec4 col = texture2D(gradient, vec2(r, 0.0));
@ -220,7 +212,6 @@ precision mediump float;
#endif
varying vec2 v_cp;
varying vec2 v_atc;
uniform mat3 invmat;
uniform sampler2D gradient;
uniform vec2 from, to, dir;
uniform float radFrom, radTo;
@ -231,13 +222,12 @@ bool isNaN(float v) {
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
}
void main() {
vec3 untf = vec3(v_cp, 1.0) * invmat;
float o_a = 0.5 * sqrt(
pow(-2.0*from.x*from.x+2.0*from.x*to.x+2.0*from.x*untf.x-2.0*to.x*untf.x-2.0*from.y*from.y+2.0*from.y*to.y+2.0*from.y*untf.y-2.0*to.y*untf.y+2.0*radFrom*radFrom-2.0*radFrom*radTo, 2.0)
-4.0*(from.x*from.x-2.0*from.x*untf.x+untf.x*untf.x+from.y*from.y-2.0*from.y*untf.y+untf.y*untf.y-radFrom*radFrom)
pow(-2.0*from.x*from.x+2.0*from.x*to.x+2.0*from.x*v_cp.x-2.0*to.x*v_cp.x-2.0*from.y*from.y+2.0*from.y*to.y+2.0*from.y*v_cp.y-2.0*to.y*v_cp.y+2.0*radFrom*radFrom-2.0*radFrom*radTo, 2.0)
-4.0*(from.x*from.x-2.0*from.x*v_cp.x+v_cp.x*v_cp.x+from.y*from.y-2.0*from.y*v_cp.y+v_cp.y*v_cp.y-radFrom*radFrom)
*(from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo)
);
float o_b = (from.x*from.x-from.x*to.x-from.x*untf.x+to.x*untf.x+from.y*from.y-from.y*to.y-from.y*untf.y+to.y*untf.y-radFrom*radFrom+radFrom*radTo);
float o_b = (from.x*from.x-from.x*to.x-from.x*v_cp.x+to.x*v_cp.x+from.y*from.y-from.y*to.y-from.y*v_cp.y+to.y*v_cp.y-radFrom*radFrom+radFrom*radTo);
float o_c = (from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo);
float o1 = (-o_a + o_b) / o_c;
float o2 = (o_a + o_b) / o_c;
@ -270,13 +260,11 @@ precision mediump float;
varying vec2 v_cp;
varying vec2 v_atc;
uniform vec2 imageSize;
uniform mat3 invmat;
uniform sampler2D image;
uniform sampler2D alphaTex;
uniform float globalAlpha;
void main() {
vec3 untf = vec3(v_cp, 1.0) * invmat;
vec4 col = texture2D(image, mod(untf.xy / imageSize, 1.0));
vec4 col = texture2D(image, mod(v_cp / imageSize, 1.0));
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
gl_FragColor = col;
}`

BIN
testdata/Gradient.png vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
testdata/Image.png vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
testdata/ImagePattern.png vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
testdata/cat.jpg vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB