implemented shadowBlur (wip)
This commit is contained in:
parent
0cb030619e
commit
f2225e857a
9 changed files with 860 additions and 276 deletions
94
canvas.go
94
canvas.go
|
@ -50,6 +50,7 @@ type drawState struct {
|
|||
shadowColor glColor
|
||||
shadowOffsetX float64
|
||||
shadowOffsetY float64
|
||||
shadowBlur float64
|
||||
|
||||
/*
|
||||
The current transformation matrix.
|
||||
|
@ -190,14 +191,22 @@ var (
|
|||
lgar *linearGradientAlphaShader
|
||||
ipar *imagePatternAlphaShader
|
||||
ir *imageShader
|
||||
offScrTex uint32
|
||||
offScrW int
|
||||
offScrH int
|
||||
renderStencilBuf uint32
|
||||
frameBuf uint32
|
||||
gauss15r *gaussian15Shader
|
||||
gauss63r *gaussian63Shader
|
||||
gauss255r *gaussian255Shader
|
||||
offscr1 offscreenBuffer
|
||||
offscr2 offscreenBuffer
|
||||
glChan = make(chan func())
|
||||
)
|
||||
|
||||
type offscreenBuffer struct {
|
||||
tex uint32
|
||||
w int
|
||||
h int
|
||||
renderStencilBuf uint32
|
||||
frameBuf uint32
|
||||
}
|
||||
|
||||
// LoadGL needs to be called once per GL context to load the GL assets
|
||||
// that canvas needs. The parameter is an implementation of the GL interface
|
||||
// in this package that should make this package neutral to GL implementations.
|
||||
|
@ -288,6 +297,33 @@ func LoadGL(glimpl GL) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
gauss15r, err = loadGaussian15Shader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = glError()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
gauss63r, err = loadGaussian63Shader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = glError()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
gauss255r, err = loadGaussian255Shader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = glError()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
gli.GenBuffers(1, &buf)
|
||||
err = glError()
|
||||
if err != nil {
|
||||
|
@ -514,32 +550,33 @@ func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLo
|
|||
return sar.vertex, sar.alphaTexCoord
|
||||
}
|
||||
|
||||
func (cv *Canvas) enableTextureRenderTarget() {
|
||||
if offScrW != cv.w || offScrH != cv.h {
|
||||
if offScrW != 0 && offScrH != 0 {
|
||||
gli.DeleteTextures(1, &offScrTex)
|
||||
gli.DeleteFramebuffers(1, &frameBuf)
|
||||
gli.DeleteRenderbuffers(1, &renderStencilBuf)
|
||||
func (cv *Canvas) enableTextureRenderTarget(offscr *offscreenBuffer) {
|
||||
if offscr.w != cv.w || offscr.h != cv.h {
|
||||
if offscr.w != 0 && offscr.h != 0 {
|
||||
gli.DeleteTextures(1, &offscr.tex)
|
||||
gli.DeleteFramebuffers(1, &offscr.frameBuf)
|
||||
gli.DeleteRenderbuffers(1, &offscr.renderStencilBuf)
|
||||
}
|
||||
offScrW = cv.w
|
||||
offScrH = cv.h
|
||||
offscr.w = cv.w
|
||||
offscr.h = cv.h
|
||||
|
||||
gli.GenTextures(1, &offScrTex)
|
||||
gli.BindTexture(gl_TEXTURE_2D, offScrTex)
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.GenTextures(1, &offscr.tex)
|
||||
gli.BindTexture(gl_TEXTURE_2D, offscr.tex)
|
||||
// todo do non-power-of-two textures work everywhere?
|
||||
gli.TexImage2D(gl_TEXTURE_2D, 0, gl_RGB, int32(cv.w), int32(cv.h), 0, gl_RGB, gl_UNSIGNED_BYTE, nil)
|
||||
gli.TexImage2D(gl_TEXTURE_2D, 0, gl_RGBA, int32(cv.w), int32(cv.h), 0, gl_RGBA, gl_UNSIGNED_BYTE, nil)
|
||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_NEAREST)
|
||||
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_NEAREST)
|
||||
|
||||
gli.GenFramebuffers(1, &frameBuf)
|
||||
gli.BindFramebuffer(gl_FRAMEBUFFER, frameBuf)
|
||||
gli.GenFramebuffers(1, &offscr.frameBuf)
|
||||
gli.BindFramebuffer(gl_FRAMEBUFFER, offscr.frameBuf)
|
||||
|
||||
gli.GenRenderbuffers(1, &renderStencilBuf)
|
||||
gli.BindRenderbuffer(gl_RENDERBUFFER, renderStencilBuf)
|
||||
gli.GenRenderbuffers(1, &offscr.renderStencilBuf)
|
||||
gli.BindRenderbuffer(gl_RENDERBUFFER, offscr.renderStencilBuf)
|
||||
gli.RenderbufferStorage(gl_RENDERBUFFER, gl_DEPTH_STENCIL, int32(cv.w), int32(cv.h))
|
||||
gli.FramebufferRenderbuffer(gl_FRAMEBUFFER, gl_DEPTH_STENCIL_ATTACHMENT, gl_RENDERBUFFER, renderStencilBuf)
|
||||
gli.FramebufferRenderbuffer(gl_FRAMEBUFFER, gl_DEPTH_STENCIL_ATTACHMENT, gl_RENDERBUFFER, offscr.renderStencilBuf)
|
||||
|
||||
gli.FramebufferTexture(gl_FRAMEBUFFER, gl_COLOR_ATTACHMENT0, offScrTex, 0)
|
||||
gli.FramebufferTexture(gl_FRAMEBUFFER, gl_COLOR_ATTACHMENT0, offscr.tex, 0)
|
||||
|
||||
if gli.CheckFramebufferStatus(gl_FRAMEBUFFER) != gl_FRAMEBUFFER_COMPLETE {
|
||||
// todo this should maybe not panic
|
||||
|
@ -548,7 +585,7 @@ func (cv *Canvas) enableTextureRenderTarget() {
|
|||
|
||||
gli.Clear(gl_COLOR_BUFFER_BIT | gl_STENCIL_BUFFER_BIT)
|
||||
} else {
|
||||
gli.BindFramebuffer(gl_FRAMEBUFFER, frameBuf)
|
||||
gli.BindFramebuffer(gl_FRAMEBUFFER, offscr.frameBuf)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -556,11 +593,6 @@ func (cv *Canvas) disableTextureRenderTarget() {
|
|||
gli.BindFramebuffer(gl_FRAMEBUFFER, 0)
|
||||
}
|
||||
|
||||
func (cv *Canvas) renderOffscreenTexture() {
|
||||
img := Image{w: cv.w, h: cv.h, tex: offScrTex}
|
||||
cv.DrawImage(&img, 0, 0, cv.fw, cv.fh)
|
||||
}
|
||||
|
||||
// SetLineWidth sets the line width for any line drawing calls
|
||||
func (cv *Canvas) SetLineWidth(width float64) {
|
||||
if width < 0 {
|
||||
|
@ -720,3 +752,9 @@ func (cv *Canvas) SetShadowOffset(x, y float64) {
|
|||
cv.state.shadowOffsetX = x
|
||||
cv.state.shadowOffsetY = y
|
||||
}
|
||||
|
||||
// SetShadowBlur sets the gaussian blur radius of the shadow
|
||||
// (0 for no blur)
|
||||
func (cv *Canvas) SetShadowBlur(r float64) {
|
||||
cv.state.shadowBlur = r
|
||||
}
|
||||
|
|
|
@ -181,6 +181,9 @@ func (_ GLImpl) TexSubImage2D(target uint32, level int32, xoffset int32, yoffset
|
|||
func (_ GLImpl) Uniform1f(location int32, v0 float32) {
|
||||
gl.Uniform1f(location, v0)
|
||||
}
|
||||
func (_ GLImpl) Uniform1fv(location int32, count int32, v *float32) {
|
||||
gl.Uniform1fv(location, count, v)
|
||||
}
|
||||
func (_ GLImpl) Uniform1i(location int32, v0 int32) {
|
||||
gl.Uniform1i(location, v0)
|
||||
}
|
||||
|
|
63
images.go
63
images.go
|
@ -309,3 +309,66 @@ func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
|
|||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
}
|
||||
|
||||
func (cv *Canvas) drawImageTemp(image interface{}, coords ...float64) {
|
||||
img := getImage(image)
|
||||
|
||||
if img == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if img.deleted {
|
||||
return
|
||||
}
|
||||
|
||||
cv.activate()
|
||||
|
||||
var sx, sy, sw, sh, dx, dy, dw, dh float64
|
||||
sw, sh = float64(img.w), float64(img.h)
|
||||
dw, dh = float64(img.w), float64(img.h)
|
||||
if len(coords) == 2 {
|
||||
dx, dy = coords[0], coords[1]
|
||||
} else if len(coords) == 4 {
|
||||
dx, dy = coords[0], coords[1]
|
||||
dw, dh = coords[2], coords[3]
|
||||
} else if len(coords) == 8 {
|
||||
sx, sy = coords[0], coords[1]
|
||||
sw, sh = coords[2], coords[3]
|
||||
dx, dy = coords[4], coords[5]
|
||||
dw, dh = coords[6], coords[7]
|
||||
}
|
||||
|
||||
sx /= float64(img.w)
|
||||
sy /= float64(img.h)
|
||||
sw /= float64(img.w)
|
||||
sh /= float64(img.h)
|
||||
|
||||
p0 := vec{dx, dy}
|
||||
p1 := vec{dx, dy + dh}
|
||||
p2 := vec{dx + dw, dy + dh}
|
||||
p3 := vec{dx + dw, dy}
|
||||
|
||||
gli.StencilFunc(gl_EQUAL, 0, 0xFF)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, shadowBuf)
|
||||
data := [16]float32{float32(p0[0]), float32(p0[1]), float32(p1[0]), float32(p1[1]), float32(p2[0]), float32(p2[1]), float32(p3[0]), float32(p3[1]),
|
||||
float32(sx), float32(sy), float32(sx), float32(sy + sh), float32(sx + sw), float32(sy + sh), float32(sx + sw), float32(sy)}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.BindTexture(gl_TEXTURE_2D, img.tex)
|
||||
|
||||
gli.UseProgram(ir.id)
|
||||
gli.Uniform1i(ir.image, 0)
|
||||
gli.Uniform2f(ir.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
gli.Uniform1f(ir.globalAlpha, float32(cv.state.globalAlpha))
|
||||
gli.VertexAttribPointer(ir.vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
gli.VertexAttribPointer(ir.texCoord, 2, gl_FLOAT, false, 0, 8*4)
|
||||
gli.EnableVertexAttribArray(ir.vertex)
|
||||
gli.EnableVertexAttribArray(ir.texCoord)
|
||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||
gli.DisableVertexAttribArray(ir.vertex)
|
||||
gli.DisableVertexAttribArray(ir.texCoord)
|
||||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
}
|
||||
|
|
734
made_shaders.go
734
made_shaders.go
|
@ -5,63 +5,58 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
type radialGradientShader struct {
|
||||
type gaussian63Shader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
texCoord uint32
|
||||
canvasSize int32
|
||||
invmat int32
|
||||
gradient int32
|
||||
from int32
|
||||
to int32
|
||||
dir int32
|
||||
radFrom int32
|
||||
radTo int32
|
||||
len int32
|
||||
globalAlpha int32
|
||||
kernelScale int32
|
||||
image int32
|
||||
kernel int32
|
||||
}
|
||||
|
||||
func loadRadialGradientShader() (*radialGradientShader, error) {
|
||||
func loadGaussian63Shader() (*gaussian63Shader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||
gli.ShaderSource(vs, radialGradientVS)
|
||||
gli.ShaderSource(vs, gaussian63VS)
|
||||
gli.CompileShader(vs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(vs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("VERTEX_SHADER compilation log for radialGradientVS:\n\n%s\n", shLog)
|
||||
fmt.Printf("VERTEX_SHADER compilation log for gaussian63VS:\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 radialGradientVS")
|
||||
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for gaussian63VS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for radialGradientVS, glError: " + fmt.Sprint(glErr))
|
||||
return nil, errors.New("error compiling shader part for gaussian63VS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||
gli.ShaderSource(fs, radialGradientFS)
|
||||
gli.ShaderSource(fs, gaussian63FS)
|
||||
gli.CompileShader(fs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(fs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for radialGradientFS:\n\n%s\n", shLog)
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for gaussian63FS:\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 radialGradientFS")
|
||||
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for gaussian63FS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for radialGradientFS, glError: " + fmt.Sprint(glErr))
|
||||
return nil, errors.New("error compiling shader part for gaussian63FS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +68,7 @@ func loadRadialGradientShader() (*radialGradientShader, error) {
|
|||
|
||||
shLog := gli.GetProgramInfoLog(program)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("Shader link log for radialGradientFS:\n\n%s\n", shLog)
|
||||
fmt.Printf("Shader link log for gaussian63FS:\n\n%s\n", shLog)
|
||||
}
|
||||
|
||||
var status int32
|
||||
|
@ -81,26 +76,21 @@ func loadRadialGradientShader() (*radialGradientShader, error) {
|
|||
if status != gl_TRUE {
|
||||
gli.DeleteShader(vs)
|
||||
gli.DeleteShader(fs)
|
||||
return nil, errors.New("error linking shader for radialGradientFS")
|
||||
return nil, errors.New("error linking shader for gaussian63FS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error linking shader for radialGradientFS, glError: " + fmt.Sprint(glErr))
|
||||
return nil, errors.New("error linking shader for gaussian63FS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
result := &radialGradientShader{}
|
||||
result := &gaussian63Shader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, "vertex"))
|
||||
result.texCoord = uint32(gli.GetAttribLocation(program, "texCoord"))
|
||||
result.canvasSize = gli.GetUniformLocation(program, "canvasSize")
|
||||
result.invmat = gli.GetUniformLocation(program, "invmat")
|
||||
result.gradient = gli.GetUniformLocation(program, "gradient")
|
||||
result.from = gli.GetUniformLocation(program, "from")
|
||||
result.to = gli.GetUniformLocation(program, "to")
|
||||
result.dir = gli.GetUniformLocation(program, "dir")
|
||||
result.radFrom = gli.GetUniformLocation(program, "radFrom")
|
||||
result.radTo = gli.GetUniformLocation(program, "radTo")
|
||||
result.len = gli.GetUniformLocation(program, "len")
|
||||
result.globalAlpha = gli.GetUniformLocation(program, "globalAlpha")
|
||||
result.kernelScale = gli.GetUniformLocation(program, "kernelScale")
|
||||
result.image = gli.GetUniformLocation(program, "image")
|
||||
result.kernel = gli.GetUniformLocation(program, "kernel")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
@ -191,190 +181,6 @@ func loadSolidShader() (*solidShader, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
type solidAlphaShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
alphaTexCoord uint32
|
||||
canvasSize int32
|
||||
color int32
|
||||
alphaTex int32
|
||||
globalAlpha int32
|
||||
}
|
||||
|
||||
func loadSolidAlphaShader() (*solidAlphaShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||
gli.ShaderSource(vs, solidAlphaVS)
|
||||
gli.CompileShader(vs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(vs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("VERTEX_SHADER compilation log for solidAlphaVS:\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 solidAlphaVS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for solidAlphaVS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||
gli.ShaderSource(fs, solidAlphaFS)
|
||||
gli.CompileShader(fs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(fs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for solidAlphaFS:\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 solidAlphaFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for solidAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
program = gli.CreateProgram()
|
||||
gli.AttachShader(program, vs)
|
||||
gli.AttachShader(program, fs)
|
||||
gli.LinkProgram(program)
|
||||
|
||||
shLog := gli.GetProgramInfoLog(program)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("Shader link log for solidAlphaFS:\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 solidAlphaFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error linking shader for solidAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
result := &solidAlphaShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, "vertex"))
|
||||
result.alphaTexCoord = uint32(gli.GetAttribLocation(program, "alphaTexCoord"))
|
||||
result.canvasSize = gli.GetUniformLocation(program, "canvasSize")
|
||||
result.color = gli.GetUniformLocation(program, "color")
|
||||
result.alphaTex = gli.GetUniformLocation(program, "alphaTex")
|
||||
result.globalAlpha = gli.GetUniformLocation(program, "globalAlpha")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type linearGradientShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
canvasSize int32
|
||||
invmat int32
|
||||
gradient int32
|
||||
from int32
|
||||
dir int32
|
||||
len int32
|
||||
globalAlpha int32
|
||||
}
|
||||
|
||||
func loadLinearGradientShader() (*linearGradientShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||
gli.ShaderSource(vs, linearGradientVS)
|
||||
gli.CompileShader(vs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(vs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("VERTEX_SHADER compilation log for linearGradientVS:\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 linearGradientVS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for linearGradientVS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||
gli.ShaderSource(fs, linearGradientFS)
|
||||
gli.CompileShader(fs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(fs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for linearGradientFS:\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 linearGradientFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for linearGradientFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
program = gli.CreateProgram()
|
||||
gli.AttachShader(program, vs)
|
||||
gli.AttachShader(program, fs)
|
||||
gli.LinkProgram(program)
|
||||
|
||||
shLog := gli.GetProgramInfoLog(program)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("Shader link log for linearGradientFS:\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 linearGradientFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error linking shader for linearGradientFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
result := &linearGradientShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, "vertex"))
|
||||
result.canvasSize = gli.GetUniformLocation(program, "canvasSize")
|
||||
result.invmat = gli.GetUniformLocation(program, "invmat")
|
||||
result.gradient = gli.GetUniformLocation(program, "gradient")
|
||||
result.from = gli.GetUniformLocation(program, "from")
|
||||
result.dir = gli.GetUniformLocation(program, "dir")
|
||||
result.len = gli.GetUniformLocation(program, "len")
|
||||
result.globalAlpha = gli.GetUniformLocation(program, "globalAlpha")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type linearGradientAlphaShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
|
@ -577,57 +383,58 @@ func loadRadialGradientAlphaShader() (*radialGradientAlphaShader, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
type imageShader struct {
|
||||
type gaussian15Shader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
texCoord uint32
|
||||
canvasSize int32
|
||||
kernelScale int32
|
||||
image int32
|
||||
globalAlpha int32
|
||||
kernel int32
|
||||
}
|
||||
|
||||
func loadImageShader() (*imageShader, error) {
|
||||
func loadGaussian15Shader() (*gaussian15Shader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||
gli.ShaderSource(vs, imageVS)
|
||||
gli.ShaderSource(vs, gaussian15VS)
|
||||
gli.CompileShader(vs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(vs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("VERTEX_SHADER compilation log for imageVS:\n\n%s\n", shLog)
|
||||
fmt.Printf("VERTEX_SHADER compilation log for gaussian15VS:\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")
|
||||
return nil, errors.New("Error compiling GL_VERTEX_SHADER shader part for gaussian15VS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for imageVS, glError: " + fmt.Sprint(glErr))
|
||||
return nil, errors.New("error compiling shader part for gaussian15VS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||
gli.ShaderSource(fs, imageFS)
|
||||
gli.ShaderSource(fs, gaussian15FS)
|
||||
gli.CompileShader(fs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(fs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for imageFS:\n\n%s\n", shLog)
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for gaussian15FS:\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")
|
||||
return nil, errors.New("Error compiling GL_FRAGMENT_SHADER shader part for gaussian15FS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for imageFS, glError: " + fmt.Sprint(glErr))
|
||||
return nil, errors.New("error compiling shader part for gaussian15FS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -639,7 +446,7 @@ func loadImageShader() (*imageShader, error) {
|
|||
|
||||
shLog := gli.GetProgramInfoLog(program)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("Shader link log for imageFS:\n\n%s\n", shLog)
|
||||
fmt.Printf("Shader link log for gaussian15FS:\n\n%s\n", shLog)
|
||||
}
|
||||
|
||||
var status int32
|
||||
|
@ -647,20 +454,21 @@ func loadImageShader() (*imageShader, error) {
|
|||
if status != gl_TRUE {
|
||||
gli.DeleteShader(vs)
|
||||
gli.DeleteShader(fs)
|
||||
return nil, errors.New("error linking shader for imageFS")
|
||||
return nil, errors.New("error linking shader for gaussian15FS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error linking shader for imageFS, glError: " + fmt.Sprint(glErr))
|
||||
return nil, errors.New("error linking shader for gaussian15FS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
result := &imageShader{}
|
||||
result := &gaussian15Shader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, "vertex"))
|
||||
result.texCoord = uint32(gli.GetAttribLocation(program, "texCoord"))
|
||||
result.canvasSize = gli.GetUniformLocation(program, "canvasSize")
|
||||
result.kernelScale = gli.GetUniformLocation(program, "kernelScale")
|
||||
result.image = gli.GetUniformLocation(program, "image")
|
||||
result.globalAlpha = gli.GetUniformLocation(program, "globalAlpha")
|
||||
result.kernel = gli.GetUniformLocation(program, "kernel")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
@ -755,6 +563,468 @@ func loadImagePatternShader() (*imagePatternShader, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
type solidAlphaShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
alphaTexCoord uint32
|
||||
canvasSize int32
|
||||
color int32
|
||||
alphaTex int32
|
||||
globalAlpha int32
|
||||
}
|
||||
|
||||
func loadSolidAlphaShader() (*solidAlphaShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||
gli.ShaderSource(vs, solidAlphaVS)
|
||||
gli.CompileShader(vs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(vs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("VERTEX_SHADER compilation log for solidAlphaVS:\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 solidAlphaVS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for solidAlphaVS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||
gli.ShaderSource(fs, solidAlphaFS)
|
||||
gli.CompileShader(fs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(fs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for solidAlphaFS:\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 solidAlphaFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for solidAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
program = gli.CreateProgram()
|
||||
gli.AttachShader(program, vs)
|
||||
gli.AttachShader(program, fs)
|
||||
gli.LinkProgram(program)
|
||||
|
||||
shLog := gli.GetProgramInfoLog(program)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("Shader link log for solidAlphaFS:\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 solidAlphaFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error linking shader for solidAlphaFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
result := &solidAlphaShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, "vertex"))
|
||||
result.alphaTexCoord = uint32(gli.GetAttribLocation(program, "alphaTexCoord"))
|
||||
result.canvasSize = gli.GetUniformLocation(program, "canvasSize")
|
||||
result.color = gli.GetUniformLocation(program, "color")
|
||||
result.alphaTex = gli.GetUniformLocation(program, "alphaTex")
|
||||
result.globalAlpha = gli.GetUniformLocation(program, "globalAlpha")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type gaussian255Shader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
texCoord uint32
|
||||
canvasSize int32
|
||||
kernelScale int32
|
||||
image int32
|
||||
kernel int32
|
||||
}
|
||||
|
||||
func loadGaussian255Shader() (*gaussian255Shader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||
gli.ShaderSource(vs, gaussian255VS)
|
||||
gli.CompileShader(vs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(vs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("VERTEX_SHADER compilation log for gaussian255VS:\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 gaussian255VS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for gaussian255VS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||
gli.ShaderSource(fs, gaussian255FS)
|
||||
gli.CompileShader(fs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(fs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for gaussian255FS:\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 gaussian255FS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for gaussian255FS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
program = gli.CreateProgram()
|
||||
gli.AttachShader(program, vs)
|
||||
gli.AttachShader(program, fs)
|
||||
gli.LinkProgram(program)
|
||||
|
||||
shLog := gli.GetProgramInfoLog(program)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("Shader link log for gaussian255FS:\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 gaussian255FS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error linking shader for gaussian255FS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
result := &gaussian255Shader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, "vertex"))
|
||||
result.texCoord = uint32(gli.GetAttribLocation(program, "texCoord"))
|
||||
result.canvasSize = gli.GetUniformLocation(program, "canvasSize")
|
||||
result.kernelScale = gli.GetUniformLocation(program, "kernelScale")
|
||||
result.image = gli.GetUniformLocation(program, "image")
|
||||
result.kernel = gli.GetUniformLocation(program, "kernel")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type radialGradientShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
canvasSize int32
|
||||
invmat int32
|
||||
gradient int32
|
||||
from int32
|
||||
to int32
|
||||
dir int32
|
||||
radFrom int32
|
||||
radTo int32
|
||||
len int32
|
||||
globalAlpha int32
|
||||
}
|
||||
|
||||
func loadRadialGradientShader() (*radialGradientShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||
gli.ShaderSource(vs, radialGradientVS)
|
||||
gli.CompileShader(vs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(vs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("VERTEX_SHADER compilation log for radialGradientVS:\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 radialGradientVS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for radialGradientVS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||
gli.ShaderSource(fs, radialGradientFS)
|
||||
gli.CompileShader(fs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(fs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for radialGradientFS:\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 radialGradientFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for radialGradientFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
program = gli.CreateProgram()
|
||||
gli.AttachShader(program, vs)
|
||||
gli.AttachShader(program, fs)
|
||||
gli.LinkProgram(program)
|
||||
|
||||
shLog := gli.GetProgramInfoLog(program)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("Shader link log for radialGradientFS:\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 radialGradientFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error linking shader for radialGradientFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
result := &radialGradientShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, "vertex"))
|
||||
result.canvasSize = gli.GetUniformLocation(program, "canvasSize")
|
||||
result.invmat = gli.GetUniformLocation(program, "invmat")
|
||||
result.gradient = gli.GetUniformLocation(program, "gradient")
|
||||
result.from = gli.GetUniformLocation(program, "from")
|
||||
result.to = gli.GetUniformLocation(program, "to")
|
||||
result.dir = gli.GetUniformLocation(program, "dir")
|
||||
result.radFrom = gli.GetUniformLocation(program, "radFrom")
|
||||
result.radTo = gli.GetUniformLocation(program, "radTo")
|
||||
result.len = gli.GetUniformLocation(program, "len")
|
||||
result.globalAlpha = gli.GetUniformLocation(program, "globalAlpha")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type linearGradientShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
canvasSize int32
|
||||
invmat int32
|
||||
gradient int32
|
||||
from int32
|
||||
dir int32
|
||||
len int32
|
||||
globalAlpha int32
|
||||
}
|
||||
|
||||
func loadLinearGradientShader() (*linearGradientShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||
gli.ShaderSource(vs, linearGradientVS)
|
||||
gli.CompileShader(vs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(vs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("VERTEX_SHADER compilation log for linearGradientVS:\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 linearGradientVS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for linearGradientVS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||
gli.ShaderSource(fs, linearGradientFS)
|
||||
gli.CompileShader(fs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(fs)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("FRAGMENT_SHADER compilation log for linearGradientFS:\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 linearGradientFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error compiling shader part for linearGradientFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
program = gli.CreateProgram()
|
||||
gli.AttachShader(program, vs)
|
||||
gli.AttachShader(program, fs)
|
||||
gli.LinkProgram(program)
|
||||
|
||||
shLog := gli.GetProgramInfoLog(program)
|
||||
if len(shLog) > 0 {
|
||||
fmt.Printf("Shader link log for linearGradientFS:\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 linearGradientFS")
|
||||
}
|
||||
if glErr := gli.GetError(); glErr != gl_NO_ERROR {
|
||||
return nil, errors.New("error linking shader for linearGradientFS, glError: " + fmt.Sprint(glErr))
|
||||
}
|
||||
}
|
||||
|
||||
result := &linearGradientShader{}
|
||||
result.id = program
|
||||
result.vertex = uint32(gli.GetAttribLocation(program, "vertex"))
|
||||
result.canvasSize = gli.GetUniformLocation(program, "canvasSize")
|
||||
result.invmat = gli.GetUniformLocation(program, "invmat")
|
||||
result.gradient = gli.GetUniformLocation(program, "gradient")
|
||||
result.from = gli.GetUniformLocation(program, "from")
|
||||
result.dir = gli.GetUniformLocation(program, "dir")
|
||||
result.len = gli.GetUniformLocation(program, "len")
|
||||
result.globalAlpha = gli.GetUniformLocation(program, "globalAlpha")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type imageShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
texCoord uint32
|
||||
canvasSize int32
|
||||
image int32
|
||||
globalAlpha int32
|
||||
}
|
||||
|
||||
func loadImageShader() (*imageShader, error) {
|
||||
var vs, fs, program uint32
|
||||
|
||||
{
|
||||
vs = gli.CreateShader(gl_VERTEX_SHADER)
|
||||
gli.ShaderSource(vs, imageVS)
|
||||
gli.CompileShader(vs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(vs)
|
||||
if len(shLog) > 0 {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fs = gli.CreateShader(gl_FRAGMENT_SHADER)
|
||||
gli.ShaderSource(fs, imageFS)
|
||||
gli.CompileShader(fs)
|
||||
|
||||
shLog := gli.GetShaderInfoLog(fs)
|
||||
if len(shLog) > 0 {
|
||||
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)
|
||||
|
||||
shLog := gli.GetProgramInfoLog(program)
|
||||
if len(shLog) > 0 {
|
||||
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, "vertex"))
|
||||
result.texCoord = uint32(gli.GetAttribLocation(program, "texCoord"))
|
||||
result.canvasSize = gli.GetUniformLocation(program, "canvasSize")
|
||||
result.image = gli.GetUniformLocation(program, "image")
|
||||
result.globalAlpha = gli.GetUniformLocation(program, "globalAlpha")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type imagePatternAlphaShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
|
|
|
@ -116,9 +116,12 @@ func shaderFindInputVariables(source string) []ShaderInput {
|
|||
if !isAttrib && !isUniform {
|
||||
continue
|
||||
}
|
||||
for i := 2; i < len(parts); i++ {
|
||||
for _, part := range parts[2:] {
|
||||
if idx := strings.IndexByte(part, '['); idx >= 0 {
|
||||
part = part[:idx]
|
||||
}
|
||||
inputs = append(inputs, ShaderInput{
|
||||
Name: parts[i],
|
||||
Name: part,
|
||||
IsAttrib: isAttrib,
|
||||
IsUniform: isUniform})
|
||||
}
|
||||
|
|
|
@ -844,6 +844,7 @@ type GL interface {
|
|||
TexParameteri(target uint32, pname uint32, param int32)
|
||||
TexSubImage2D(target uint32, level int32, xoffset int32, yoffset int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer)
|
||||
Uniform1f(location int32, v0 float32)
|
||||
Uniform1fv(location int32, count int32, v *float32)
|
||||
Uniform1i(location int32, v0 int32)
|
||||
Uniform2f(location int32, v0 float32, v1 float32)
|
||||
Uniform4f(location int32, v0 float32, v1 float32, v2 float32, v3 float32)
|
||||
|
|
97
shaders.go
97
shaders.go
|
@ -1,5 +1,11 @@
|
|||
package canvas
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var imageVS = `
|
||||
attribute vec2 vertex, texCoord;
|
||||
uniform vec2 canvasSize;
|
||||
|
@ -274,3 +280,94 @@ void main() {
|
|||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var gaussian15VS = `
|
||||
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 gaussian15FS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_texCoord;
|
||||
uniform vec2 kernelScale;
|
||||
uniform sampler2D image;
|
||||
uniform float kernel[15];
|
||||
void main() {
|
||||
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
_SUM_
|
||||
gl_FragColor = color;
|
||||
}`
|
||||
|
||||
var gaussian63VS = `
|
||||
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 gaussian63FS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_texCoord;
|
||||
uniform vec2 kernelScale;
|
||||
uniform sampler2D image;
|
||||
uniform float kernel[63];
|
||||
void main() {
|
||||
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
_SUM_
|
||||
gl_FragColor = color;
|
||||
}`
|
||||
|
||||
var gaussian255VS = `
|
||||
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 gaussian255FS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_texCoord;
|
||||
uniform vec2 kernelScale;
|
||||
uniform sampler2D image;
|
||||
uniform float kernel[255];
|
||||
void main() {
|
||||
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
_SUM_
|
||||
gl_FragColor = color;
|
||||
}`
|
||||
|
||||
func init() {
|
||||
fstr := "\tcolor += texture2D(image, v_texCoord + vec2(%.1f * kernelScale.x, %.1f * kernelScale.y)) * kernel[%d];\n"
|
||||
bb := bytes.Buffer{}
|
||||
for i := 0; i < 255; i++ {
|
||||
off := float64(i) - 127
|
||||
fmt.Fprintf(&bb, fstr, off, off, i)
|
||||
}
|
||||
gaussian255FS = strings.Replace(gaussian255FS, "_SUM_", bb.String(), -1)
|
||||
bb.Reset()
|
||||
for i := 0; i < 63; i++ {
|
||||
off := float64(i) - 31
|
||||
fmt.Fprintf(&bb, fstr, off, off, i)
|
||||
}
|
||||
gaussian63FS = strings.Replace(gaussian63FS, "_SUM_", bb.String(), -1)
|
||||
bb.Reset()
|
||||
for i := 0; i < 15; i++ {
|
||||
off := float64(i) - 7
|
||||
fmt.Fprintf(&bb, fstr, off, off, i)
|
||||
}
|
||||
gaussian15FS = strings.Replace(gaussian15FS, "_SUM_", bb.String(), -1)
|
||||
}
|
||||
|
|
106
shadows.go
106
shadows.go
|
@ -2,6 +2,7 @@ package canvas
|
|||
|
||||
import (
|
||||
"image"
|
||||
"math"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
|
@ -10,6 +11,12 @@ func (cv *Canvas) drawShadow(tris []float32) {
|
|||
return
|
||||
}
|
||||
|
||||
if cv.state.shadowBlur > 0 {
|
||||
cv.enableTextureRenderTarget(&offscr1)
|
||||
gli.ClearColor(0, 0, 0, 0)
|
||||
gli.Clear(gl_COLOR_BUFFER_BIT | gl_STENCIL_BUFFER_BIT)
|
||||
}
|
||||
|
||||
ox, oy := float32(cv.state.shadowOffsetX), float32(cv.state.shadowOffsetY)
|
||||
|
||||
count := len(tris)
|
||||
|
@ -53,12 +60,22 @@ func (cv *Canvas) drawShadow(tris []float32) {
|
|||
|
||||
gli.Clear(gl_STENCIL_BUFFER_BIT)
|
||||
gli.StencilMask(0xFF)
|
||||
|
||||
if cv.state.shadowBlur > 0 {
|
||||
cv.drawBlurredShadow()
|
||||
}
|
||||
}
|
||||
|
||||
func (cv *Canvas) drawTextShadow(offset image.Point, strWidth, strHeight int, x, y float64) {
|
||||
x += cv.state.shadowOffsetX
|
||||
y += cv.state.shadowOffsetY
|
||||
|
||||
if cv.state.shadowBlur > 0 {
|
||||
cv.enableTextureRenderTarget(&offscr1)
|
||||
gli.ClearColor(0, 0, 0, 0)
|
||||
gli.Clear(gl_COLOR_BUFFER_BIT | gl_STENCIL_BUFFER_BIT)
|
||||
}
|
||||
|
||||
gli.StencilFunc(gl_EQUAL, 0, 0xFF)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
|
@ -92,4 +109,93 @@ func (cv *Canvas) drawTextShadow(offset image.Point, strWidth, strHeight int, x,
|
|||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
|
||||
if cv.state.shadowBlur > 0 {
|
||||
cv.drawBlurredShadow()
|
||||
}
|
||||
}
|
||||
|
||||
func (cv *Canvas) drawBlurredShadow() {
|
||||
gli.BlendFunc(gl_ONE, gl_ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
var kernel [255]float32
|
||||
gaussianKernel(cv.state.shadowBlur, kernel[:])
|
||||
|
||||
cv.enableTextureRenderTarget(&offscr2)
|
||||
gli.ClearColor(0, 0, 0, 0)
|
||||
gli.Clear(gl_COLOR_BUFFER_BIT | gl_STENCIL_BUFFER_BIT)
|
||||
|
||||
gli.StencilFunc(gl_EQUAL, 0, 0xFF)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, shadowBuf)
|
||||
data := [16]float32{0, 0, 0, float32(cv.h), float32(cv.w), float32(cv.h), float32(cv.w), 0, 0, 0, 0, 1, 1, 1, 1, 0}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.BindTexture(gl_TEXTURE_2D, offscr1.tex)
|
||||
|
||||
gli.UseProgram(gauss255r.id)
|
||||
gli.Uniform1i(gauss255r.image, 0)
|
||||
gli.Uniform2f(gauss255r.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
gli.Uniform2f(gauss255r.kernelScale, 1.0/float32(cv.fw), 0.0)
|
||||
gli.Uniform1fv(gauss255r.kernel, int32(len(kernel)), &kernel[0])
|
||||
gli.VertexAttribPointer(gauss255r.vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
gli.VertexAttribPointer(gauss255r.texCoord, 2, gl_FLOAT, false, 0, 8*4)
|
||||
gli.EnableVertexAttribArray(gauss255r.vertex)
|
||||
gli.EnableVertexAttribArray(gauss255r.texCoord)
|
||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||
gli.DisableVertexAttribArray(gauss255r.vertex)
|
||||
gli.DisableVertexAttribArray(gauss255r.texCoord)
|
||||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
|
||||
cv.disableTextureRenderTarget()
|
||||
|
||||
gli.StencilFunc(gl_EQUAL, 0, 0xFF)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, shadowBuf)
|
||||
data = [16]float32{0, 0, 0, float32(cv.h), float32(cv.w), float32(cv.h), float32(cv.w), 0, 0, 0, 0, 1, 1, 1, 1, 0}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.BindTexture(gl_TEXTURE_2D, offscr2.tex)
|
||||
|
||||
gli.UseProgram(gauss255r.id)
|
||||
gli.Uniform1i(gauss255r.image, 0)
|
||||
gli.Uniform2f(gauss255r.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
gli.Uniform2f(gauss255r.kernelScale, 0.0, 1.0/float32(cv.fh))
|
||||
gli.Uniform1fv(gauss255r.kernel, int32(len(kernel)), &kernel[0])
|
||||
gli.VertexAttribPointer(gauss255r.vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
gli.VertexAttribPointer(gauss255r.texCoord, 2, gl_FLOAT, false, 0, 8*4)
|
||||
gli.EnableVertexAttribArray(gauss255r.vertex)
|
||||
gli.EnableVertexAttribArray(gauss255r.texCoord)
|
||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||
gli.DisableVertexAttribArray(gauss255r.vertex)
|
||||
gli.DisableVertexAttribArray(gauss255r.texCoord)
|
||||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
|
||||
gli.BlendFunc(gl_SRC_ALPHA, gl_ONE_MINUS_SRC_ALPHA)
|
||||
}
|
||||
|
||||
func gaussianKernel(stddev float64, target []float32) {
|
||||
stddevSqr := stddev * stddev
|
||||
center := float64(len(target) / 2)
|
||||
factor := 1.0 / math.Sqrt(2*math.Pi*stddevSqr)
|
||||
for i := range target {
|
||||
x := float64(i) - center
|
||||
target[i] = float32(factor * math.Pow(math.E, -x*x/(2*stddevSqr)))
|
||||
}
|
||||
normalizeKernel(target)
|
||||
}
|
||||
|
||||
func normalizeKernel(kernel []float32) {
|
||||
var sum float32
|
||||
for _, v := range kernel {
|
||||
sum += v
|
||||
}
|
||||
factor := 1.0 / sum
|
||||
for i := range kernel {
|
||||
kernel[i] *= factor
|
||||
}
|
||||
}
|
||||
|
|
5
text.go
5
text.go
|
@ -220,13 +220,16 @@ func (cv *Canvas) FillText(str string, x, y float64) {
|
|||
gli.DisableVertexAttribArray(vertex)
|
||||
gli.DisableVertexAttribArray(alphaTexCoord)
|
||||
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.ActiveTexture(gl_TEXTURE1)
|
||||
gli.BindTexture(gl_TEXTURE_2D, alphaTex)
|
||||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
|
||||
for y := 0; y < strHeight; y++ {
|
||||
gli.TexSubImage2D(gl_TEXTURE_2D, 0, 0, int32(alphaTexSize-1-y), int32(strWidth), 1, gl_ALPHA, gl_UNSIGNED_BYTE, gli.Ptr(&zeroes[0]))
|
||||
}
|
||||
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
}
|
||||
|
||||
// TextMetrics is the result of a MeasureText call
|
||||
|
|
Loading…
Reference in a new issue