diff --git a/examples/lights/main.go b/examples/lights/main.go index c1a6d3f..dd41386 100644 --- a/examples/lights/main.go +++ b/examples/lights/main.go @@ -27,10 +27,6 @@ func loadPicture(path string) (pixel.Picture, error) { return pixel.PictureDataFromImage(img), nil } -type drawer interface { - Draw(pixel.Target) -} - type colorlight struct { color pixel.RGBA point pixel.Vec @@ -43,7 +39,7 @@ type colorlight struct { imd *imdraw.IMDraw } -func (cl *colorlight) apply(src, noise drawer, dst pixel.ComposeTarget) { +func (cl *colorlight) apply(dst pixel.ComposeTarget, center pixel.Vec, src, noise *pixel.Sprite) { // create the light arc if not created already if cl.imd == nil { imd := imdraw.New(nil) @@ -66,12 +62,12 @@ func (cl *colorlight) apply(src, noise drawer, dst pixel.ComposeTarget) { // draw the noise inside the light dst.SetMatrix(pixel.IM) dst.SetComposeMethod(pixel.ComposeIn) - noise.Draw(dst) + noise.Draw(dst, pixel.IM.Moved(center)) // draw an image inside the noisy light dst.SetColorMask(cl.color) dst.SetComposeMethod(pixel.ComposeIn) - src.Draw(dst) + src.Draw(dst, pixel.IM.Moved(center)) // draw the light reflected from the dust dst.SetMatrix(pixel.IM.Scaled(0, cl.radius).Rotated(0, cl.angle).Moved(cl.point)) @@ -101,9 +97,7 @@ func run() { } panda := pixel.NewSprite(pandaPic, pandaPic.Bounds()) - panda.SetMatrix(pixel.IM.Moved(win.Bounds().Center())) noise := pixel.NewSprite(noisePic, noisePic.Bounds()) - noise.SetMatrix(pixel.IM.Moved(win.Bounds().Center())) colors := []pixel.RGBA{ pixel.RGB(1, 0, 0), @@ -174,7 +168,7 @@ func run() { // draw the panda visible outside the light win.SetColorMask(pixel.Alpha(0.4)) win.SetComposeMethod(pixel.ComposePlus) - panda.Draw(win) + panda.Draw(win, pixel.IM.Moved(win.Bounds().Center())) allLight.Clear(pixel.Alpha(0)) allLight.SetComposeMethod(pixel.ComposePlus) @@ -182,13 +176,13 @@ func run() { // accumulate all the lights for i := range lights { oneLight.Clear(pixel.Alpha(0)) - lights[i].apply(panda, noise, oneLight) - oneLight.Draw(allLight) + lights[i].apply(oneLight, oneLight.Bounds().Center(), panda, noise) + oneLight.Draw(allLight, pixel.IM.Moved(allLight.Bounds().Center())) } // compose the final result win.SetColorMask(pixel.Alpha(1)) - allLight.Draw(win) + allLight.Draw(win, pixel.IM.Moved(win.Bounds().Center())) win.Update() diff --git a/examples/platformer/main.go b/examples/platformer/main.go index ee2971e..dab3628 100644 --- a/examples/platformer/main.go +++ b/examples/platformer/main.go @@ -215,7 +215,7 @@ func (ga *gopherAnim) draw(t pixel.Target, phys *gopherPhys) { } // draw the correct frame with the correct position and direction ga.sprite.Set(ga.sheet, ga.frame) - ga.sprite.SetMatrix(pixel.IM. + ga.sprite.Draw(t, pixel.IM. ScaledXY(0, pixel.V( phys.rect.W()/ga.sprite.Frame().W(), phys.rect.H()/ga.sprite.Frame().H(), @@ -223,7 +223,6 @@ func (ga *gopherAnim) draw(t pixel.Target, phys *gopherPhys) { ScaledXY(0, pixel.V(-ga.dir, 1)). Moved(phys.rect.Center()), ) - ga.sprite.Draw(t) } type goal struct { @@ -385,7 +384,7 @@ func run() { win.Bounds().H()/canvas.Bounds().H(), ), ).Moved(win.Bounds().Center())) - canvas.Draw(win) + canvas.Draw(win, pixel.IM.Moved(canvas.Bounds().Center())) win.Update() } } diff --git a/examples/smoke/main.go b/examples/smoke/main.go index 40007a2..4b366c2 100644 --- a/examples/smoke/main.go +++ b/examples/smoke/main.go @@ -54,13 +54,14 @@ func (p *particles) DrawAll(t pixel.Target) { for e := p.parts.Front(); e != nil; e = e.Next() { part := e.Value.(*particle) - part.Sprite.SetMatrix(pixel.IM. - Scaled(0, part.Scale). - Rotated(0, part.Rot). - Moved(part.Pos), + part.Sprite.DrawColorMask( + t, + pixel.IM. + Scaled(0, part.Scale). + Rotated(0, part.Rot). + Moved(part.Pos), + part.Mask, ) - part.Sprite.SetColorMask(part.Mask) - part.Sprite.Draw(t) } } diff --git a/examples/xor/main.go b/examples/xor/main.go index 9b4c5c3..a062de4 100644 --- a/examples/xor/main.go +++ b/examples/xor/main.go @@ -66,7 +66,7 @@ func run() { imd.Draw(canvas) win.Clear(colornames.Green) - canvas.Draw(win) + canvas.Draw(win, pixel.IM.Moved(win.Bounds().Center())) win.Update() } } diff --git a/pixelgl/canvas.go b/pixelgl/canvas.go index 723b544..038bcc0 100644 --- a/pixelgl/canvas.go +++ b/pixelgl/canvas.go @@ -123,7 +123,7 @@ func (c *Canvas) SetBounds(bounds pixel.Rect) { c.sprite = pixel.NewSprite(nil, pixel.Rect{}) } c.sprite.Set(c, c.Bounds()) - c.sprite.SetMatrix(pixel.IM.Moved(c.Bounds().Center())) + //c.sprite.SetMatrix(pixel.IM.Moved(c.Bounds().Center())) } // Bounds returns the rectangular bounds of the Canvas. @@ -245,12 +245,18 @@ func (c *Canvas) Pixels() []uint8 { return pixels } -// Draw draws a rectangle equal to Canvas's Bounds containing the Canvas's content to another -// Target. +// Draw draws the content of the Canvas onto another Target, transformed by the given Matrix, just +// like if it was a Sprite containing the whole Canvas. +func (c *Canvas) Draw(t pixel.Target, matrix pixel.Matrix) { + c.sprite.Draw(t, matrix) +} + +// DrawColorMask draws the content of the Canvas onto another Target, transformed by the given +// Matrix and multiplied by the given mask, just like if it was a Sprite containing the whole Canvas. // -// Note, that the matrix and the color mask of this Canvas have no effect here. -func (c *Canvas) Draw(t pixel.Target) { - c.sprite.Draw(t) +// If the color mask is nil, a fully opaque white mask will be used causing no effect. +func (c *Canvas) DrawColorMask(t pixel.Target, matrix pixel.Matrix, mask color.Color) { + c.sprite.DrawColorMask(t, matrix, mask) } type canvasTriangles struct { diff --git a/sprite.go b/sprite.go index 6ac9aeb..45989d6 100644 --- a/sprite.go +++ b/sprite.go @@ -57,43 +57,35 @@ func (s *Sprite) Frame() Rect { return s.frame } -// SetMatrix sets a Matrix that this Sprite will be transformed by. This overrides any previously -// set Matrix. +// Draw draws the Sprite onto the provided Target. The Sprite will be transformed by the given Matrix. // -// Note, that this has nothing to do with BasicTarget's SetMatrix method. This only affects this -// Sprite and is usable with any Target. -func (s *Sprite) SetMatrix(matrix Matrix) { - if s.matrix != matrix { +// This method is equivalent to calling DrawColorMask with nil color mask. +func (s *Sprite) Draw(t Target, matrix Matrix) { + s.DrawColorMask(t, matrix, nil) +} + +// DrawColorMask draw the Sprite onto the provided Target. The Sprite will be transformed by the +// given Matrix and all of it's color will be multiplied by the given mask. +// +// If the mask is nil, a fully opaque white mask will be used, which causes no effect. +func (s *Sprite) DrawColorMask(t Target, matrix Matrix, mask color.Color) { + dirty := false + if matrix != s.matrix { s.matrix = matrix - s.calcData() + dirty = true } -} - -// Matrix returns the currently set Matrix. -func (s *Sprite) Matrix() Matrix { - return s.matrix -} - -// SetColorMask sets a color that this Sprite will be multiplied by. This overrides any previously -// set color mask. -// -// Note, that this has nothing to do with BasicTarget's SetColorMask method. This only affects this -// Sprite and is usable with any Target. -func (s *Sprite) SetColorMask(mask color.Color) { - rgba := ToRGBA(mask) - if s.mask != rgba { + if mask == nil { + mask = Alpha(1) + } + if mask != s.mask { s.mask = ToRGBA(mask) + dirty = true + } + + if dirty { s.calcData() } -} -// ColorMask returns the currently set color mask. -func (s *Sprite) ColorMask() RGBA { - return s.mask -} - -// Draw draws the Sprite onto the provided Target. -func (s *Sprite) Draw(t Target) { s.d.Draw(t) }