vary the gaussian shader kernel size depending on the blur radius for better performance
This commit is contained in:
parent
f2225e857a
commit
afad74f7b2
2 changed files with 57 additions and 31 deletions
25
canvas.go
25
canvas.go
|
@ -191,9 +191,9 @@ var (
|
|||
lgar *linearGradientAlphaShader
|
||||
ipar *imagePatternAlphaShader
|
||||
ir *imageShader
|
||||
gauss15r *gaussian15Shader
|
||||
gauss63r *gaussian63Shader
|
||||
gauss255r *gaussian255Shader
|
||||
gauss15r *gaussianShader
|
||||
gauss63r *gaussianShader
|
||||
gauss255r *gaussianShader
|
||||
offscr1 offscreenBuffer
|
||||
offscr2 offscreenBuffer
|
||||
glChan = make(chan func())
|
||||
|
@ -207,6 +207,16 @@ type offscreenBuffer struct {
|
|||
frameBuf uint32
|
||||
}
|
||||
|
||||
type gaussianShader struct {
|
||||
id uint32
|
||||
vertex uint32
|
||||
texCoord uint32
|
||||
canvasSize int32
|
||||
kernelScale int32
|
||||
image int32
|
||||
kernel int32
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
@ -297,7 +307,7 @@ func LoadGL(glimpl GL) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
gauss15r, err = loadGaussian15Shader()
|
||||
gauss15s, err := loadGaussian15Shader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -305,8 +315,9 @@ func LoadGL(glimpl GL) (err error) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
gauss15r = (*gaussianShader)(gauss15s)
|
||||
|
||||
gauss63r, err = loadGaussian63Shader()
|
||||
gauss63s, err := loadGaussian63Shader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -314,8 +325,9 @@ func LoadGL(glimpl GL) (err error) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
gauss63r = (*gaussianShader)(gauss63s)
|
||||
|
||||
gauss255r, err = loadGaussian255Shader()
|
||||
gauss255s, err := loadGaussian255Shader()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -323,6 +335,7 @@ func LoadGL(glimpl GL) (err error) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
gauss255r = (*gaussianShader)(gauss255s)
|
||||
|
||||
gli.GenBuffers(1, &buf)
|
||||
err = glError()
|
||||
|
|
63
shadows.go
63
shadows.go
|
@ -118,8 +118,21 @@ func (cv *Canvas) drawTextShadow(offset image.Point, strWidth, strHeight int, x,
|
|||
func (cv *Canvas) drawBlurredShadow() {
|
||||
gli.BlendFunc(gl_ONE, gl_ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
var kernel [255]float32
|
||||
gaussianKernel(cv.state.shadowBlur, kernel[:])
|
||||
var kernel []float32
|
||||
var kernelBuf [255]float32
|
||||
var gs *gaussianShader
|
||||
if cv.state.shadowBlur < 3 {
|
||||
gs = gauss15r
|
||||
kernel = kernelBuf[:15]
|
||||
} else if cv.state.shadowBlur < 12 {
|
||||
gs = gauss63r
|
||||
kernel = kernelBuf[:63]
|
||||
} else {
|
||||
gs = gauss255r
|
||||
kernel = kernelBuf[:255]
|
||||
}
|
||||
|
||||
gaussianKernel(cv.state.shadowBlur, kernel)
|
||||
|
||||
cv.enableTextureRenderTarget(&offscr2)
|
||||
gli.ClearColor(0, 0, 0, 0)
|
||||
|
@ -134,18 +147,18 @@ func (cv *Canvas) drawBlurredShadow() {
|
|||
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.UseProgram(gs.id)
|
||||
gli.Uniform1i(gs.image, 0)
|
||||
gli.Uniform2f(gs.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
gli.Uniform2f(gs.kernelScale, 1.0/float32(cv.fw), 0.0)
|
||||
gli.Uniform1fv(gs.kernel, int32(len(kernel)), &kernel[0])
|
||||
gli.VertexAttribPointer(gs.vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
gli.VertexAttribPointer(gs.texCoord, 2, gl_FLOAT, false, 0, 8*4)
|
||||
gli.EnableVertexAttribArray(gs.vertex)
|
||||
gli.EnableVertexAttribArray(gs.texCoord)
|
||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||
gli.DisableVertexAttribArray(gauss255r.vertex)
|
||||
gli.DisableVertexAttribArray(gauss255r.texCoord)
|
||||
gli.DisableVertexAttribArray(gs.vertex)
|
||||
gli.DisableVertexAttribArray(gs.texCoord)
|
||||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
|
||||
|
@ -160,18 +173,18 @@ func (cv *Canvas) drawBlurredShadow() {
|
|||
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.UseProgram(gs.id)
|
||||
gli.Uniform1i(gs.image, 0)
|
||||
gli.Uniform2f(gs.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
gli.Uniform2f(gs.kernelScale, 0.0, 1.0/float32(cv.fh))
|
||||
gli.Uniform1fv(gs.kernel, int32(len(kernel)), &kernel[0])
|
||||
gli.VertexAttribPointer(gs.vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
gli.VertexAttribPointer(gs.texCoord, 2, gl_FLOAT, false, 0, 8*4)
|
||||
gli.EnableVertexAttribArray(gs.vertex)
|
||||
gli.EnableVertexAttribArray(gs.texCoord)
|
||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||
gli.DisableVertexAttribArray(gauss255r.vertex)
|
||||
gli.DisableVertexAttribArray(gauss255r.texCoord)
|
||||
gli.DisableVertexAttribArray(gs.vertex)
|
||||
gli.DisableVertexAttribArray(gs.texCoord)
|
||||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
|
||||
|
@ -186,7 +199,7 @@ func gaussianKernel(stddev float64, target []float32) {
|
|||
x := float64(i) - center
|
||||
target[i] = float32(factor * math.Pow(math.E, -x*x/(2*stddevSqr)))
|
||||
}
|
||||
normalizeKernel(target)
|
||||
// normalizeKernel(target)
|
||||
}
|
||||
|
||||
func normalizeKernel(kernel []float32) {
|
||||
|
|
Loading…
Reference in a new issue