implemented globalAlpha

This commit is contained in:
Thomas Friedel 2018-04-09 17:39:26 +02:00
parent 3fcf95cc86
commit e75355ac37
6 changed files with 688 additions and 607 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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)

File diff suppressed because it is too large Load diff

View file

@ -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() {

View file

@ -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;
}`