implemented globalAlpha
This commit is contained in:
parent
3fcf95cc86
commit
e75355ac37
6 changed files with 688 additions and 607 deletions
17
canvas.go
17
canvas.go
|
@ -33,6 +33,7 @@ type drawState struct {
|
|||
lineWidth float64
|
||||
lineJoin lineJoin
|
||||
lineEnd lineEnd
|
||||
globalAlpha float64
|
||||
|
||||
lineDash []float64
|
||||
lineDashPoint int
|
||||
|
@ -86,6 +87,9 @@ func New(x, y, w, h int) *Canvas {
|
|||
stateStack: make([]drawState, 0, 20),
|
||||
}
|
||||
cv.state.lineWidth = 1
|
||||
cv.state.globalAlpha = 1
|
||||
cv.state.fill.color = glColor{a: 1}
|
||||
cv.state.stroke.color = glColor{a: 1}
|
||||
cv.state.transform = matIdentity()
|
||||
return cv
|
||||
}
|
||||
|
@ -329,6 +333,7 @@ func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
|
|||
gli.Uniform2f(lgr.dir, float32(dir[0]), float32(dir[1]))
|
||||
gli.Uniform1f(lgr.len, float32(length))
|
||||
gli.Uniform1i(lgr.gradient, 0)
|
||||
gli.Uniform1f(lgr.globalAlpha, float32(cv.state.globalAlpha))
|
||||
return lgr.vertex
|
||||
}
|
||||
if rg := style.radialGradient; rg != nil {
|
||||
|
@ -351,6 +356,7 @@ func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
|
|||
gli.Uniform1f(rgr.radTo, float32(rg.radTo))
|
||||
gli.Uniform1f(rgr.len, float32(length))
|
||||
gli.Uniform1i(rgr.gradient, 0)
|
||||
gli.Uniform1f(rgr.globalAlpha, float32(cv.state.globalAlpha))
|
||||
return rgr.vertex
|
||||
}
|
||||
if img := style.image; img != nil {
|
||||
|
@ -362,6 +368,7 @@ func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
|
|||
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))
|
||||
return ipr.vertex
|
||||
}
|
||||
|
||||
|
@ -369,6 +376,7 @@ func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
|
|||
gli.Uniform2f(sr.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
c := style.color
|
||||
gli.Uniform4f(sr.color, float32(c.r), float32(c.g), float32(c.b), float32(c.a))
|
||||
gli.Uniform1f(sr.globalAlpha, float32(cv.state.globalAlpha))
|
||||
return sr.vertex
|
||||
}
|
||||
|
||||
|
@ -391,6 +399,7 @@ func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLo
|
|||
gli.Uniform1f(lgar.len, float32(length))
|
||||
gli.Uniform1i(lgar.gradient, 0)
|
||||
gli.Uniform1i(lgar.alphaTex, alphaTexSlot)
|
||||
gli.Uniform1f(lgar.globalAlpha, float32(cv.state.globalAlpha))
|
||||
return lgar.vertex, lgar.alphaTexCoord
|
||||
}
|
||||
if rg := style.radialGradient; rg != nil {
|
||||
|
@ -414,6 +423,7 @@ func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLo
|
|||
gli.Uniform1f(rgar.len, float32(length))
|
||||
gli.Uniform1i(rgar.gradient, 0)
|
||||
gli.Uniform1i(rgar.alphaTex, alphaTexSlot)
|
||||
gli.Uniform1f(rgar.globalAlpha, float32(cv.state.globalAlpha))
|
||||
return rgar.vertex, rgar.alphaTexCoord
|
||||
}
|
||||
if img := style.image; img != nil {
|
||||
|
@ -426,6 +436,7 @@ func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLo
|
|||
gli.Uniform2f(ipar.imageSize, float32(img.w), float32(img.h))
|
||||
gli.Uniform1i(ipar.image, 0)
|
||||
gli.Uniform1i(ipar.alphaTex, alphaTexSlot)
|
||||
gli.Uniform1f(ipar.globalAlpha, float32(cv.state.globalAlpha))
|
||||
return ipar.vertex, ipar.alphaTexCoord
|
||||
}
|
||||
|
||||
|
@ -434,6 +445,7 @@ func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLo
|
|||
c := style.color
|
||||
gli.Uniform4f(sar.color, float32(c.r), float32(c.g), float32(c.b), float32(c.a))
|
||||
gli.Uniform1i(sar.alphaTex, alphaTexSlot)
|
||||
gli.Uniform1f(sar.globalAlpha, float32(cv.state.globalAlpha))
|
||||
return sar.vertex, sar.alphaTexCoord
|
||||
}
|
||||
|
||||
|
@ -498,6 +510,11 @@ func (cv *Canvas) SetLineDash(dash []float64) {
|
|||
cv.state.lineDashOffset = 0
|
||||
}
|
||||
|
||||
// SetGlobalAlpha sets the global alpha value
|
||||
func (cv *Canvas) SetGlobalAlpha(alpha float64) {
|
||||
cv.state.globalAlpha = alpha
|
||||
}
|
||||
|
||||
// Save saves the current draw state to a stack
|
||||
func (cv *Canvas) Save() {
|
||||
cv.stateStack = append(cv.stateStack, cv.state)
|
||||
|
|
|
@ -85,6 +85,7 @@ func (cv *Canvas) PutImageData(img *image.RGBA, x, y int) {
|
|||
gli.UseProgram(ir.id)
|
||||
gli.Uniform1i(ir.image, 0)
|
||||
gli.Uniform2f(ir.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
gli.Uniform1f(ir.globalAlpha, 1)
|
||||
gli.VertexAttribPointer(ir.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.VertexAttribPointer(ir.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
||||
gli.EnableVertexAttribArray(ir.vertex)
|
||||
|
|
|
@ -260,6 +260,7 @@ func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
|
|||
gli.UseProgram(ir.id)
|
||||
gli.Uniform1i(ir.image, 0)
|
||||
gli.Uniform2f(ir.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
gli.Uniform1f(ir.globalAlpha, float32(cv.state.globalAlpha))
|
||||
gli.VertexAttribPointer(ir.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.VertexAttribPointer(ir.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
||||
gli.EnableVertexAttribArray(ir.vertex)
|
||||
|
|
1120
made_shaders.go
1120
made_shaders.go
File diff suppressed because it is too large
Load diff
67
paths.go
67
paths.go
|
@ -465,31 +465,65 @@ func (cv *Canvas) Fill() {
|
|||
return
|
||||
}
|
||||
cv.activate()
|
||||
|
||||
var triBuf [1000]float32
|
||||
tris := triBuf[:0]
|
||||
tris = append(tris, 0, 0, float32(cv.fw), 0, float32(cv.fw), float32(cv.fh), 0, 0, float32(cv.fw), float32(cv.fh), 0, float32(cv.fh))
|
||||
|
||||
start := 0
|
||||
for i, p := range cv.polyPath {
|
||||
if p.flags&pathMove == 0 {
|
||||
continue
|
||||
}
|
||||
if i >= start+3 {
|
||||
cv.fillPoly(cv.polyPath[start:i])
|
||||
tris = cv.appendSubPathTriangles(tris, cv.polyPath[start:i])
|
||||
}
|
||||
start = i
|
||||
}
|
||||
if len(cv.polyPath) >= start+3 {
|
||||
cv.fillPoly(cv.polyPath[start:])
|
||||
tris = cv.appendSubPathTriangles(tris, cv.polyPath[start:])
|
||||
}
|
||||
}
|
||||
|
||||
func (cv *Canvas) fillPoly(path []pathPoint) {
|
||||
if len(path) < 3 {
|
||||
if len(tris) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
cv.activate()
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
var triBuf [1000]float32
|
||||
var tris []float32
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.ColorMask(false, false, false, false)
|
||||
gli.StencilFunc(gl_ALWAYS, 1, 0xFF)
|
||||
gli.StencilOp(gl_REPLACE, gl_REPLACE, gl_REPLACE)
|
||||
gli.StencilMask(0x01)
|
||||
|
||||
gli.UseProgram(sr.id)
|
||||
gli.Uniform4f(sr.color, 0, 0, 0, 0)
|
||||
gli.Uniform2f(sr.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
|
||||
gli.EnableVertexAttribArray(sr.vertex)
|
||||
gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.DrawArrays(gl_TRIANGLES, 6, int32(len(tris)/2-6))
|
||||
gli.DisableVertexAttribArray(sr.vertex)
|
||||
|
||||
gli.ColorMask(true, true, true, true)
|
||||
|
||||
gli.StencilFunc(gl_EQUAL, 1, 0xFF)
|
||||
gli.StencilMask(0xFF)
|
||||
|
||||
vertex := cv.useShader(&cv.state.fill)
|
||||
gli.EnableVertexAttribArray(vertex)
|
||||
gli.VertexAttribPointer(vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.DrawArrays(gl_TRIANGLES, 0, 6)
|
||||
gli.DisableVertexAttribArray(vertex)
|
||||
|
||||
gli.StencilOp(gl_KEEP, gl_KEEP, gl_KEEP)
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
|
||||
gli.StencilMask(0x01)
|
||||
gli.Clear(gl_STENCIL_BUFFER_BIT)
|
||||
gli.StencilMask(0xFF)
|
||||
}
|
||||
|
||||
func (cv *Canvas) appendSubPathTriangles(tris []float32, path []pathPoint) []float32 {
|
||||
if path[len(path)-1].flags&pathIsConvex != 0 {
|
||||
p0, p1 := path[0].tf, path[1].tf
|
||||
last := len(path)
|
||||
|
@ -500,18 +534,9 @@ func (cv *Canvas) fillPoly(path []pathPoint) {
|
|||
}
|
||||
} else {
|
||||
path = cv.cutIntersections(path)
|
||||
tris = triangulatePath(path, triBuf[:0])
|
||||
if len(tris) == 0 {
|
||||
return
|
||||
tris = triangulatePath(path, tris)
|
||||
}
|
||||
}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl_STREAM_DRAW)
|
||||
|
||||
vertex := cv.useShader(&cv.state.fill)
|
||||
gli.EnableVertexAttribArray(vertex)
|
||||
gli.VertexAttribPointer(vertex, 2, gl_FLOAT, false, 0, nil)
|
||||
gli.DrawArrays(gl_TRIANGLES, 0, int32(len(tris)/2))
|
||||
gli.DisableVertexAttribArray(vertex)
|
||||
return tris
|
||||
}
|
||||
|
||||
func (cv *Canvas) Clip() {
|
||||
|
|
39
shaders.go
39
shaders.go
|
@ -15,8 +15,11 @@ precision mediump float;
|
|||
#endif
|
||||
varying vec2 v_texCoord;
|
||||
uniform sampler2D image;
|
||||
uniform float globalAlpha;
|
||||
void main() {
|
||||
gl_FragColor = texture2D(image, v_texCoord);
|
||||
vec4 col = texture2D(image, v_texCoord);
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var solidVS = `
|
||||
|
@ -31,8 +34,11 @@ var solidFS = `
|
|||
precision mediump float;
|
||||
#endif
|
||||
uniform vec4 color;
|
||||
uniform float globalAlpha;
|
||||
void main() {
|
||||
gl_FragColor = color;
|
||||
vec4 col = color;
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var linearGradientVS = `
|
||||
|
@ -53,12 +59,15 @@ uniform mat3 invmat;
|
|||
uniform sampler1D 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;
|
||||
float r = dot(v, dir) / len;
|
||||
r = clamp(r, 0.0, 1.0);
|
||||
gl_FragColor = texture1D(gradient, r);
|
||||
vec4 col = texture1D(gradient, r);
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var radialGradientVS = `
|
||||
|
@ -80,6 +89,7 @@ uniform sampler1D gradient;
|
|||
uniform vec2 from, to, dir;
|
||||
uniform float radFrom, radTo;
|
||||
uniform float len;
|
||||
uniform float globalAlpha;
|
||||
bool isNaN(float v) {
|
||||
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
|
||||
}
|
||||
|
@ -99,8 +109,10 @@ void main() {
|
|||
return;
|
||||
}
|
||||
float o = max(o1, o2);
|
||||
float r = radFrom + o * (radTo - radFrom);
|
||||
gl_FragColor = texture1D(gradient, o);
|
||||
//float r = radFrom + o * (radTo - radFrom);
|
||||
vec4 col = texture1D(gradient, o);
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var imagePatternVS = `
|
||||
|
@ -120,9 +132,12 @@ 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;
|
||||
gl_FragColor = texture2D(image, mod(untf.xy / imageSize, 1.0));
|
||||
vec4 col = texture2D(image, mod(untf.xy / imageSize, 1.0));
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var solidAlphaVS = `
|
||||
|
@ -141,9 +156,10 @@ precision mediump float;
|
|||
varying vec2 v_atc;
|
||||
uniform vec4 color;
|
||||
uniform sampler2D alphaTex;
|
||||
uniform float globalAlpha;
|
||||
void main() {
|
||||
vec4 col = color;
|
||||
col.a *= texture2D(alphaTex, v_atc).a;
|
||||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
|
@ -170,13 +186,14 @@ uniform sampler1D 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;
|
||||
float r = dot(v, dir) / len;
|
||||
r = clamp(r, 0.0, 1.0);
|
||||
vec4 col = texture1D(gradient, r);
|
||||
col.a *= texture2D(alphaTex, v_atc).a;
|
||||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
|
@ -203,6 +220,7 @@ uniform vec2 from, to, dir;
|
|||
uniform float radFrom, radTo;
|
||||
uniform float len;
|
||||
uniform sampler2D alphaTex;
|
||||
uniform float globalAlpha;
|
||||
bool isNaN(float v) {
|
||||
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
|
||||
}
|
||||
|
@ -224,7 +242,7 @@ void main() {
|
|||
float o = max(o1, o2);
|
||||
float r = radFrom + o * (radTo - radFrom);
|
||||
vec4 col = texture1D(gradient, o);
|
||||
col.a *= texture2D(alphaTex, v_atc).a;
|
||||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
|
@ -249,9 +267,10 @@ 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));
|
||||
col.a *= texture2D(alphaTex, v_atc).a;
|
||||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
|
Loading…
Reference in a new issue