some shadow drawing now works using the backend
This commit is contained in:
parent
38eddd2837
commit
c5c8ac500f
7 changed files with 109 additions and 155 deletions
|
@ -6,4 +6,5 @@ type Backend interface {
|
|||
ClearRect(x, y, w, h int)
|
||||
Clear(pts [4][2]float64)
|
||||
Fill(style *backendbase.Style, pts [][2]float64)
|
||||
// BlurredShadow(shadow *backendbase.Shadow, pts [][2]float64)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import "image/color"
|
|||
type Style struct {
|
||||
Color color.RGBA
|
||||
GlobalAlpha float64
|
||||
Shadow Shadow
|
||||
// radialGradient *RadialGradient
|
||||
// linearGradient *LinearGradient
|
||||
// image *Image
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
package goglbackend
|
||||
|
||||
/*
|
||||
import (
|
||||
"image"
|
||||
"math"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-gl/gl/v3.2-core/gl"
|
||||
"github.com/tfriedel6/canvas/backend/backendbase"
|
||||
)
|
||||
|
||||
func (b *GoGLBackend) drawShadow(sh *backendbase.Shadow, tris []float32) {
|
||||
if len(tris) == 0 || sh.Color.A == 0 {
|
||||
func (b *GoGLBackend) FillShadow(shadow *backendbase.Shadow, pts [][2]float64) {
|
||||
if len(pts) == 0 || shadow.Color.A == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if sh.Blur > 0 {
|
||||
b.offscr1.alpha = true
|
||||
cv.enableTextureRenderTarget(&b.offscr1)
|
||||
gl.ClearColor(0, 0, 0, 0)
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
|
||||
ox, oy := float32(shadow.OffsetX), float32(shadow.OffsetY)
|
||||
|
||||
b.ptsBuf = b.ptsBuf[:0]
|
||||
b.ptsBuf = append(b.ptsBuf,
|
||||
0, 0,
|
||||
0, float32(b.fh),
|
||||
float32(b.fw), float32(b.fh),
|
||||
float32(b.fw), 0)
|
||||
for _, pt := range pts {
|
||||
b.ptsBuf = append(b.ptsBuf, float32(pt[0])+ox, float32(pt[1])+oy)
|
||||
}
|
||||
|
||||
ox, oy := float32(sh.OffsetX), float32(sh.OffsetY)
|
||||
// if sh.Blur > 0 {
|
||||
// b.offscr1.alpha = true
|
||||
// cv.enableTextureRenderTarget(&b.offscr1)
|
||||
// gl.ClearColor(0, 0, 0, 0)
|
||||
// gl.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
|
||||
// }
|
||||
|
||||
count := len(tris)
|
||||
for i := 12; i < count; i += 2 {
|
||||
tris[i] += ox
|
||||
tris[i+1] += oy
|
||||
mode := uint32(gl.TRIANGLES)
|
||||
if len(pts) == 4 {
|
||||
mode = gl.TRIANGLE_FAN
|
||||
}
|
||||
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, b.shadowBuf)
|
||||
gl.BufferData(gl.ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl.STREAM_DRAW)
|
||||
gl.BufferData(gl.ARRAY_BUFFER, len(b.ptsBuf)*4, unsafe.Pointer(&b.ptsBuf[0]), gl.STREAM_DRAW)
|
||||
|
||||
gl.ColorMask(false, false, false, false)
|
||||
gl.StencilFunc(gl.ALWAYS, 1, 0xFF)
|
||||
|
@ -44,20 +44,20 @@ func (b *GoGLBackend) drawShadow(sh *backendbase.Shadow, tris []float32) {
|
|||
|
||||
gl.EnableVertexAttribArray(b.sr.Vertex)
|
||||
gl.VertexAttribPointer(b.sr.Vertex, 2, gl.FLOAT, false, 0, nil)
|
||||
gl.DrawArrays(gl.TRIANGLES, 6, int32(len(tris)/2-6))
|
||||
gl.DrawArrays(gl.TRIANGLES, 4, int32(len(pts)))
|
||||
gl.DisableVertexAttribArray(b.sr.Vertex)
|
||||
|
||||
gl.ColorMask(true, true, true, true)
|
||||
|
||||
gl.StencilFunc(gl.EQUAL, 1, 0xFF)
|
||||
|
||||
var style drawStyle
|
||||
style.color = colorGLToGo(sh.Color)
|
||||
var style backendbase.Style
|
||||
style.Color = shadow.Color
|
||||
|
||||
vertex := b.useShader(&style)
|
||||
gl.EnableVertexAttribArray(vertex)
|
||||
gl.VertexAttribPointer(vertex, 2, gl.FLOAT, false, 0, nil)
|
||||
gl.DrawArrays(gl.TRIANGLES, 0, 6)
|
||||
gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
|
||||
gl.DisableVertexAttribArray(vertex)
|
||||
|
||||
gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
|
||||
|
@ -66,11 +66,35 @@ func (b *GoGLBackend) drawShadow(sh *backendbase.Shadow, tris []float32) {
|
|||
gl.Clear(gl.STENCIL_BUFFER_BIT)
|
||||
gl.StencilMask(0xFF)
|
||||
|
||||
if sh.Blur > 0 {
|
||||
b.drawBlurredShadow()
|
||||
}
|
||||
}
|
||||
{
|
||||
gl.DrawArrays(mode, 4, int32(len(pts)))
|
||||
gl.DisableVertexAttribArray(b.sr.Vertex)
|
||||
|
||||
gl.ColorMask(true, true, true, true)
|
||||
|
||||
gl.StencilFunc(gl.EQUAL, 1, 0xFF)
|
||||
|
||||
vertex := b.useShader(style)
|
||||
gl.EnableVertexAttribArray(vertex)
|
||||
gl.VertexAttribPointer(vertex, 2, gl.FLOAT, false, 0, nil)
|
||||
|
||||
b.ptsBuf = append(b.ptsBuf[:0], 0, 0, float32(b.fw), 0, float32(b.fw), float32(b.fh), 0, float32(b.fh))
|
||||
gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
|
||||
gl.DisableVertexAttribArray(vertex)
|
||||
|
||||
gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
|
||||
gl.StencilFunc(gl.ALWAYS, 0, 0xFF)
|
||||
|
||||
gl.Clear(gl.STENCIL_BUFFER_BIT)
|
||||
gl.StencilMask(0xFF)
|
||||
}
|
||||
|
||||
// if sh.Blur > 0 {
|
||||
// b.drawBlurredShadow()
|
||||
// }
|
||||
}
|
||||
*/
|
||||
/*
|
||||
func (b *GoGLBackend) drawTextShadow(sh *backendbase.Shadow, offset image.Point, strWidth, strHeight int, x, y float64) {
|
||||
x += sh.OffsetX
|
||||
y += sh.OffsetY
|
||||
|
|
15
canvas.go
15
canvas.go
|
@ -33,6 +33,8 @@ type Canvas struct {
|
|||
offscreen bool
|
||||
offscrBuf offscreenBuffer
|
||||
offscrImg Image
|
||||
|
||||
shadowBuf [][2]float64
|
||||
}
|
||||
|
||||
type drawState struct {
|
||||
|
@ -58,7 +60,7 @@ type drawState struct {
|
|||
scissor scissor
|
||||
clip Path2D
|
||||
|
||||
shadowColor glColor
|
||||
shadowColor color.RGBA
|
||||
shadowOffsetX float64
|
||||
shadowOffsetY float64
|
||||
shadowBlur float64
|
||||
|
@ -500,6 +502,15 @@ func (cv *Canvas) backendStyle(s *drawStyle, alpha float64) backendbase.Style {
|
|||
}
|
||||
}
|
||||
|
||||
func (cv *Canvas) backendShadow() backendbase.Shadow {
|
||||
return backendbase.Shadow{
|
||||
Color: cv.state.shadowColor,
|
||||
OffsetX: cv.state.shadowOffsetX,
|
||||
OffsetY: cv.state.shadowOffsetY,
|
||||
Blur: cv.state.shadowBlur,
|
||||
}
|
||||
}
|
||||
|
||||
func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
|
||||
if lg := style.linearGradient; lg != nil {
|
||||
lg.load()
|
||||
|
@ -843,7 +854,7 @@ func (cv *Canvas) SetTransform(a, b, c, d, e, f float64) {
|
|||
// then no shadow is drawn
|
||||
func (cv *Canvas) SetShadowColor(color ...interface{}) {
|
||||
if c, ok := parseColor(color...); ok {
|
||||
cv.state.shadowColor = colorGoToGL(c)
|
||||
cv.state.shadowColor = c
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -324,7 +324,7 @@ func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
|
|||
p2 := cv.tf(vec{dx + dw, dy + dh})
|
||||
p3 := cv.tf(vec{dx + dw, dy})
|
||||
|
||||
if cv.state.shadowColor.a != 0 {
|
||||
if cv.state.shadowColor.A != 0 {
|
||||
tris := [24]float32{
|
||||
0, 0,
|
||||
float32(cv.fw), 0,
|
||||
|
|
122
paths.go
122
paths.go
|
@ -156,62 +156,10 @@ func (cv *Canvas) strokePath(path *Path2D) {
|
|||
start = false
|
||||
}
|
||||
|
||||
// todo draw shadow
|
||||
cv.drawShadow2(tris)
|
||||
|
||||
stl := cv.backendStyle(&cv.state.stroke, 1)
|
||||
cv.b.Fill(&stl, tris)
|
||||
|
||||
// gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
// gli.BufferData(gl_ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl_STREAM_DRAW)
|
||||
|
||||
// cv.drawShadow(tris)
|
||||
|
||||
// gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
|
||||
// if cv.state.globalAlpha >= 1 && cv.state.lineAlpha >= 1 && cv.state.stroke.isOpaque() {
|
||||
// vertex := cv.useShader(&cv.state.stroke)
|
||||
|
||||
// gli.EnableVertexAttribArray(vertex)
|
||||
// gli.VertexAttribPointer(vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
// gli.DrawArrays(gl_TRIANGLES, 6, int32(len(tris)/2-6))
|
||||
// gli.DisableVertexAttribArray(vertex)
|
||||
// } else {
|
||||
// gli.ColorMask(false, false, false, false)
|
||||
// gli.StencilFunc(gl_ALWAYS, 1, 0xFF)
|
||||
// gli.StencilOp(gl_REPLACE, gl_REPLACE, gl_REPLACE)
|
||||
// gli.StencilMask(0x01)
|
||||
|
||||
// gli.UseProgram(sr.id)
|
||||
// gli.Uniform4f(sr.color, 0, 0, 0, 0)
|
||||
// gli.Uniform2f(sr.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
|
||||
// gli.EnableVertexAttribArray(sr.vertex)
|
||||
// gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
// gli.DrawArrays(gl_TRIANGLES, 6, int32(len(tris)/2-6))
|
||||
// gli.DisableVertexAttribArray(sr.vertex)
|
||||
|
||||
// gli.ColorMask(true, true, true, true)
|
||||
|
||||
// gli.StencilFunc(gl_EQUAL, 1, 0xFF)
|
||||
|
||||
// origAlpha := cv.state.globalAlpha
|
||||
// if cv.state.lineAlpha < 1 {
|
||||
// cv.state.globalAlpha *= cv.state.lineAlpha
|
||||
// }
|
||||
// vertex := cv.useShader(&cv.state.stroke)
|
||||
// cv.state.globalAlpha = origAlpha
|
||||
|
||||
// gli.EnableVertexAttribArray(vertex)
|
||||
// gli.VertexAttribPointer(vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
// gli.DrawArrays(gl_TRIANGLES, 0, 6)
|
||||
// gli.DisableVertexAttribArray(vertex)
|
||||
|
||||
// gli.StencilOp(gl_KEEP, gl_KEEP, gl_KEEP)
|
||||
// gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
|
||||
// gli.Clear(gl_STENCIL_BUFFER_BIT)
|
||||
// gli.StencilMask(0xFF)
|
||||
// }
|
||||
}
|
||||
|
||||
func (cv *Canvas) applyLineDash(path []pathPoint) []pathPoint {
|
||||
|
@ -402,56 +350,10 @@ func (cv *Canvas) FillPath(path *Path2D) {
|
|||
return
|
||||
}
|
||||
|
||||
// todo draw shadow
|
||||
cv.drawShadow2(tris)
|
||||
|
||||
stl := cv.backendStyle(&cv.state.fill, 1)
|
||||
cv.b.Fill(&stl, tris)
|
||||
|
||||
// gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
// gli.BufferData(gl_ARRAY_BUFFER, len(tris)*4, unsafe.Pointer(&tris[0]), gl_STREAM_DRAW)
|
||||
|
||||
// cv.drawShadow(tris)
|
||||
|
||||
// gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
|
||||
// if cv.state.globalAlpha >= 1 && cv.state.lineAlpha >= 1 && cv.state.fill.isOpaque() {
|
||||
// vertex := cv.useShader(&cv.state.fill)
|
||||
|
||||
// gli.EnableVertexAttribArray(vertex)
|
||||
// gli.VertexAttribPointer(vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
// gli.DrawArrays(gl_TRIANGLES, 6, int32(len(tris)/2-6))
|
||||
// gli.DisableVertexAttribArray(vertex)
|
||||
// } else {
|
||||
// gli.ColorMask(false, false, false, false)
|
||||
// gli.StencilFunc(gl_ALWAYS, 1, 0xFF)
|
||||
// gli.StencilOp(gl_REPLACE, gl_REPLACE, gl_REPLACE)
|
||||
// gli.StencilMask(0x01)
|
||||
|
||||
// gli.UseProgram(sr.id)
|
||||
// gli.Uniform4f(sr.color, 0, 0, 0, 0)
|
||||
// gli.Uniform2f(sr.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
|
||||
// gli.EnableVertexAttribArray(sr.vertex)
|
||||
// gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
// gli.DrawArrays(gl_TRIANGLES, 6, int32(len(tris)/2-6))
|
||||
// gli.DisableVertexAttribArray(sr.vertex)
|
||||
|
||||
// gli.ColorMask(true, true, true, true)
|
||||
|
||||
// gli.StencilFunc(gl_EQUAL, 1, 0xFF)
|
||||
|
||||
// vertex := cv.useShader(&cv.state.fill)
|
||||
// gli.EnableVertexAttribArray(vertex)
|
||||
// gli.VertexAttribPointer(vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
// gli.DrawArrays(gl_TRIANGLES, 0, 6)
|
||||
// gli.DisableVertexAttribArray(vertex)
|
||||
|
||||
// gli.StencilOp(gl_KEEP, gl_KEEP, gl_KEEP)
|
||||
// gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
|
||||
// gli.Clear(gl_STENCIL_BUFFER_BIT)
|
||||
// gli.StencilMask(0xFF)
|
||||
// }
|
||||
}
|
||||
|
||||
func (cv *Canvas) appendSubPathTriangles(tris [][2]float64, path []pathPoint) [][2]float64 {
|
||||
|
@ -622,26 +524,10 @@ func (cv *Canvas) FillRect(x, y, w, h float64) {
|
|||
p2 := cv.tf(vec{x + w, y + h})
|
||||
p3 := cv.tf(vec{x + w, y})
|
||||
|
||||
if cv.state.shadowColor.a != 0 {
|
||||
tris := [24]float32{
|
||||
0, 0,
|
||||
float32(cv.fw), 0,
|
||||
float32(cv.fw), float32(cv.fh),
|
||||
0, 0,
|
||||
float32(cv.fw), float32(cv.fh),
|
||||
0, float32(cv.fh),
|
||||
float32(p0[0]), float32(p0[1]),
|
||||
float32(p3[0]), float32(p3[1]),
|
||||
float32(p2[0]), float32(p2[1]),
|
||||
float32(p0[0]), float32(p0[1]),
|
||||
float32(p2[0]), float32(p2[1]),
|
||||
float32(p1[0]), float32(p1[1]),
|
||||
}
|
||||
cv.drawShadow(tris[:])
|
||||
}
|
||||
|
||||
data := [4][2]float64{{p0[0], p0[1]}, {p1[0], p1[1]}, {p2[0], p2[1]}, {p3[0], p3[1]}}
|
||||
|
||||
cv.drawShadow2(data[:])
|
||||
|
||||
stl := cv.backendStyle(&cv.state.fill, 1)
|
||||
cv.b.Fill(&stl, data[:])
|
||||
}
|
||||
|
|
39
shadows.go
39
shadows.go
|
@ -4,10 +4,39 @@ import (
|
|||
"image"
|
||||
"math"
|
||||
"unsafe"
|
||||
|
||||
"github.com/tfriedel6/canvas/backend/backendbase"
|
||||
)
|
||||
|
||||
func (cv *Canvas) drawShadow2(pts [][2]float64) {
|
||||
if cv.state.shadowColor.A == 0 {
|
||||
return
|
||||
}
|
||||
if cv.state.shadowOffsetX == 0 && cv.state.shadowOffsetY == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if cv.shadowBuf == nil || cap(cv.shadowBuf) < len(pts) {
|
||||
cv.shadowBuf = make([][2]float64, 0, len(pts)+1000)
|
||||
}
|
||||
cv.shadowBuf = cv.shadowBuf[:0]
|
||||
|
||||
for _, pt := range pts {
|
||||
cv.shadowBuf = append(cv.shadowBuf, [2]float64{
|
||||
pt[0] + cv.state.shadowOffsetX,
|
||||
pt[1] + cv.state.shadowOffsetY,
|
||||
})
|
||||
}
|
||||
|
||||
shadow := cv.backendShadow()
|
||||
if cv.state.shadowBlur == 0 {
|
||||
style := backendbase.Style{Color: shadow.Color, GlobalAlpha: 1}
|
||||
cv.b.Fill(&style, cv.shadowBuf)
|
||||
}
|
||||
}
|
||||
|
||||
func (cv *Canvas) drawShadow(tris []float32) {
|
||||
if len(tris) == 0 || cv.state.shadowColor.a == 0 {
|
||||
if len(tris) == 0 || cv.state.shadowColor.A == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -48,7 +77,7 @@ func (cv *Canvas) drawShadow(tris []float32) {
|
|||
gli.StencilFunc(gl_EQUAL, 1, 0xFF)
|
||||
|
||||
var style drawStyle
|
||||
style.color = colorGLToGo(cv.state.shadowColor)
|
||||
style.color = cv.state.shadowColor
|
||||
|
||||
vertex := cv.useShader(&style)
|
||||
gli.EnableVertexAttribArray(vertex)
|
||||
|
@ -68,6 +97,10 @@ func (cv *Canvas) drawShadow(tris []float32) {
|
|||
}
|
||||
|
||||
func (cv *Canvas) drawTextShadow(offset image.Point, strWidth, strHeight int, x, y float64) {
|
||||
if cv.state.shadowColor.A == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
x += cv.state.shadowOffsetX
|
||||
y += cv.state.shadowOffsetY
|
||||
|
||||
|
@ -83,7 +116,7 @@ func (cv *Canvas) drawTextShadow(offset image.Point, strWidth, strHeight int, x,
|
|||
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
|
||||
|
||||
var style drawStyle
|
||||
style.color = colorGLToGo(cv.state.shadowColor)
|
||||
style.color = cv.state.shadowColor
|
||||
|
||||
vertex, alphaTexCoord := cv.useAlphaShader(&style, 1)
|
||||
|
||||
|
|
Loading…
Reference in a new issue