allow efficiently drawing one Canvas onto another
This commit is contained in:
parent
f65ea40e19
commit
3d13e52add
|
@ -73,12 +73,26 @@ func (c *Canvas) MakeTriangles(t pixel.Triangles) pixel.TargetTriangles {
|
|||
//
|
||||
// PictureColor is supported.
|
||||
func (c *Canvas) MakePicture(p pixel.Picture) pixel.TargetPicture {
|
||||
// short paths
|
||||
if cp, ok := p.(*canvasPicture); ok {
|
||||
tp := new(canvasPicture)
|
||||
*tp = *cp
|
||||
tp.c = c
|
||||
tp.dst = c
|
||||
return tp
|
||||
}
|
||||
if ccp, ok := p.(*canvasCanvasPicture); ok {
|
||||
tp := new(canvasCanvasPicture)
|
||||
*tp = *ccp
|
||||
tp.dst = c
|
||||
return tp
|
||||
}
|
||||
if canvas, ok := p.(*Canvas); ok {
|
||||
return &canvasCanvasPicture{
|
||||
src: canvas,
|
||||
dst: c,
|
||||
bounds: c.bounds,
|
||||
}
|
||||
}
|
||||
|
||||
bounds := p.Bounds()
|
||||
bx, by, bw, bh := intBounds(bounds)
|
||||
|
@ -112,7 +126,7 @@ func (c *Canvas) MakePicture(p pixel.Picture) pixel.TargetPicture {
|
|||
float64(bw), float64(bh),
|
||||
),
|
||||
bounds: bounds,
|
||||
c: c,
|
||||
dst: c,
|
||||
}
|
||||
cp.orig = cp
|
||||
return cp
|
||||
|
@ -239,9 +253,10 @@ func (c *Canvas) Original() pixel.Picture {
|
|||
func (c *Canvas) Color(at pixel.Vec) pixel.NRGBA {
|
||||
if c.orig.dirty {
|
||||
mainthread.Call(func() {
|
||||
c.f.Texture.Begin()
|
||||
c.orig.pixels = c.f.Texture.Pixels(0, 0, c.f.Texture.Width(), c.f.Texture.Height())
|
||||
c.f.Texture.End()
|
||||
tex := c.f.Texture()
|
||||
tex.Begin()
|
||||
c.orig.pixels = tex.Pixels(0, 0, tex.Width(), tex.Height())
|
||||
tex.End()
|
||||
})
|
||||
c.orig.dirty = false
|
||||
}
|
||||
|
@ -265,7 +280,7 @@ type canvasTriangles struct {
|
|||
c *Canvas
|
||||
}
|
||||
|
||||
func (ct *canvasTriangles) draw(cp *canvasPicture) {
|
||||
func (ct *canvasTriangles) draw(tex *glhf.Texture, borders, bounds pixel.Rect) {
|
||||
ct.c.orig.dirty = true
|
||||
|
||||
// save the current state vars to avoid race condition
|
||||
|
@ -286,35 +301,35 @@ func (ct *canvasTriangles) draw(cp *canvasPicture) {
|
|||
ct.c.s.SetUniformAttr(canvasTransform, mat)
|
||||
ct.c.s.SetUniformAttr(canvasColorMask, col)
|
||||
|
||||
if cp == nil {
|
||||
if tex == nil {
|
||||
ct.vs.Begin()
|
||||
ct.vs.Draw()
|
||||
ct.vs.End()
|
||||
} else {
|
||||
cp.tex.Begin()
|
||||
tex.Begin()
|
||||
|
||||
ct.c.s.SetUniformAttr(canvasTexBorders, mgl32.Vec4{
|
||||
float32(cp.borders.X()),
|
||||
float32(cp.borders.Y()),
|
||||
float32(cp.borders.W()),
|
||||
float32(cp.borders.H()),
|
||||
float32(borders.X()),
|
||||
float32(borders.Y()),
|
||||
float32(borders.W()),
|
||||
float32(borders.H()),
|
||||
})
|
||||
ct.c.s.SetUniformAttr(canvasTexBounds, mgl32.Vec4{
|
||||
float32(cp.bounds.X()),
|
||||
float32(cp.bounds.Y()),
|
||||
float32(cp.bounds.W()),
|
||||
float32(cp.bounds.H()),
|
||||
float32(bounds.X()),
|
||||
float32(bounds.Y()),
|
||||
float32(bounds.W()),
|
||||
float32(bounds.H()),
|
||||
})
|
||||
|
||||
if cp.tex.Smooth() != ct.c.smooth {
|
||||
cp.tex.SetSmooth(ct.c.smooth)
|
||||
if tex.Smooth() != ct.c.smooth {
|
||||
tex.SetSmooth(ct.c.smooth)
|
||||
}
|
||||
|
||||
ct.vs.Begin()
|
||||
ct.vs.Draw()
|
||||
ct.vs.End()
|
||||
|
||||
cp.tex.End()
|
||||
tex.End()
|
||||
}
|
||||
|
||||
ct.c.s.End()
|
||||
|
@ -323,7 +338,7 @@ func (ct *canvasTriangles) draw(cp *canvasPicture) {
|
|||
}
|
||||
|
||||
func (ct *canvasTriangles) Draw() {
|
||||
ct.draw(nil)
|
||||
ct.draw(nil, pixel.Rect{}, pixel.Rect{})
|
||||
}
|
||||
|
||||
type canvasPicture struct {
|
||||
|
@ -332,7 +347,7 @@ type canvasPicture struct {
|
|||
bounds pixel.Rect
|
||||
|
||||
orig *canvasPicture
|
||||
c *Canvas
|
||||
dst *Canvas
|
||||
}
|
||||
|
||||
func (cp *canvasPicture) Bounds() pixel.Rect {
|
||||
|
@ -352,10 +367,39 @@ func (cp *canvasPicture) Original() pixel.Picture {
|
|||
|
||||
func (cp *canvasPicture) Draw(t pixel.TargetTriangles) {
|
||||
ct := t.(*canvasTriangles)
|
||||
if cp.c != ct.c {
|
||||
if cp.dst != ct.c {
|
||||
panic(fmt.Errorf("%T.Draw: TargetTriangles generated by different Canvas", cp))
|
||||
}
|
||||
ct.draw(cp)
|
||||
ct.draw(cp.tex, cp.borders, cp.bounds)
|
||||
}
|
||||
|
||||
type canvasCanvasPicture struct {
|
||||
src, dst *Canvas
|
||||
bounds pixel.Rect
|
||||
orig *canvasCanvasPicture
|
||||
}
|
||||
|
||||
func (ccp *canvasCanvasPicture) Bounds() pixel.Rect {
|
||||
return ccp.bounds
|
||||
}
|
||||
|
||||
func (ccp *canvasCanvasPicture) Slice(r pixel.Rect) pixel.Picture {
|
||||
sp := new(canvasCanvasPicture)
|
||||
*sp = *ccp
|
||||
sp.bounds = r
|
||||
return sp
|
||||
}
|
||||
|
||||
func (ccp *canvasCanvasPicture) Original() pixel.Picture {
|
||||
return ccp.orig
|
||||
}
|
||||
|
||||
func (ccp *canvasCanvasPicture) Draw(t pixel.TargetTriangles) {
|
||||
ct := t.(*canvasTriangles)
|
||||
if ccp.dst != ct.c {
|
||||
panic(fmt.Errorf("%T.Draw: TargetTriangles generated by different Canvas", ccp))
|
||||
}
|
||||
ct.draw(ccp.src.f.Texture(), ccp.src.orig.bounds, ccp.bounds)
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
|
@ -166,14 +166,14 @@ func (w *Window) Update() {
|
|||
mainthread.Call(func() {
|
||||
w.begin()
|
||||
|
||||
glhf.Bounds(0, 0, w.canvas.f.Texture.Width(), w.canvas.f.Texture.Height())
|
||||
glhf.Bounds(0, 0, w.canvas.f.Texture().Width(), w.canvas.f.Texture().Height())
|
||||
|
||||
glhf.Clear(0, 0, 0, 0)
|
||||
w.canvas.f.Begin()
|
||||
w.canvas.f.Blit(
|
||||
nil,
|
||||
0, 0, w.canvas.f.Texture.Width(), w.canvas.f.Texture.Height(),
|
||||
0, 0, w.canvas.f.Texture.Width(), w.canvas.f.Texture.Height(),
|
||||
0, 0, w.canvas.f.Texture().Width(), w.canvas.f.Texture().Height(),
|
||||
0, 0, w.canvas.f.Texture().Width(), w.canvas.f.Texture().Height(),
|
||||
)
|
||||
w.canvas.f.End()
|
||||
|
||||
|
|
Loading…
Reference in New Issue