shaders are now in their own file; text fill now uses font rendering more directly and supports fill styles
This commit is contained in:
parent
d509a6f86d
commit
da6538b1e3
7 changed files with 996 additions and 308 deletions
271
canvas.go
271
canvas.go
|
@ -2,13 +2,15 @@ package canvas
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/golang/freetype/truetype"
|
"github.com/golang/freetype/truetype"
|
||||||
"github.com/tfriedel6/lm"
|
"github.com/tfriedel6/lm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:generate go run make_shaders.go
|
||||||
|
//go:generate go fmt
|
||||||
|
|
||||||
// Canvas represents an area on the viewport on which to draw
|
// Canvas represents an area on the viewport on which to draw
|
||||||
// using a set of functions very similar to the HTML5 canvas
|
// using a set of functions very similar to the HTML5 canvas
|
||||||
type Canvas struct {
|
type Canvas struct {
|
||||||
|
@ -17,10 +19,6 @@ type Canvas struct {
|
||||||
|
|
||||||
polyPath []pathPoint
|
polyPath []pathPoint
|
||||||
linePath []pathPoint
|
linePath []pathPoint
|
||||||
text struct {
|
|
||||||
target *image.RGBA
|
|
||||||
tex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
state drawState
|
state drawState
|
||||||
stateStack []drawState
|
stateStack []drawState
|
||||||
|
@ -133,14 +131,21 @@ loop:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bufferTextureSize = 2048
|
||||||
|
|
||||||
var (
|
var (
|
||||||
gli GL
|
gli GL
|
||||||
buf uint32
|
buf uint32
|
||||||
|
alphaTex uint32
|
||||||
sr *solidShader
|
sr *solidShader
|
||||||
tr *textureShader
|
|
||||||
lgr *linearGradientShader
|
lgr *linearGradientShader
|
||||||
rgr *radialGradientShader
|
rgr *radialGradientShader
|
||||||
ipr *imagePatternShader
|
ipr *imagePatternShader
|
||||||
|
sar *solidAlphaShader
|
||||||
|
rgar *radialGradientAlphaShader
|
||||||
|
lgar *linearGradientAlphaShader
|
||||||
|
ipar *imagePatternAlphaShader
|
||||||
|
ir *imageShader
|
||||||
glChan = make(chan func())
|
glChan = make(chan func())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -158,15 +163,6 @@ func LoadGL(glimpl GL) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tr, err = loadTextureShader()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = glError()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lgr, err = loadLinearGradientShader()
|
lgr, err = loadLinearGradientShader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -194,12 +190,66 @@ func LoadGL(glimpl GL) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sar, err = loadSolidAlphaShader()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = glError()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lgar, err = loadLinearGradientAlphaShader()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = glError()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rgar, err = loadRadialGradientAlphaShader()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = glError()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ipar, err = loadImagePatternAlphaShader()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = glError()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ir, err = loadImageShader()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = glError()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
gli.GenBuffers(1, &buf)
|
gli.GenBuffers(1, &buf)
|
||||||
err = glError()
|
err = glError()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gli.ActiveTexture(gl_TEXTURE0)
|
||||||
|
gli.GenTextures(1, &alphaTex)
|
||||||
|
gli.BindTexture(gl_TEXTURE_2D, alphaTex)
|
||||||
|
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_NEAREST)
|
||||||
|
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_NEAREST)
|
||||||
|
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE)
|
||||||
|
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE)
|
||||||
|
gli.TexImage2D(gl_TEXTURE_2D, 0, gl_ALPHA, bufferTextureSize, bufferTextureSize, 0, gl_ALPHA, gl_UNSIGNED_BYTE, nil)
|
||||||
|
|
||||||
gli.Enable(gl_BLEND)
|
gli.Enable(gl_BLEND)
|
||||||
gli.BlendFunc(gl_SRC_ALPHA, gl_ONE_MINUS_SRC_ALPHA)
|
gli.BlendFunc(gl_SRC_ALPHA, gl_ONE_MINUS_SRC_ALPHA)
|
||||||
gli.Enable(gl_STENCIL_TEST)
|
gli.Enable(gl_STENCIL_TEST)
|
||||||
|
@ -208,132 +258,6 @@ func LoadGL(glimpl GL) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate go run make_shaders.go
|
|
||||||
//go:generate go fmt
|
|
||||||
|
|
||||||
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;
|
|
||||||
void main() {
|
|
||||||
gl_FragColor = color;
|
|
||||||
}`
|
|
||||||
|
|
||||||
var textureVS = `
|
|
||||||
attribute vec2 vertex, texCoord;
|
|
||||||
uniform vec2 canvasSize;
|
|
||||||
varying vec2 v_texCoord;
|
|
||||||
void main() {
|
|
||||||
v_texCoord = texCoord;
|
|
||||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
|
||||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
|
||||||
}`
|
|
||||||
var textureFS = `
|
|
||||||
#ifdef GL_ES
|
|
||||||
precision mediump float;
|
|
||||||
#endif
|
|
||||||
varying vec2 v_texCoord;
|
|
||||||
uniform sampler2D image;
|
|
||||||
void main() {
|
|
||||||
gl_FragColor = texture2D(image, v_texCoord);
|
|
||||||
}`
|
|
||||||
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 mat3 invmat;
|
|
||||||
uniform sampler1D gradient;
|
|
||||||
uniform vec2 from, dir;
|
|
||||||
uniform float len;
|
|
||||||
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);
|
|
||||||
}`
|
|
||||||
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 mat3 invmat;
|
|
||||||
uniform sampler1D gradient;
|
|
||||||
uniform vec2 from, to, dir;
|
|
||||||
uniform float radFrom, radTo;
|
|
||||||
uniform float len;
|
|
||||||
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)
|
|
||||||
*(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_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);
|
|
||||||
gl_FragColor = texture1D(gradient, o);
|
|
||||||
}`
|
|
||||||
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 mat3 invmat;
|
|
||||||
uniform sampler2D image;
|
|
||||||
void main() {
|
|
||||||
vec3 untf = vec3(v_cp, 1.0) * invmat;
|
|
||||||
gl_FragColor = texture2D(image, mod(untf.xy / imageSize, 1.0));
|
|
||||||
//gl_FragColor = vec4(v_cp * 0.1, 0.0, 1.0);
|
|
||||||
}`
|
|
||||||
|
|
||||||
func glError() error {
|
func glError() error {
|
||||||
glErr := gli.GetError()
|
glErr := gli.GetError()
|
||||||
if glErr != gl_NO_ERROR {
|
if glErr != gl_NO_ERROR {
|
||||||
|
@ -439,6 +363,71 @@ func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
|
||||||
return sr.vertex
|
return sr.vertex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLoc, alphaTexCoordLoc uint32) {
|
||||||
|
if lg := style.linearGradient; lg != nil {
|
||||||
|
lg.load()
|
||||||
|
gli.ActiveTexture(gl_TEXTURE0)
|
||||||
|
gli.BindTexture(gl_TEXTURE_1D, lg.tex)
|
||||||
|
gli.UseProgram(lgar.id)
|
||||||
|
from := cv.tf(lg.from)
|
||||||
|
to := cv.tf(lg.to)
|
||||||
|
dir := to.Sub(from)
|
||||||
|
length := dir.Len()
|
||||||
|
dir = dir.DivF(length)
|
||||||
|
gli.Uniform2f(lgar.canvasSize, cv.fw, cv.fh)
|
||||||
|
inv := cv.state.transform.Invert()
|
||||||
|
gli.UniformMatrix3fv(lgar.invmat, 1, false, &inv[0])
|
||||||
|
gli.Uniform2f(lgar.from, from[0], from[1])
|
||||||
|
gli.Uniform2f(lgar.dir, dir[0], dir[1])
|
||||||
|
gli.Uniform1f(lgar.len, length)
|
||||||
|
gli.Uniform1i(lgar.gradient, 0)
|
||||||
|
gli.Uniform1i(lgar.alphaTex, alphaTexSlot)
|
||||||
|
return lgar.vertex, lgar.alphaTexCoord
|
||||||
|
}
|
||||||
|
if rg := style.radialGradient; rg != nil {
|
||||||
|
rg.load()
|
||||||
|
gli.ActiveTexture(gl_TEXTURE0)
|
||||||
|
gli.BindTexture(gl_TEXTURE_1D, rg.tex)
|
||||||
|
gli.UseProgram(rgar.id)
|
||||||
|
from := cv.tf(rg.from)
|
||||||
|
to := cv.tf(rg.to)
|
||||||
|
dir := to.Sub(from)
|
||||||
|
length := dir.Len()
|
||||||
|
dir = dir.DivF(length)
|
||||||
|
gli.Uniform2f(rgar.canvasSize, cv.fw, cv.fh)
|
||||||
|
inv := cv.state.transform.Invert()
|
||||||
|
gli.UniformMatrix3fv(rgar.invmat, 1, false, &inv[0])
|
||||||
|
gli.Uniform2f(rgar.from, from[0], from[1])
|
||||||
|
gli.Uniform2f(rgar.to, to[0], to[1])
|
||||||
|
gli.Uniform2f(rgar.dir, dir[0], dir[1])
|
||||||
|
gli.Uniform1f(rgar.radFrom, rg.radFrom)
|
||||||
|
gli.Uniform1f(rgar.radTo, rg.radTo)
|
||||||
|
gli.Uniform1f(rgar.len, length)
|
||||||
|
gli.Uniform1i(rgar.gradient, 0)
|
||||||
|
gli.Uniform1i(rgar.alphaTex, alphaTexSlot)
|
||||||
|
return rgar.vertex, rgar.alphaTexCoord
|
||||||
|
}
|
||||||
|
if img := style.image; img != nil {
|
||||||
|
gli.UseProgram(ipar.id)
|
||||||
|
gli.ActiveTexture(gl_TEXTURE0)
|
||||||
|
gli.BindTexture(gl_TEXTURE_2D, img.tex)
|
||||||
|
gli.Uniform2f(ipar.canvasSize, cv.fw, cv.fh)
|
||||||
|
inv := cv.state.transform.Invert()
|
||||||
|
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)
|
||||||
|
return ipar.vertex, ipar.alphaTexCoord
|
||||||
|
}
|
||||||
|
|
||||||
|
gli.UseProgram(sar.id)
|
||||||
|
gli.Uniform2f(sar.canvasSize, cv.fw, cv.fh)
|
||||||
|
c := style.color
|
||||||
|
gli.Uniform4f(sar.color, c.r, c.g, c.b, c.a)
|
||||||
|
gli.Uniform1i(sar.alphaTex, alphaTexSlot)
|
||||||
|
return sar.vertex, sar.alphaTexCoord
|
||||||
|
}
|
||||||
|
|
||||||
// SetLineWidth sets the line width for any line drawing calls
|
// SetLineWidth sets the line width for any line drawing calls
|
||||||
func (cv *Canvas) SetLineWidth(width float32) {
|
func (cv *Canvas) SetLineWidth(width float32) {
|
||||||
cv.state.lineWidth = width
|
cv.state.lineWidth = width
|
||||||
|
|
18
imagedata.go
18
imagedata.go
|
@ -79,14 +79,14 @@ func (cv *Canvas) PutImageData(img *image.RGBA, x, y int) {
|
||||||
0, 0, 1, 0, 1, 1, 0, 1}
|
0, 0, 1, 0, 1, 1, 0, 1}
|
||||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||||
|
|
||||||
gli.UseProgram(tr.id)
|
gli.UseProgram(ir.id)
|
||||||
gli.Uniform1i(tr.image, 0)
|
gli.Uniform1i(ir.image, 0)
|
||||||
gli.Uniform2f(tr.canvasSize, cv.fw, cv.fh)
|
gli.Uniform2f(ir.canvasSize, cv.fw, cv.fh)
|
||||||
gli.VertexAttribPointer(tr.vertex, 2, gl_FLOAT, false, 0, nil)
|
gli.VertexAttribPointer(ir.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||||
gli.VertexAttribPointer(tr.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
gli.VertexAttribPointer(ir.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
||||||
gli.EnableVertexAttribArray(tr.vertex)
|
gli.EnableVertexAttribArray(ir.vertex)
|
||||||
gli.EnableVertexAttribArray(tr.texCoord)
|
gli.EnableVertexAttribArray(ir.texCoord)
|
||||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||||
gli.DisableVertexAttribArray(tr.vertex)
|
gli.DisableVertexAttribArray(ir.vertex)
|
||||||
gli.DisableVertexAttribArray(tr.texCoord)
|
gli.DisableVertexAttribArray(ir.texCoord)
|
||||||
}
|
}
|
||||||
|
|
18
images.go
18
images.go
|
@ -233,14 +233,14 @@ func (cv *Canvas) DrawImage(image interface{}, coords ...float32) {
|
||||||
gli.ActiveTexture(gl_TEXTURE0)
|
gli.ActiveTexture(gl_TEXTURE0)
|
||||||
gli.BindTexture(gl_TEXTURE_2D, img.tex)
|
gli.BindTexture(gl_TEXTURE_2D, img.tex)
|
||||||
|
|
||||||
gli.UseProgram(tr.id)
|
gli.UseProgram(ir.id)
|
||||||
gli.Uniform1i(tr.image, 0)
|
gli.Uniform1i(ir.image, 0)
|
||||||
gli.Uniform2f(tr.canvasSize, cv.fw, cv.fh)
|
gli.Uniform2f(ir.canvasSize, cv.fw, cv.fh)
|
||||||
gli.VertexAttribPointer(tr.vertex, 2, gl_FLOAT, false, 0, nil)
|
gli.VertexAttribPointer(ir.vertex, 2, gl_FLOAT, false, 0, nil)
|
||||||
gli.VertexAttribPointer(tr.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
gli.VertexAttribPointer(ir.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
||||||
gli.EnableVertexAttribArray(tr.vertex)
|
gli.EnableVertexAttribArray(ir.vertex)
|
||||||
gli.EnableVertexAttribArray(tr.texCoord)
|
gli.EnableVertexAttribArray(ir.texCoord)
|
||||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||||
gli.DisableVertexAttribArray(tr.vertex)
|
gli.DisableVertexAttribArray(ir.vertex)
|
||||||
gli.DisableVertexAttribArray(tr.texCoord)
|
gli.DisableVertexAttribArray(ir.texCoord)
|
||||||
}
|
}
|
||||||
|
|
580
made_shaders.go
580
made_shaders.go
|
@ -6,19 +6,22 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type textureShader struct {
|
type linearGradientShader struct {
|
||||||
id uint32
|
id uint32
|
||||||
vertex uint32
|
vertex uint32
|
||||||
texCoord uint32
|
|
||||||
canvasSize int32
|
canvasSize int32
|
||||||
image int32
|
invmat int32
|
||||||
|
gradient int32
|
||||||
|
from int32
|
||||||
|
dir int32
|
||||||
|
len int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadTextureShader() (*textureShader, error) {
|
func loadLinearGradientShader() (*linearGradientShader, error) {
|
||||||
var vs, fs, program uint32
|
var vs, fs, program uint32
|
||||||
|
|
||||||
{
|
{
|
||||||
csource, freeFunc := gli.Strs(textureVS + "\x00")
|
csource, freeFunc := gli.Strs(linearGradientVS + "\x00")
|
||||||
defer freeFunc()
|
defer freeFunc()
|
||||||
|
|
||||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||||
|
@ -30,22 +33,22 @@ func loadTextureShader() (*textureShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("VERTEX_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("VERTEX_SHADER compilation log for linearGradientVS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part")
|
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for linearGradientVS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for linearGradientVS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
csource, freeFunc := gli.Strs(textureFS + "\x00")
|
csource, freeFunc := gli.Strs(linearGradientFS + "\x00")
|
||||||
defer freeFunc()
|
defer freeFunc()
|
||||||
|
|
||||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||||
|
@ -57,17 +60,17 @@ func loadTextureShader() (*textureShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("FRAGMENT_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("FRAGMENT_SHADER compilation log for linearGradientFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part")
|
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for linearGradientFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for linearGradientFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +85,7 @@ func loadTextureShader() (*textureShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("Shader link log:\n\n%s\n", shLog)
|
fmt.Printf("Shader link log for linearGradientFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
|
@ -90,35 +93,44 @@ func loadTextureShader() (*textureShader, error) {
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("error linking shader")
|
return nil, errors.New("error linking shader for linearGradientFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error linking shader, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error linking shader for linearGradientFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &textureShader{}
|
result := &linearGradientShader{}
|
||||||
result.id = program
|
result.id = program
|
||||||
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||||
result.texCoord = uint32(gli.GetAttribLocation(program, gli.Str("texCoord\x00")))
|
|
||||||
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
||||||
result.image = gli.GetUniformLocation(program, gli.Str("image\x00"))
|
result.invmat = gli.GetUniformLocation(program, gli.Str("invmat\x00"))
|
||||||
|
result.gradient = gli.GetUniformLocation(program, gli.Str("gradient\x00"))
|
||||||
|
result.from = gli.GetUniformLocation(program, gli.Str("from\x00"))
|
||||||
|
result.dir = gli.GetUniformLocation(program, gli.Str("dir\x00"))
|
||||||
|
result.len = gli.GetUniformLocation(program, gli.Str("len\x00"))
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type solidShader struct {
|
type linearGradientAlphaShader struct {
|
||||||
id uint32
|
id uint32
|
||||||
vertex uint32
|
vertex uint32
|
||||||
|
alphaTexCoord uint32
|
||||||
canvasSize int32
|
canvasSize int32
|
||||||
color int32
|
invmat int32
|
||||||
|
gradient int32
|
||||||
|
from int32
|
||||||
|
dir int32
|
||||||
|
len int32
|
||||||
|
alphaTex int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSolidShader() (*solidShader, error) {
|
func loadLinearGradientAlphaShader() (*linearGradientAlphaShader, error) {
|
||||||
var vs, fs, program uint32
|
var vs, fs, program uint32
|
||||||
|
|
||||||
{
|
{
|
||||||
csource, freeFunc := gli.Strs(solidVS + "\x00")
|
csource, freeFunc := gli.Strs(linearGradientAlphaVS + "\x00")
|
||||||
defer freeFunc()
|
defer freeFunc()
|
||||||
|
|
||||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||||
|
@ -130,22 +142,22 @@ func loadSolidShader() (*solidShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("VERTEX_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("VERTEX_SHADER compilation log for linearGradientAlphaVS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part")
|
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for linearGradientAlphaVS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for linearGradientAlphaVS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
csource, freeFunc := gli.Strs(solidFS + "\x00")
|
csource, freeFunc := gli.Strs(linearGradientAlphaFS + "\x00")
|
||||||
defer freeFunc()
|
defer freeFunc()
|
||||||
|
|
||||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||||
|
@ -157,17 +169,17 @@ func loadSolidShader() (*solidShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("FRAGMENT_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("FRAGMENT_SHADER compilation log for linearGradientAlphaFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part")
|
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for linearGradientAlphaFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for linearGradientAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +194,7 @@ func loadSolidShader() (*solidShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("Shader link log:\n\n%s\n", shLog)
|
fmt.Printf("Shader link log for linearGradientAlphaFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
|
@ -190,18 +202,131 @@ func loadSolidShader() (*solidShader, error) {
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("error linking shader")
|
return nil, errors.New("error linking shader for linearGradientAlphaFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error linking shader, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error linking shader for linearGradientAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &solidShader{}
|
result := &linearGradientAlphaShader{}
|
||||||
result.id = program
|
result.id = program
|
||||||
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||||
|
result.alphaTexCoord = uint32(gli.GetAttribLocation(program, gli.Str("alphaTexCoord\x00")))
|
||||||
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
||||||
result.color = gli.GetUniformLocation(program, gli.Str("color\x00"))
|
result.invmat = gli.GetUniformLocation(program, gli.Str("invmat\x00"))
|
||||||
|
result.gradient = gli.GetUniformLocation(program, gli.Str("gradient\x00"))
|
||||||
|
result.from = gli.GetUniformLocation(program, gli.Str("from\x00"))
|
||||||
|
result.dir = gli.GetUniformLocation(program, gli.Str("dir\x00"))
|
||||||
|
result.len = gli.GetUniformLocation(program, gli.Str("len\x00"))
|
||||||
|
result.alphaTex = gli.GetUniformLocation(program, gli.Str("alphaTex\x00"))
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type imagePatternAlphaShader struct {
|
||||||
|
id uint32
|
||||||
|
vertex uint32
|
||||||
|
alphaTexCoord uint32
|
||||||
|
canvasSize int32
|
||||||
|
imageSize int32
|
||||||
|
invmat int32
|
||||||
|
image int32
|
||||||
|
alphaTex int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadImagePatternAlphaShader() (*imagePatternAlphaShader, error) {
|
||||||
|
var vs, fs, program uint32
|
||||||
|
|
||||||
|
{
|
||||||
|
csource, freeFunc := gli.Strs(imagePatternAlphaVS + "\x00")
|
||||||
|
defer freeFunc()
|
||||||
|
|
||||||
|
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||||
|
gli.ShaderSource(vs, 1, csource, nil)
|
||||||
|
gli.CompileShader(vs)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetShaderiv(vs, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("VERTEX_SHADER compilation log for imagePatternAlphaVS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(vs)
|
||||||
|
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for imagePatternAlphaVS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error compiling shader part for imagePatternAlphaVS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
csource, freeFunc := gli.Strs(imagePatternAlphaFS + "\x00")
|
||||||
|
defer freeFunc()
|
||||||
|
|
||||||
|
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||||
|
gli.ShaderSource(fs, 1, csource, nil)
|
||||||
|
gli.CompileShader(fs)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetShaderiv(fs, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("FRAGMENT_SHADER compilation log for imagePatternAlphaFS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(fs)
|
||||||
|
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for imagePatternAlphaFS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error compiling shader part for imagePatternAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
program = gli.CreateProgram()
|
||||||
|
gli.AttachShader(program, vs)
|
||||||
|
gli.AttachShader(program, fs)
|
||||||
|
gli.LinkProgram(program)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetProgramiv(program, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("Shader link log for imagePatternAlphaFS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetProgramiv(program, gl_LINK_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(vs)
|
||||||
|
gli.DeleteShader(fs)
|
||||||
|
return nil, errors.New("error linking shader for imagePatternAlphaFS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error linking shader for imagePatternAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := &imagePatternAlphaShader{}
|
||||||
|
result.id = program
|
||||||
|
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||||
|
result.alphaTexCoord = uint32(gli.GetAttribLocation(program, gli.Str("alphaTexCoord\x00")))
|
||||||
|
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
||||||
|
result.imageSize = gli.GetUniformLocation(program, gli.Str("imageSize\x00"))
|
||||||
|
result.invmat = gli.GetUniformLocation(program, gli.Str("invmat\x00"))
|
||||||
|
result.image = gli.GetUniformLocation(program, gli.Str("image\x00"))
|
||||||
|
result.alphaTex = gli.GetUniformLocation(program, gli.Str("alphaTex\x00"))
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
@ -231,17 +356,17 @@ func loadImagePatternShader() (*imagePatternShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("VERTEX_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("VERTEX_SHADER compilation log for imagePatternVS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part")
|
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for imagePatternVS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for imagePatternVS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,17 +383,17 @@ func loadImagePatternShader() (*imagePatternShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("FRAGMENT_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("FRAGMENT_SHADER compilation log for imagePatternFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part")
|
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for imagePatternFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for imagePatternFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +408,7 @@ func loadImagePatternShader() (*imagePatternShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("Shader link log:\n\n%s\n", shLog)
|
fmt.Printf("Shader link log for imagePatternFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
|
@ -291,10 +416,10 @@ func loadImagePatternShader() (*imagePatternShader, error) {
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("error linking shader")
|
return nil, errors.New("error linking shader for imagePatternFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error linking shader, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error linking shader for imagePatternFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,22 +434,20 @@ func loadImagePatternShader() (*imagePatternShader, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type linearGradientShader struct {
|
type solidAlphaShader struct {
|
||||||
id uint32
|
id uint32
|
||||||
vertex uint32
|
vertex uint32
|
||||||
|
alphaTexCoord uint32
|
||||||
canvasSize int32
|
canvasSize int32
|
||||||
invmat int32
|
color int32
|
||||||
gradient int32
|
alphaTex int32
|
||||||
from int32
|
|
||||||
dir int32
|
|
||||||
len int32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadLinearGradientShader() (*linearGradientShader, error) {
|
func loadSolidAlphaShader() (*solidAlphaShader, error) {
|
||||||
var vs, fs, program uint32
|
var vs, fs, program uint32
|
||||||
|
|
||||||
{
|
{
|
||||||
csource, freeFunc := gli.Strs(linearGradientVS + "\x00")
|
csource, freeFunc := gli.Strs(solidAlphaVS + "\x00")
|
||||||
defer freeFunc()
|
defer freeFunc()
|
||||||
|
|
||||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||||
|
@ -336,22 +459,22 @@ func loadLinearGradientShader() (*linearGradientShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("VERTEX_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("VERTEX_SHADER compilation log for solidAlphaVS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part")
|
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for solidAlphaVS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for solidAlphaVS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
csource, freeFunc := gli.Strs(linearGradientFS + "\x00")
|
csource, freeFunc := gli.Strs(solidAlphaFS + "\x00")
|
||||||
defer freeFunc()
|
defer freeFunc()
|
||||||
|
|
||||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||||
|
@ -363,17 +486,17 @@ func loadLinearGradientShader() (*linearGradientShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("FRAGMENT_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("FRAGMENT_SHADER compilation log for solidAlphaFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part")
|
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for solidAlphaFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for solidAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +511,7 @@ func loadLinearGradientShader() (*linearGradientShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("Shader link log:\n\n%s\n", shLog)
|
fmt.Printf("Shader link log for solidAlphaFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
|
@ -396,22 +519,337 @@ func loadLinearGradientShader() (*linearGradientShader, error) {
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("error linking shader")
|
return nil, errors.New("error linking shader for solidAlphaFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error linking shader, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error linking shader for solidAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &linearGradientShader{}
|
result := &solidAlphaShader{}
|
||||||
result.id = program
|
result.id = program
|
||||||
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||||
|
result.alphaTexCoord = uint32(gli.GetAttribLocation(program, gli.Str("alphaTexCoord\x00")))
|
||||||
|
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
||||||
|
result.color = gli.GetUniformLocation(program, gli.Str("color\x00"))
|
||||||
|
result.alphaTex = gli.GetUniformLocation(program, gli.Str("alphaTex\x00"))
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type radialGradientAlphaShader struct {
|
||||||
|
id uint32
|
||||||
|
vertex uint32
|
||||||
|
alphaTexCoord uint32
|
||||||
|
canvasSize int32
|
||||||
|
invmat int32
|
||||||
|
gradient int32
|
||||||
|
from int32
|
||||||
|
to int32
|
||||||
|
dir int32
|
||||||
|
radFrom int32
|
||||||
|
radTo int32
|
||||||
|
len int32
|
||||||
|
alphaTex int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadRadialGradientAlphaShader() (*radialGradientAlphaShader, error) {
|
||||||
|
var vs, fs, program uint32
|
||||||
|
|
||||||
|
{
|
||||||
|
csource, freeFunc := gli.Strs(radialGradientAlphaVS + "\x00")
|
||||||
|
defer freeFunc()
|
||||||
|
|
||||||
|
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||||
|
gli.ShaderSource(vs, 1, csource, nil)
|
||||||
|
gli.CompileShader(vs)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetShaderiv(vs, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("VERTEX_SHADER compilation log for radialGradientAlphaVS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(vs)
|
||||||
|
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for radialGradientAlphaVS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error compiling shader part for radialGradientAlphaVS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
csource, freeFunc := gli.Strs(radialGradientAlphaFS + "\x00")
|
||||||
|
defer freeFunc()
|
||||||
|
|
||||||
|
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||||
|
gli.ShaderSource(fs, 1, csource, nil)
|
||||||
|
gli.CompileShader(fs)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetShaderiv(fs, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("FRAGMENT_SHADER compilation log for radialGradientAlphaFS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(fs)
|
||||||
|
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for radialGradientAlphaFS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error compiling shader part for radialGradientAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
program = gli.CreateProgram()
|
||||||
|
gli.AttachShader(program, vs)
|
||||||
|
gli.AttachShader(program, fs)
|
||||||
|
gli.LinkProgram(program)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetProgramiv(program, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("Shader link log for radialGradientAlphaFS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetProgramiv(program, gl_LINK_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(vs)
|
||||||
|
gli.DeleteShader(fs)
|
||||||
|
return nil, errors.New("error linking shader for radialGradientAlphaFS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error linking shader for radialGradientAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := &radialGradientAlphaShader{}
|
||||||
|
result.id = program
|
||||||
|
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||||
|
result.alphaTexCoord = uint32(gli.GetAttribLocation(program, gli.Str("alphaTexCoord\x00")))
|
||||||
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
||||||
result.invmat = gli.GetUniformLocation(program, gli.Str("invmat\x00"))
|
result.invmat = gli.GetUniformLocation(program, gli.Str("invmat\x00"))
|
||||||
result.gradient = gli.GetUniformLocation(program, gli.Str("gradient\x00"))
|
result.gradient = gli.GetUniformLocation(program, gli.Str("gradient\x00"))
|
||||||
result.from = gli.GetUniformLocation(program, gli.Str("from\x00"))
|
result.from = gli.GetUniformLocation(program, gli.Str("from\x00"))
|
||||||
|
result.to = gli.GetUniformLocation(program, gli.Str("to\x00"))
|
||||||
result.dir = gli.GetUniformLocation(program, gli.Str("dir\x00"))
|
result.dir = gli.GetUniformLocation(program, gli.Str("dir\x00"))
|
||||||
|
result.radFrom = gli.GetUniformLocation(program, gli.Str("radFrom\x00"))
|
||||||
|
result.radTo = gli.GetUniformLocation(program, gli.Str("radTo\x00"))
|
||||||
result.len = gli.GetUniformLocation(program, gli.Str("len\x00"))
|
result.len = gli.GetUniformLocation(program, gli.Str("len\x00"))
|
||||||
|
result.alphaTex = gli.GetUniformLocation(program, gli.Str("alphaTex\x00"))
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type solidShader struct {
|
||||||
|
id uint32
|
||||||
|
vertex uint32
|
||||||
|
canvasSize int32
|
||||||
|
color int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadSolidShader() (*solidShader, error) {
|
||||||
|
var vs, fs, program uint32
|
||||||
|
|
||||||
|
{
|
||||||
|
csource, freeFunc := gli.Strs(solidVS + "\x00")
|
||||||
|
defer freeFunc()
|
||||||
|
|
||||||
|
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||||
|
gli.ShaderSource(vs, 1, csource, nil)
|
||||||
|
gli.CompileShader(vs)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetShaderiv(vs, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("VERTEX_SHADER compilation log for solidVS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(vs)
|
||||||
|
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for solidVS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error compiling shader part for solidVS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
csource, freeFunc := gli.Strs(solidFS + "\x00")
|
||||||
|
defer freeFunc()
|
||||||
|
|
||||||
|
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||||
|
gli.ShaderSource(fs, 1, csource, nil)
|
||||||
|
gli.CompileShader(fs)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetShaderiv(fs, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("FRAGMENT_SHADER compilation log for solidFS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(fs)
|
||||||
|
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for solidFS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error compiling shader part for solidFS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
program = gli.CreateProgram()
|
||||||
|
gli.AttachShader(program, vs)
|
||||||
|
gli.AttachShader(program, fs)
|
||||||
|
gli.LinkProgram(program)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetProgramiv(program, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("Shader link log for solidFS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetProgramiv(program, gl_LINK_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(vs)
|
||||||
|
gli.DeleteShader(fs)
|
||||||
|
return nil, errors.New("error linking shader for solidFS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error linking shader for solidFS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := &solidShader{}
|
||||||
|
result.id = program
|
||||||
|
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||||
|
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
||||||
|
result.color = gli.GetUniformLocation(program, gli.Str("color\x00"))
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type imageShader struct {
|
||||||
|
id uint32
|
||||||
|
vertex uint32
|
||||||
|
texCoord uint32
|
||||||
|
canvasSize int32
|
||||||
|
image int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadImageShader() (*imageShader, error) {
|
||||||
|
var vs, fs, program uint32
|
||||||
|
|
||||||
|
{
|
||||||
|
csource, freeFunc := gli.Strs(imageVS + "\x00")
|
||||||
|
defer freeFunc()
|
||||||
|
|
||||||
|
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||||
|
gli.ShaderSource(vs, 1, csource, nil)
|
||||||
|
gli.CompileShader(vs)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetShaderiv(vs, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("VERTEX_SHADER compilation log for imageVS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(vs)
|
||||||
|
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for imageVS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error compiling shader part for imageVS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
csource, freeFunc := gli.Strs(imageFS + "\x00")
|
||||||
|
defer freeFunc()
|
||||||
|
|
||||||
|
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||||
|
gli.ShaderSource(fs, 1, csource, nil)
|
||||||
|
gli.CompileShader(fs)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetShaderiv(fs, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("FRAGMENT_SHADER compilation log for imageFS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(fs)
|
||||||
|
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for imageFS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error compiling shader part for imageFS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
program = gli.CreateProgram()
|
||||||
|
gli.AttachShader(program, vs)
|
||||||
|
gli.AttachShader(program, fs)
|
||||||
|
gli.LinkProgram(program)
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gli.GetProgramiv(program, gl_INFO_LOG_LENGTH, &logLength)
|
||||||
|
if logLength > 0 {
|
||||||
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
|
fmt.Printf("Shader link log for imageFS:\n\n%s\n", shLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gli.GetProgramiv(program, gl_LINK_STATUS, &status)
|
||||||
|
if status != gl_TRUE {
|
||||||
|
gli.DeleteShader(vs)
|
||||||
|
gli.DeleteShader(fs)
|
||||||
|
return nil, errors.New("error linking shader for imageFS")
|
||||||
|
}
|
||||||
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
|
return nil, errors.New("error linking shader for imageFS, glError: " + fmt.Sprint(glErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := &imageShader{}
|
||||||
|
result.id = program
|
||||||
|
result.vertex = uint32(gli.GetAttribLocation(program, gli.Str("vertex\x00")))
|
||||||
|
result.texCoord = uint32(gli.GetAttribLocation(program, gli.Str("texCoord\x00")))
|
||||||
|
result.canvasSize = gli.GetUniformLocation(program, gli.Str("canvasSize\x00"))
|
||||||
|
result.image = gli.GetUniformLocation(program, gli.Str("image\x00"))
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
@ -446,17 +884,17 @@ func loadRadialGradientShader() (*radialGradientShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(vs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("VERTEX_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("VERTEX_SHADER compilation log for radialGradientVS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(vs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part")
|
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for radialGradientVS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for radialGradientVS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,17 +911,17 @@ func loadRadialGradientShader() (*radialGradientShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(fs, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("FRAGMENT_SHADER compilation log:\n\n%s\n", shLog)
|
fmt.Printf("FRAGMENT_SHADER compilation log for radialGradientFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(fs, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part")
|
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for radialGradientFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for radialGradientFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +936,7 @@ func loadRadialGradientShader() (*radialGradientShader, error) {
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("Shader link log:\n\n%s\n", shLog)
|
fmt.Printf("Shader link log for radialGradientFS:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
|
@ -506,10 +944,10 @@ func loadRadialGradientShader() (*radialGradientShader, error) {
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("error linking shader")
|
return nil, errors.New("error linking shader for radialGradientFS")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error linking shader, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error linking shader for radialGradientFS, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -212,17 +212,17 @@ const compilePart = `
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetShaderInfoLog(SHADER_VAR, logLength, nil, gli.Str(shLog))
|
gli.GetShaderInfoLog(SHADER_VAR, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("SHADER_TYPE compilation log:\n\n%s\n", shLog)
|
fmt.Printf("SHADER_TYPE compilation log for SHADER_SRC:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
gli.GetShaderiv(SHADER_VAR, gl_COMPILE_STATUS, &status)
|
gli.GetShaderiv(SHADER_VAR, gl_COMPILE_STATUS, &status)
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(SHADER_VAR)
|
gli.DeleteShader(SHADER_VAR)
|
||||||
return nil, errors.New("Error compiling GL_SHADER_TYPE shader part")
|
return nil, errors.New("Error compiling GL_SHADER_TYPE shader part for SHADER_SRC")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error compiling shader part, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error compiling shader part for SHADER_SRC, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -238,7 +238,7 @@ const linkPart = `
|
||||||
if logLength > 0 {
|
if logLength > 0 {
|
||||||
shLog := strings.Repeat("\x00", int(logLength+1))
|
shLog := strings.Repeat("\x00", int(logLength+1))
|
||||||
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
gli.GetProgramInfoLog(program, logLength, nil, gli.Str(shLog))
|
||||||
fmt.Printf("Shader link log:\n\n%s\n", shLog)
|
fmt.Printf("Shader link log for SHADER_SRC:\n\n%s\n", shLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
|
@ -246,10 +246,10 @@ const linkPart = `
|
||||||
if status != gl_TRUE {
|
if status != gl_TRUE {
|
||||||
gli.DeleteShader(vs)
|
gli.DeleteShader(vs)
|
||||||
gli.DeleteShader(fs)
|
gli.DeleteShader(fs)
|
||||||
return nil, errors.New("error linking shader")
|
return nil, errors.New("error linking shader for SHADER_SRC")
|
||||||
}
|
}
|
||||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||||
return nil, errors.New("error linking shader, glError: " + fmt.Sprint(glErr))
|
return nil, errors.New("error linking shader for SHADER_SRC, glError: " + fmt.Sprint(glErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -297,7 +297,8 @@ func buildCode(buf *bytes.Buffer, baseName string, inputs []ShaderInput) {
|
||||||
part = strings.Replace(part, "SHADER_VAR", "fs", -1)
|
part = strings.Replace(part, "SHADER_VAR", "fs", -1)
|
||||||
fmt.Fprint(buf, part)
|
fmt.Fprint(buf, part)
|
||||||
|
|
||||||
fmt.Fprint(buf, linkPart)
|
part = strings.Replace(linkPart, "SHADER_SRC", fsName, -1)
|
||||||
|
fmt.Fprint(buf, part)
|
||||||
|
|
||||||
fmt.Fprint(buf, "\n")
|
fmt.Fprint(buf, "\n")
|
||||||
fmt.Fprintf(buf, "\tresult := &%s{}\n", shaderName)
|
fmt.Fprintf(buf, "\tresult := &%s{}\n", shaderName)
|
||||||
|
|
257
shaders.go
Normal file
257
shaders.go
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
package canvas
|
||||||
|
|
||||||
|
var imageVS = `
|
||||||
|
attribute vec2 vertex, texCoord;
|
||||||
|
uniform vec2 canvasSize;
|
||||||
|
varying vec2 v_texCoord;
|
||||||
|
void main() {
|
||||||
|
v_texCoord = texCoord;
|
||||||
|
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||||
|
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||||
|
}`
|
||||||
|
var imageFS = `
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
varying vec2 v_texCoord;
|
||||||
|
uniform sampler2D image;
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = texture2D(image, v_texCoord);
|
||||||
|
}`
|
||||||
|
|
||||||
|
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;
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = color;
|
||||||
|
}`
|
||||||
|
|
||||||
|
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 mat3 invmat;
|
||||||
|
uniform sampler1D gradient;
|
||||||
|
uniform vec2 from, dir;
|
||||||
|
uniform float len;
|
||||||
|
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);
|
||||||
|
}`
|
||||||
|
|
||||||
|
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 mat3 invmat;
|
||||||
|
uniform sampler1D gradient;
|
||||||
|
uniform vec2 from, to, dir;
|
||||||
|
uniform float radFrom, radTo;
|
||||||
|
uniform float len;
|
||||||
|
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)
|
||||||
|
*(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_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);
|
||||||
|
gl_FragColor = texture1D(gradient, o);
|
||||||
|
}`
|
||||||
|
|
||||||
|
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 mat3 invmat;
|
||||||
|
uniform sampler2D image;
|
||||||
|
void main() {
|
||||||
|
vec3 untf = vec3(v_cp, 1.0) * invmat;
|
||||||
|
gl_FragColor = texture2D(image, mod(untf.xy / imageSize, 1.0));
|
||||||
|
}`
|
||||||
|
|
||||||
|
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;
|
||||||
|
void main() {
|
||||||
|
vec4 col = color;
|
||||||
|
col.a *= texture2D(alphaTex, v_atc).a;
|
||||||
|
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 mat3 invmat;
|
||||||
|
uniform sampler1D gradient;
|
||||||
|
uniform vec2 from, dir;
|
||||||
|
uniform float len;
|
||||||
|
uniform sampler2D alphaTex;
|
||||||
|
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;
|
||||||
|
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 mat3 invmat;
|
||||||
|
uniform sampler1D gradient;
|
||||||
|
uniform vec2 from, to, dir;
|
||||||
|
uniform float radFrom, radTo;
|
||||||
|
uniform float len;
|
||||||
|
uniform sampler2D alphaTex;
|
||||||
|
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)
|
||||||
|
*(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_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 = texture1D(gradient, o);
|
||||||
|
col.a *= texture2D(alphaTex, v_atc).a;
|
||||||
|
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 mat3 invmat;
|
||||||
|
uniform sampler2D image;
|
||||||
|
uniform sampler2D alphaTex;
|
||||||
|
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;
|
||||||
|
gl_FragColor = col;
|
||||||
|
}`
|
113
text.go
113
text.go
|
@ -2,13 +2,13 @@ package canvas
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"image"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/golang/freetype"
|
"github.com/golang/freetype"
|
||||||
"github.com/golang/freetype/truetype"
|
"github.com/golang/freetype/truetype"
|
||||||
"github.com/tfriedel6/lm"
|
"github.com/tfriedel6/lm"
|
||||||
|
"golang.org/x/image/font"
|
||||||
"golang.org/x/image/math/fixed"
|
"golang.org/x/image/math/fixed"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,66 +53,69 @@ func LoadFont(src interface{}, name string) (*Font, error) {
|
||||||
func (cv *Canvas) FillText(str string, x, y float32) {
|
func (cv *Canvas) FillText(str string, x, y float32) {
|
||||||
cv.activate()
|
cv.activate()
|
||||||
|
|
||||||
if cv.text.target == nil || cv.text.target.Bounds().Dx() != cv.w || cv.text.target.Bounds().Dy() != cv.h {
|
frc := fontRenderingContext
|
||||||
if cv.text.tex != 0 {
|
frc.setFont(cv.state.font.font)
|
||||||
gli.DeleteTextures(1, &cv.text.tex)
|
frc.setFontSize(float64(cv.state.fontSize))
|
||||||
}
|
|
||||||
cv.text.target = image.NewRGBA(image.Rect(0, 0, cv.w, cv.h))
|
|
||||||
gli.GenTextures(1, &cv.text.tex)
|
|
||||||
gli.ActiveTexture(gl_TEXTURE0)
|
|
||||||
gli.BindTexture(gl_TEXTURE_2D, cv.text.tex)
|
|
||||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_NEAREST)
|
|
||||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_NEAREST)
|
|
||||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE)
|
|
||||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE)
|
|
||||||
gli.TexImage2D(gl_TEXTURE_2D, 0, gl_RGBA, int32(cv.w), int32(cv.h), 0, gl_RGBA, gl_UNSIGNED_BYTE, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
fontRenderingContext.setFont(cv.state.font.font)
|
|
||||||
fontRenderingContext.setFontSize(float64(cv.state.fontSize))
|
|
||||||
fontRenderingContext.setSrc(image.NewUniform(colorGLToGo(cv.state.fill.color)))
|
|
||||||
fontRenderingContext.setDst(cv.text.target)
|
|
||||||
fontRenderingContext.setClip(cv.text.target.Bounds())
|
|
||||||
_, bounds, _ := fontRenderingContext.drawString(str, fixed.Point26_6{X: fixed.Int26_6(x*64 + 0.5), Y: fixed.Int26_6(y*64 + 0.5)})
|
|
||||||
subImg := cv.text.target.SubImage(bounds).(*image.RGBA)
|
|
||||||
|
|
||||||
gli.BlendFunc(gl_ONE, gl_ONE_MINUS_SRC_ALPHA)
|
|
||||||
|
|
||||||
gli.ActiveTexture(gl_TEXTURE0)
|
|
||||||
gli.BindTexture(gl_TEXTURE_2D, cv.text.tex)
|
|
||||||
|
|
||||||
for y, w, h := 0, bounds.Dx(), bounds.Dy(); y < h; y++ {
|
|
||||||
off := y * subImg.Stride
|
|
||||||
pix := subImg.Pix
|
|
||||||
gli.TexSubImage2D(gl_TEXTURE_2D, 0, 0, int32(cv.h-1-y), int32(w), 1, gl_RGBA, gl_UNSIGNED_BYTE, gli.Ptr(&pix[off]))
|
|
||||||
for b := w * 4; b > 0; b-- {
|
|
||||||
pix[off] = 0
|
|
||||||
off++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||||
p0 := cv.tf(lm.Vec2{float32(bounds.Min.X), float32(bounds.Min.Y)})
|
|
||||||
p1 := cv.tf(lm.Vec2{float32(bounds.Min.X), float32(bounds.Max.Y)})
|
vertex, alphaTexCoord := cv.useAlphaShader(&cv.state.fill, 1)
|
||||||
p2 := cv.tf(lm.Vec2{float32(bounds.Max.X), float32(bounds.Max.Y)})
|
|
||||||
p3 := cv.tf(lm.Vec2{float32(bounds.Max.X), float32(bounds.Min.Y)})
|
gli.ActiveTexture(gl_TEXTURE1)
|
||||||
tw := float32(bounds.Max.X-bounds.Min.X) / cv.fw
|
gli.BindTexture(gl_TEXTURE_2D, alphaTex)
|
||||||
th := float32(bounds.Max.Y-bounds.Min.Y) / cv.fh
|
|
||||||
|
gli.EnableVertexAttribArray(vertex)
|
||||||
|
gli.EnableVertexAttribArray(alphaTexCoord)
|
||||||
|
|
||||||
|
fnt := cv.state.font.font
|
||||||
|
|
||||||
|
prev, hasPrev := truetype.Index(0), false
|
||||||
|
for _, rn := range str {
|
||||||
|
idx := fnt.Index(rn)
|
||||||
|
if idx == 0 {
|
||||||
|
prev = 0
|
||||||
|
hasPrev = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hasPrev {
|
||||||
|
kern := fnt.Kern(frc.scale, prev, idx)
|
||||||
|
if frc.hinting != font.HintingNone {
|
||||||
|
kern = (kern + 32) &^ 63
|
||||||
|
}
|
||||||
|
x += float32(kern) / 64
|
||||||
|
}
|
||||||
|
advance, mask, offset, err := frc.glyph(idx, fixed.Point26_6{})
|
||||||
|
if err != nil {
|
||||||
|
prev = 0
|
||||||
|
hasPrev = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
bounds := mask.Bounds().Add(offset)
|
||||||
|
|
||||||
|
for y, w, h := 0, bounds.Dx(), bounds.Dy(); y < h; y++ {
|
||||||
|
off := y * mask.Stride
|
||||||
|
gli.TexSubImage2D(gl_TEXTURE_2D, 0, 0, int32(bufferTextureSize-1-y), int32(w), 1, gl_ALPHA, gl_UNSIGNED_BYTE, gli.Ptr(&mask.Pix[off]))
|
||||||
|
}
|
||||||
|
|
||||||
|
p0 := cv.tf(lm.Vec2{float32(bounds.Min.X) + x, float32(bounds.Min.Y) + y})
|
||||||
|
p1 := cv.tf(lm.Vec2{float32(bounds.Min.X) + x, float32(bounds.Max.Y) + y})
|
||||||
|
p2 := cv.tf(lm.Vec2{float32(bounds.Max.X) + x, float32(bounds.Max.Y) + y})
|
||||||
|
p3 := cv.tf(lm.Vec2{float32(bounds.Max.X) + x, float32(bounds.Min.Y) + y})
|
||||||
|
tw := float32(bounds.Dx()) / bufferTextureSize
|
||||||
|
th := float32(bounds.Dy()) / bufferTextureSize
|
||||||
data := [16]float32{p0[0], p0[1], p1[0], p1[1], p2[0], p2[1], p3[0], p3[1],
|
data := [16]float32{p0[0], p0[1], p1[0], p1[1], p2[0], p2[1], p3[0], p3[1],
|
||||||
0, 1, 0, 1 - th, tw, 1 - th, tw, 1}
|
0, 1, 0, 1 - th, tw, 1 - th, tw, 1}
|
||||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||||
|
|
||||||
gli.UseProgram(tr.id)
|
gli.VertexAttribPointer(vertex, 2, gl_FLOAT, false, 0, nil)
|
||||||
gli.Uniform2f(tr.canvasSize, cv.fw, cv.fh)
|
gli.VertexAttribPointer(alphaTexCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
||||||
gli.Uniform1i(tr.image, 0)
|
|
||||||
|
|
||||||
gli.VertexAttribPointer(tr.vertex, 2, gl_FLOAT, false, 0, nil)
|
|
||||||
gli.VertexAttribPointer(tr.texCoord, 2, gl_FLOAT, false, 0, gli.PtrOffset(8*4))
|
|
||||||
gli.EnableVertexAttribArray(tr.vertex)
|
|
||||||
gli.EnableVertexAttribArray(tr.texCoord)
|
|
||||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||||
gli.DisableVertexAttribArray(tr.vertex)
|
|
||||||
gli.DisableVertexAttribArray(tr.texCoord)
|
|
||||||
|
|
||||||
gli.BlendFunc(gl_SRC_ALPHA, gl_ONE_MINUS_SRC_ALPHA)
|
x += float32(advance) / 64
|
||||||
|
}
|
||||||
|
|
||||||
|
gli.DisableVertexAttribArray(vertex)
|
||||||
|
gli.DisableVertexAttribArray(alphaTexCoord)
|
||||||
|
|
||||||
|
gli.ActiveTexture(gl_TEXTURE0)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue