added some tests; improved gradient and image pattern transformations
This commit is contained in:
parent
65ebe6af69
commit
6091afb755
7 changed files with 60 additions and 34 deletions
12
canvas.go
12
canvas.go
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
32
shaders.go
32
shaders.go
|
@ -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
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
BIN
testdata/Image.png
vendored
Executable file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
testdata/ImagePattern.png
vendored
Executable file
BIN
testdata/ImagePattern.png
vendored
Executable file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
testdata/cat.jpg
vendored
Executable file
BIN
testdata/cat.jpg
vendored
Executable file
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
Loading…
Reference in a new issue