From 3d3f1c6e1148e430131e7f2679c50a3f4cb6884d Mon Sep 17 00:00:00 2001 From: faiface Date: Mon, 10 Apr 2017 00:30:50 +0200 Subject: [PATCH] add Canvas.SetComposeMethod --- pixelgl/canvas.go | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/pixelgl/canvas.go b/pixelgl/canvas.go index 758a5b5..f2a9bc5 100644 --- a/pixelgl/canvas.go +++ b/pixelgl/canvas.go @@ -19,11 +19,14 @@ type Canvas struct { gf *GLFrame shader *glhf.Shader + cmp pixel.ComposeMethod mat mgl32.Mat3 col mgl32.Vec4 smooth bool } +var _ pixel.ComposeTarget = (*Canvas)(nil) + // NewCanvas creates a new empty, fully transparent Canvas with given bounds. If the smooth flag is // set, then stretched Pictures will be smoothed and will not be drawn pixely onto this Canvas. func NewCanvas(bounds pixel.Rect, smooth bool) *Canvas { @@ -107,6 +110,12 @@ func (c *Canvas) SetColorMask(col color.Color) { } } +// SetComposeMethod sets a Porter-Duff composition method to be used in the following draws onto +// this Canvas. +func (c *Canvas) SetComposeMethod(cmp pixel.ComposeMethod) { + c.cmp = cmp +} + // SetBounds resizes the Canvas to the new bounds. Old content will be preserved. func (c *Canvas) SetBounds(bounds pixel.Rect) { c.gf.SetBounds(bounds) @@ -135,6 +144,32 @@ func (c *Canvas) setGlhfBounds() { glhf.Bounds(bx, by, bw, bh) } +// must be manually called inside mainthread +func (c *Canvas) setBlendFunc() { + switch c.cmp { + case pixel.ComposeOver: + glhf.BlendFunc(glhf.One, glhf.OneMinusSrcAlpha) + case pixel.ComposeIn: + glhf.BlendFunc(glhf.DstAlpha, glhf.Zero) + case pixel.ComposeOut: + glhf.BlendFunc(glhf.OneMinusDstAlpha, glhf.Zero) + case pixel.ComposeAtop: + glhf.BlendFunc(glhf.DstAlpha, glhf.OneMinusSrcAlpha) + case pixel.ComposeDstOver: + glhf.BlendFunc(glhf.OneMinusDstAlpha, glhf.One) + case pixel.ComposeDstIn: + glhf.BlendFunc(glhf.Zero, glhf.SrcAlpha) + case pixel.ComposeDstOut: + glhf.BlendFunc(glhf.Zero, glhf.OneMinusSrcAlpha) + case pixel.ComposeDstAtop: + glhf.BlendFunc(glhf.OneMinusDstAlpha, glhf.SrcAlpha) + case pixel.ComposeXor: + glhf.BlendFunc(glhf.OneMinusDstAlpha, glhf.OneMinusSrcAlpha) + default: + panic(errors.New("Canvas: invalid compose method")) + } +} + // Clear fills the whole Canvas with a single color. func (c *Canvas) Clear(color color.Color) { c.gf.Dirty() @@ -188,7 +223,7 @@ func (ct *canvasTriangles) draw(tex *glhf.Texture, bounds pixel.Rect) { mainthread.CallNonBlock(func() { ct.dst.setGlhfBounds() - glhf.BlendFunc(glhf.One, glhf.OneMinusSrcAlpha) + ct.dst.setBlendFunc() frame := ct.dst.gf.Frame() shader := ct.dst.shader