some shadow drawing now works using the backend

This commit is contained in:
Thomas Friedel 2019-02-20 16:34:56 +01:00
parent 38eddd2837
commit c5c8ac500f
7 changed files with 109 additions and 155 deletions

View file

@ -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)
}

View file

@ -5,7 +5,6 @@ import "image/color"
type Style struct {
Color color.RGBA
GlobalAlpha float64
Shadow Shadow
// radialGradient *RadialGradient
// linearGradient *LinearGradient
// image *Image

View file

@ -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

View file

@ -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
}
}

View file

@ -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
View file

@ -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[:])
}

View file

@ -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)