unified some of the shaders to simplify

This commit is contained in:
Thomas Friedel 2020-02-11 13:24:06 +01:00
parent a80e3778fd
commit 50bf39fe62
4 changed files with 208 additions and 551 deletions

View file

@ -33,13 +33,17 @@ func (b *GoGLBackend) Clip(pts [][2]float64) {
gl.BindBuffer(gl.ARRAY_BUFFER, b.buf)
gl.BufferData(gl.ARRAY_BUFFER, len(b.ptsBuf)*4, unsafe.Pointer(&b.ptsBuf[0]), gl.STREAM_DRAW)
gl.VertexAttribPointer(b.sr.Vertex, 2, gl.FLOAT, false, 0, nil)
gl.VertexAttribPointer(b.shd.Vertex, 2, gl.FLOAT, false, 0, nil)
gl.UseProgram(b.sr.ID)
gl.Uniform4f(b.sr.Color, 1, 1, 1, 1)
gl.Uniform2f(b.sr.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform1f(b.sr.GlobalAlpha, 1)
gl.EnableVertexAttribArray(b.sr.Vertex)
gl.UseProgram(b.shd.ID)
gl.Uniform4f(b.shd.Color, 1, 1, 1, 1)
gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform1f(b.shd.GlobalAlpha, 1)
gl.Uniform1i(b.shd.UseAlphaTex, 0)
gl.Uniform1i(b.shd.UseLinearGradient, 0)
gl.Uniform1i(b.shd.UseRadialGradient, 0)
gl.Uniform1i(b.shd.UseImagePattern, 0)
gl.EnableVertexAttribArray(b.shd.Vertex)
gl.ColorMask(false, false, false, false)
@ -61,7 +65,7 @@ func (b *GoGLBackend) Clip(pts [][2]float64) {
gl.StencilOp(gl.ZERO, gl.ZERO, gl.ZERO)
gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
gl.DisableVertexAttribArray(b.sr.Vertex)
gl.DisableVertexAttribArray(b.shd.Vertex)
gl.ColorMask(true, true, true, true)
gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)

View file

@ -33,10 +33,14 @@ func (b *GoGLBackend) Clear(pts [4][2]float64) {
float32(pts[2][0]), float32(pts[2][1]),
float32(pts[3][0]), float32(pts[3][1])}
gl.UseProgram(b.sr.ID)
gl.Uniform2f(b.sr.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform4f(b.sr.Color, 0, 0, 0, 0)
gl.Uniform1f(b.sr.GlobalAlpha, 1)
gl.UseProgram(b.shd.ID)
gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform4f(b.shd.Color, 0, 0, 0, 0)
gl.Uniform1f(b.shd.GlobalAlpha, 1)
gl.Uniform1i(b.shd.UseAlphaTex, 0)
gl.Uniform1i(b.shd.UseLinearGradient, 0)
gl.Uniform1i(b.shd.UseRadialGradient, 0)
gl.Uniform1i(b.shd.UseImagePattern, 0)
gl.Disable(gl.BLEND)
@ -45,10 +49,10 @@ func (b *GoGLBackend) Clear(pts [4][2]float64) {
gl.StencilFunc(gl.EQUAL, 0, 0xFF)
gl.VertexAttribPointer(b.sr.Vertex, 2, gl.FLOAT, false, 0, nil)
gl.EnableVertexAttribArray(b.sr.Vertex)
gl.VertexAttribPointer(b.shd.Vertex, 2, gl.FLOAT, false, 0, nil)
gl.EnableVertexAttribArray(b.shd.Vertex)
gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
gl.DisableVertexAttribArray(b.sr.Vertex)
gl.DisableVertexAttribArray(b.shd.Vertex)
gl.StencilFunc(gl.ALWAYS, 0, 0xFF)
@ -111,7 +115,7 @@ func (b *GoGLBackend) Fill(style *backendbase.FillStyle, pts [][2]float64, canOv
gl.BufferData(gl.ARRAY_BUFFER, len(b.ptsBuf)*4, unsafe.Pointer(&b.ptsBuf[0]), gl.STREAM_DRAW)
if !canOverlap || style.Color.A >= 255 {
vertex := b.useShader(style)
vertex, _ := b.useShader(style, false, 0)
gl.StencilFunc(gl.EQUAL, 0, 0xFF)
gl.EnableVertexAttribArray(vertex)
@ -125,21 +129,25 @@ func (b *GoGLBackend) Fill(style *backendbase.FillStyle, pts [][2]float64, canOv
gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE)
gl.StencilMask(0x01)
gl.UseProgram(b.sr.ID)
gl.Uniform4f(b.sr.Color, 0, 0, 0, 0)
gl.Uniform2f(b.sr.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform1f(b.sr.GlobalAlpha, 1)
gl.UseProgram(b.shd.ID)
gl.Uniform4f(b.shd.Color, 0, 0, 0, 0)
gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform1f(b.shd.GlobalAlpha, 1)
gl.Uniform1i(b.shd.UseAlphaTex, 0)
gl.Uniform1i(b.shd.UseLinearGradient, 0)
gl.Uniform1i(b.shd.UseRadialGradient, 0)
gl.Uniform1i(b.shd.UseImagePattern, 0)
gl.EnableVertexAttribArray(b.sr.Vertex)
gl.VertexAttribPointer(b.sr.Vertex, 2, gl.FLOAT, false, 0, nil)
gl.EnableVertexAttribArray(b.shd.Vertex)
gl.VertexAttribPointer(b.shd.Vertex, 2, gl.FLOAT, false, 0, nil)
gl.DrawArrays(mode, 4, int32(len(pts)))
gl.DisableVertexAttribArray(b.sr.Vertex)
gl.DisableVertexAttribArray(b.shd.Vertex)
gl.ColorMask(true, true, true, true)
gl.StencilFunc(gl.EQUAL, 1, 0xFF)
vertex := b.useShader(style)
vertex, _ := b.useShader(style, false, 0)
gl.EnableVertexAttribArray(vertex)
gl.VertexAttribPointer(vertex, 2, gl.FLOAT, false, 0, nil)
@ -181,7 +189,7 @@ func (b *GoGLBackend) FillImageMask(style *backendbase.FillStyle, mask *image.Al
gl.BindBuffer(gl.ARRAY_BUFFER, b.buf)
vertex, alphaTexCoord := b.useAlphaShader(style, 1)
vertex, alphaTexCoord := b.useShader(style, true, 1)
gl.EnableVertexAttribArray(vertex)
gl.EnableVertexAttribArray(alphaTexCoord)

View file

@ -20,14 +20,7 @@ type GLContext struct {
shadowBuf uint32
alphaTex uint32
sr solidShader
lgr linearGradientShader
rgr radialGradientShader
ipr imagePatternShader
sar solidAlphaShader
rgar radialGradientAlphaShader
lgar linearGradientAlphaShader
ipar imagePatternAlphaShader
shd unifiedShader
ir imageShader
gauss15r gaussianShader
gauss63r gaussianShader
@ -59,74 +52,11 @@ func NewGLContext() (*GLContext, error) {
gl.GetError() // clear error state
err = loadShader(solidVS, solidFS, &ctx.sr.shaderProgram)
err = loadShader(unifiedVS, unifiedFS, &ctx.shd.shaderProgram)
if err != nil {
return nil, err
}
ctx.sr.shaderProgram.mustLoadLocations(&ctx.sr)
if err = glError(); err != nil {
return nil, err
}
err = loadShader(linearGradientVS, linearGradientFS, &ctx.lgr.shaderProgram)
if err != nil {
return nil, err
}
ctx.lgr.shaderProgram.mustLoadLocations(&ctx.lgr)
if err = glError(); err != nil {
return nil, err
}
err = loadShader(radialGradientVS, radialGradientFS, &ctx.rgr.shaderProgram)
if err != nil {
return nil, err
}
ctx.rgr.shaderProgram.mustLoadLocations(&ctx.rgr)
if err = glError(); err != nil {
return nil, err
}
err = loadShader(imagePatternVS, imagePatternFS, &ctx.ipr.shaderProgram)
if err != nil {
return nil, err
}
ctx.ipr.shaderProgram.mustLoadLocations(&ctx.ipr)
if err = glError(); err != nil {
return nil, err
}
err = loadShader(solidAlphaVS, solidAlphaFS, &ctx.sar.shaderProgram)
if err != nil {
return nil, err
}
ctx.sar.shaderProgram.mustLoadLocations(&ctx.sar)
if err = glError(); err != nil {
return nil, err
}
err = loadShader(linearGradientAlphaVS, linearGradientFS, &ctx.lgar.shaderProgram)
if err != nil {
return nil, err
}
ctx.lgar.shaderProgram.mustLoadLocations(&ctx.lgar)
if err = glError(); err != nil {
return nil, err
}
err = loadShader(radialGradientAlphaVS, radialGradientAlphaFS, &ctx.rgar.shaderProgram)
if err != nil {
return nil, err
}
ctx.rgar.shaderProgram.mustLoadLocations(&ctx.rgar)
if err = glError(); err != nil {
return nil, err
}
err = loadShader(imagePatternAlphaVS, imagePatternAlphaFS, &ctx.ipar.shaderProgram)
if err != nil {
return nil, err
}
ctx.ipar.shaderProgram.mustLoadLocations(&ctx.ipar)
ctx.shd.shaderProgram.mustLoadLocations(&ctx.shd)
if err = glError(); err != nil {
return nil, err
}
@ -397,150 +327,99 @@ func colorGoToGL(c color.RGBA) glColor {
return glc
}
func (b *GoGLBackend) useShader(style *backendbase.FillStyle) (vertexLoc uint32) {
func (b *GoGLBackend) useShader(style *backendbase.FillStyle, useAlpha bool, alphaTexSlot int32) (vertexLoc, alphaTexCoordLoc uint32) {
var alphaVal int32
if useAlpha {
alphaVal = 1
}
if lg := style.LinearGradient; lg != nil {
lg := lg.(*LinearGradient)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, lg.tex)
gl.UseProgram(b.lgr.ID)
gl.UseProgram(b.shd.ID)
from := vec{style.Gradient.X0, style.Gradient.Y0}
to := vec{style.Gradient.X1, style.Gradient.Y1}
dir := to.sub(from)
length := dir.len()
dir = dir.scale(1 / length)
gl.Uniform2f(b.lgr.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.lgr.From, float32(from[0]), float32(from[1]))
gl.Uniform2f(b.lgr.Dir, float32(dir[0]), float32(dir[1]))
gl.Uniform1f(b.lgr.Len, float32(length))
gl.Uniform1i(b.lgr.Gradient, 0)
gl.Uniform1f(b.lgr.GlobalAlpha, float32(style.Color.A)/255)
return b.lgr.Vertex
gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.shd.From, float32(from[0]), float32(from[1]))
gl.Uniform2f(b.shd.Dir, float32(dir[0]), float32(dir[1]))
gl.Uniform1f(b.shd.Len, float32(length))
gl.Uniform1i(b.shd.Gradient, 0)
gl.Uniform1f(b.shd.GlobalAlpha, float32(style.Color.A)/255)
gl.Uniform1i(b.shd.AlphaTex, alphaTexSlot)
gl.Uniform1i(b.shd.UseAlphaTex, alphaVal)
gl.Uniform1i(b.shd.UseLinearGradient, 1)
gl.Uniform1i(b.shd.UseRadialGradient, 0)
gl.Uniform1i(b.shd.UseImagePattern, 0)
return b.shd.Vertex, b.shd.AlphaTexCoord
}
if rg := style.RadialGradient; rg != nil {
rg := rg.(*RadialGradient)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, rg.tex)
gl.UseProgram(b.rgr.ID)
gl.UseProgram(b.shd.ID)
from := vec{style.Gradient.X0, style.Gradient.Y0}
to := vec{style.Gradient.X1, style.Gradient.Y1}
gl.Uniform2f(b.rgr.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.rgr.From, float32(from[0]), float32(from[1]))
gl.Uniform2f(b.rgr.To, float32(to[0]), float32(to[1]))
gl.Uniform1f(b.rgr.RadFrom, float32(style.Gradient.RadFrom))
gl.Uniform1f(b.rgr.RadTo, float32(style.Gradient.RadTo))
gl.Uniform1i(b.rgr.Gradient, 0)
gl.Uniform1f(b.rgr.GlobalAlpha, float32(style.Color.A)/255)
return b.rgr.Vertex
gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.shd.From, float32(from[0]), float32(from[1]))
gl.Uniform2f(b.shd.To, float32(to[0]), float32(to[1]))
gl.Uniform1f(b.shd.RadFrom, float32(style.Gradient.RadFrom))
gl.Uniform1f(b.shd.RadTo, float32(style.Gradient.RadTo))
gl.Uniform1i(b.shd.Gradient, 0)
gl.Uniform1f(b.shd.GlobalAlpha, float32(style.Color.A)/255)
gl.Uniform1i(b.shd.AlphaTex, alphaTexSlot)
gl.Uniform1i(b.shd.UseAlphaTex, alphaVal)
gl.Uniform1i(b.shd.UseLinearGradient, 0)
gl.Uniform1i(b.shd.UseRadialGradient, 1)
gl.Uniform1i(b.shd.UseImagePattern, 0)
return b.shd.Vertex, b.shd.AlphaTexCoord
}
if ip := style.ImagePattern; ip != nil {
ipd := ip.(*ImagePattern).data
img := ipd.Image.(*Image)
gl.UseProgram(b.ipr.ID)
gl.UseProgram(b.shd.ID)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, img.tex)
gl.Uniform2f(b.ipr.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.ipr.ImageSize, float32(img.w), float32(img.h))
gl.Uniform1i(b.ipr.Image, 0)
gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.shd.ImageSize, float32(img.w), float32(img.h))
gl.Uniform1i(b.shd.Image, 0)
var f32mat [9]float32
for i, v := range ipd.Transform {
f32mat[i] = float32(v)
}
gl.UniformMatrix3fv(b.ipr.ImageTransform, 1, false, &f32mat[0])
gl.UniformMatrix3fv(b.shd.ImageTransform, 1, false, &f32mat[0])
switch ipd.Repeat {
case backendbase.Repeat:
gl.Uniform2f(b.ipr.Repeat, 1, 1)
gl.Uniform2f(b.shd.Repeat, 1, 1)
case backendbase.RepeatX:
gl.Uniform2f(b.ipr.Repeat, 1, 0)
gl.Uniform2f(b.shd.Repeat, 1, 0)
case backendbase.RepeatY:
gl.Uniform2f(b.ipr.Repeat, 0, 1)
gl.Uniform2f(b.shd.Repeat, 0, 1)
case backendbase.NoRepeat:
gl.Uniform2f(b.ipr.Repeat, 0, 0)
gl.Uniform2f(b.shd.Repeat, 0, 0)
}
gl.Uniform1f(b.ipr.GlobalAlpha, float32(style.Color.A)/255)
return b.ipr.Vertex
gl.Uniform1f(b.shd.GlobalAlpha, float32(style.Color.A)/255)
gl.Uniform1i(b.shd.AlphaTex, alphaTexSlot)
gl.Uniform1i(b.shd.UseAlphaTex, alphaVal)
gl.Uniform1i(b.shd.UseLinearGradient, 0)
gl.Uniform1i(b.shd.UseRadialGradient, 0)
gl.Uniform1i(b.shd.UseImagePattern, 1)
return b.shd.Vertex, b.shd.AlphaTexCoord
}
gl.UseProgram(b.sr.ID)
gl.Uniform2f(b.sr.CanvasSize, float32(b.fw), float32(b.fh))
gl.UseProgram(b.shd.ID)
gl.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
c := colorGoToGL(style.Color)
gl.Uniform4f(b.sr.Color, float32(c.r), float32(c.g), float32(c.b), float32(c.a))
gl.Uniform1f(b.sr.GlobalAlpha, 1)
return b.sr.Vertex
}
func (b *GoGLBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot int32) (vertexLoc, alphaTexCoordLoc uint32) {
if lg := style.LinearGradient; lg != nil {
lg := lg.(*LinearGradient)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, lg.tex)
gl.UseProgram(b.lgar.ID)
from := vec{style.Gradient.X0, style.Gradient.Y0}
to := vec{style.Gradient.X1, style.Gradient.Y1}
dir := to.sub(from)
length := dir.len()
dir = dir.scale(1 / length)
gl.Uniform2f(b.lgar.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.lgar.From, float32(from[0]), float32(from[1]))
gl.Uniform2f(b.lgar.Dir, float32(dir[0]), float32(dir[1]))
gl.Uniform1f(b.lgar.Len, float32(length))
gl.Uniform1i(b.lgar.Gradient, 0)
gl.Uniform1i(b.lgar.AlphaTex, alphaTexSlot)
gl.Uniform1f(b.lgar.GlobalAlpha, float32(style.Color.A)/255)
return b.lgar.Vertex, b.lgar.AlphaTexCoord
}
if rg := style.RadialGradient; rg != nil {
rg := rg.(*RadialGradient)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, rg.tex)
gl.UseProgram(b.rgar.ID)
from := vec{style.Gradient.X0, style.Gradient.Y0}
to := vec{style.Gradient.X1, style.Gradient.Y1}
gl.Uniform2f(b.rgar.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.rgar.From, float32(from[0]), float32(from[1]))
gl.Uniform2f(b.rgar.To, float32(to[0]), float32(to[1]))
gl.Uniform1f(b.rgar.RadFrom, float32(style.Gradient.RadFrom))
gl.Uniform1f(b.rgar.RadTo, float32(style.Gradient.RadTo))
gl.Uniform1i(b.rgar.Gradient, 0)
gl.Uniform1i(b.rgar.AlphaTex, alphaTexSlot)
gl.Uniform1f(b.rgar.GlobalAlpha, float32(style.Color.A)/255)
return b.rgar.Vertex, b.rgar.AlphaTexCoord
}
if ip := style.ImagePattern; ip != nil {
ipd := ip.(*ImagePattern).data
img := ipd.Image.(*Image)
gl.UseProgram(b.ipar.ID)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, img.tex)
gl.Uniform2f(b.ipar.CanvasSize, float32(b.fw), float32(b.fh))
gl.Uniform2f(b.ipar.ImageSize, float32(img.w), float32(img.h))
gl.Uniform1i(b.ipar.Image, 0)
var f32mat [9]float32
for i, v := range ipd.Transform {
f32mat[i] = float32(v)
}
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.Uniform1f(b.ipar.GlobalAlpha, float32(style.Color.A)/255)
return b.ipar.Vertex, b.ipar.AlphaTexCoord
}
gl.UseProgram(b.sar.ID)
gl.Uniform2f(b.sar.CanvasSize, float32(b.fw), float32(b.fh))
c := colorGoToGL(style.Color)
gl.Uniform4f(b.sar.Color, float32(c.r), float32(c.g), float32(c.b), float32(c.a))
gl.Uniform1i(b.sar.AlphaTex, alphaTexSlot)
gl.Uniform1f(b.sar.GlobalAlpha, 1)
return b.sar.Vertex, b.sar.AlphaTexCoord
gl.Uniform4f(b.shd.Color, float32(c.r), float32(c.g), float32(c.b), float32(c.a))
gl.Uniform1f(b.shd.GlobalAlpha, 1)
gl.Uniform1i(b.shd.AlphaTex, alphaTexSlot)
gl.Uniform1i(b.shd.UseAlphaTex, alphaVal)
gl.Uniform1i(b.shd.UseLinearGradient, 0)
gl.Uniform1i(b.shd.UseRadialGradient, 0)
gl.Uniform1i(b.shd.UseImagePattern, 0)
return b.shd.Vertex, b.shd.AlphaTexCoord
}
func (b *GoGLBackend) enableTextureRenderTarget(offscr *offscreenBuffer) {

View file

@ -6,6 +6,96 @@ import (
"strings"
)
var unifiedVS = `
attribute vec2 vertex, alphaTexCoord;
uniform vec2 canvasSize;
varying vec2 v_cp, v_atc;
void main() {
v_atc = alphaTexCoord;
v_cp = vertex;
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
}
`
var unifiedFS = `
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_cp, v_atc;
uniform vec4 color;
uniform float globalAlpha;
uniform bool useLinearGradient;
uniform bool useRadialGradient;
uniform sampler2D gradient;
uniform vec2 from, dir, to;
uniform float len, radFrom, radTo;
uniform bool useImagePattern;
uniform vec2 imageSize;
uniform sampler2D image;
uniform mat3 imageTransform;
uniform vec2 repeat;
uniform bool useAlphaTex;
uniform sampler2D alphaTex;
bool isNaN(float v) {
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
}
void main() {
vec4 col = color;
if (useLinearGradient) {
vec2 v = v_cp - from;
float r = dot(v, dir) / len;
r = clamp(r, 0.0, 1.0);
col = texture2D(gradient, vec2(r, 0.0));
} else if (useRadialGradient) {
float o_a = 0.5 * sqrt(
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*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;
if (isNaN(o1) && isNaN(o2)) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
return;
}
float o = max(o1, o2);
o = clamp(o, 0.0, 1.0);
col = texture2D(gradient, vec2(o, 0.0));
} else if (useImagePattern) {
vec3 tfpt = vec3(v_cp, 1.0) * imageTransform;
vec2 imgpt = tfpt.xy / imageSize;
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;
}
}
if (useAlphaTex) {
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
} else {
col.a *= globalAlpha;
}
gl_FragColor = col;
}
`
var imageVS = `
attribute vec2 vertex, texCoord;
uniform vec2 canvasSize;
@ -28,265 +118,6 @@ void main() {
gl_FragColor = col;
}`
var solidVS = `
attribute vec2 vertex;
uniform vec2 canvasSize;
void main() {
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
}`
var solidFS = `
#ifdef GL_ES
precision mediump float;
#endif
uniform vec4 color;
uniform float globalAlpha;
void main() {
vec4 col = color;
col.a *= globalAlpha;
gl_FragColor = col;
}`
var linearGradientVS = `
attribute vec2 vertex;
uniform vec2 canvasSize;
varying vec2 v_cp;
void main() {
v_cp = vertex;
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
}`
var linearGradientFS = `
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_cp;
uniform sampler2D gradient;
uniform vec2 from, dir;
uniform float len;
uniform float globalAlpha;
void main() {
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));
col.a *= globalAlpha;
gl_FragColor = col;
}`
var radialGradientVS = `
attribute vec2 vertex;
uniform vec2 canvasSize;
varying vec2 v_cp;
void main() {
v_cp = vertex;
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
}`
var radialGradientFS = `
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_cp;
uniform sampler2D gradient;
uniform vec2 from, to;
uniform float radFrom, radTo;
uniform float globalAlpha;
bool isNaN(float v) {
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
}
void main() {
float o_a = 0.5 * sqrt(
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*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;
if (isNaN(o1) && isNaN(o2)) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
return;
}
float o = max(o1, o2);
//float r = radFrom + o * (radTo - radFrom);
vec4 col = texture2D(gradient, vec2(o, 0.0));
col.a *= globalAlpha;
gl_FragColor = col;
}`
var imagePatternVS = `
attribute vec2 vertex;
uniform vec2 canvasSize;
varying vec2 v_cp;
void main() {
v_cp = vertex;
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
}`
var imagePatternFS = `
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_cp;
uniform vec2 imageSize;
uniform sampler2D image;
uniform mat3 imageTransform;
uniform vec2 repeat;
uniform float globalAlpha;
void main() {
vec3 tfpt = vec3(v_cp, 1.0) * imageTransform;
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;
gl_FragColor = col;
}`
var solidAlphaVS = `
attribute vec2 vertex, alphaTexCoord;
uniform vec2 canvasSize;
varying vec2 v_atc;
void main() {
v_atc = alphaTexCoord;
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
}`
var solidAlphaFS = `
#ifdef GL_ES
precision mediump float;
#endif
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 * globalAlpha;
gl_FragColor = col;
}`
var linearGradientAlphaVS = `
attribute vec2 vertex, alphaTexCoord;
uniform vec2 canvasSize;
varying vec2 v_cp;
varying vec2 v_atc;
void main() {
v_cp = vertex;
v_atc = alphaTexCoord;
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
}`
var linearGradientAlphaFS = `
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_cp;
varying vec2 v_atc;
varying vec2 v_texCoord;
uniform sampler2D gradient;
uniform vec2 from, dir;
uniform float len;
uniform sampler2D alphaTex;
uniform float globalAlpha;
void main() {
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));
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
gl_FragColor = col;
}`
var radialGradientAlphaVS = `
attribute vec2 vertex, alphaTexCoord;
uniform vec2 canvasSize;
varying vec2 v_cp;
varying vec2 v_atc;
void main() {
v_cp = vertex;
v_atc = alphaTexCoord;
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
}`
var radialGradientAlphaFS = `
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_cp;
varying vec2 v_atc;
uniform sampler2D gradient;
uniform vec2 from, to;
uniform float radFrom, radTo;
uniform sampler2D alphaTex;
uniform float globalAlpha;
bool isNaN(float v) {
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
}
void main() {
float o_a = 0.5 * sqrt(
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*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;
if (isNaN(o1) && isNaN(o2)) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
return;
}
float o = max(o1, o2);
//float r = radFrom + o * (radTo - radFrom);
vec4 col = texture2D(gradient, vec2(o, 0.0));
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
gl_FragColor = col;
}`
var imagePatternAlphaVS = `
attribute vec2 vertex, alphaTexCoord;
uniform vec2 canvasSize;
varying vec2 v_cp;
varying vec2 v_atc;
void main() {
v_cp = vertex;
v_atc = alphaTexCoord;
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
}`
var imagePatternAlphaFS = `
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_cp;
varying vec2 v_atc;
uniform vec2 imageSize;
uniform sampler2D image;
uniform mat3 imageTransform;
uniform vec2 repeat;
uniform sampler2D alphaTex;
uniform float globalAlpha;
void main() {
vec3 tfpt = vec3(v_cp, 1.0) * imageTransform;
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;
gl_FragColor = col;
}`
var gaussian15VS = `
attribute vec2 vertex, texCoord;
uniform vec2 canvasSize;
@ -378,12 +209,31 @@ func init() {
gaussian15FS = strings.Replace(gaussian15FS, "_SUM_", bb.String(), -1)
}
type solidShader struct {
type unifiedShader struct {
shaderProgram
Vertex uint32
AlphaTexCoord uint32
CanvasSize int32
Color int32
GlobalAlpha int32
UseAlphaTex int32
AlphaTex int32
UseLinearGradient int32
UseRadialGradient int32
Gradient int32
From, To, Dir int32
Len int32
RadFrom, RadTo int32
UseImagePattern int32
ImageSize int32
Image int32
ImageTransform int32
Repeat int32
}
type imageShader struct {
@ -395,90 +245,6 @@ type imageShader struct {
GlobalAlpha int32
}
type linearGradientShader struct {
shaderProgram
Vertex uint32
CanvasSize int32
Gradient int32
From int32
Dir int32
Len int32
GlobalAlpha int32
}
type radialGradientShader struct {
shaderProgram
Vertex uint32
CanvasSize int32
Gradient int32
From int32
To int32
RadFrom int32
RadTo int32
GlobalAlpha int32
}
type imagePatternShader struct {
shaderProgram
Vertex uint32
CanvasSize int32
ImageSize int32
Image int32
ImageTransform int32
Repeat int32
GlobalAlpha int32
}
type solidAlphaShader struct {
shaderProgram
Vertex uint32
AlphaTexCoord uint32
CanvasSize int32
Color int32
AlphaTex int32
GlobalAlpha int32
}
type linearGradientAlphaShader struct {
shaderProgram
Vertex uint32
AlphaTexCoord uint32
CanvasSize int32
Gradient int32
From int32
Dir int32
Len int32
AlphaTex int32
GlobalAlpha int32
}
type radialGradientAlphaShader struct {
shaderProgram
Vertex uint32
AlphaTexCoord uint32
CanvasSize int32
Gradient int32
From int32
To int32
RadFrom int32
RadTo int32
AlphaTex int32
GlobalAlpha int32
}
type imagePatternAlphaShader struct {
shaderProgram
Vertex uint32
AlphaTexCoord uint32
CanvasSize int32
ImageSize int32
Image int32
ImageTransform int32
Repeat int32
AlphaTex int32
GlobalAlpha int32
}
type gaussianShader struct {
shaderProgram
Vertex uint32