diff --git a/pixelgl/canvas.go b/pixelgl/canvas.go index 4b94fd2..5a57c96 100644 --- a/pixelgl/canvas.go +++ b/pixelgl/canvas.go @@ -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 ( diff --git a/pixelgl/window.go b/pixelgl/window.go index 3f52a66..a76f8a7 100644 --- a/pixelgl/window.go +++ b/pixelgl/window.go @@ -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()