change Sprite.Draw and Canvas.Draw signatures (include Matrix)

This commit is contained in:
faiface 2017-05-17 23:45:22 +02:00
parent 53167788d6
commit b832e83517
6 changed files with 51 additions and 59 deletions

View File

@ -27,10 +27,6 @@ func loadPicture(path string) (pixel.Picture, error) {
return pixel.PictureDataFromImage(img), nil return pixel.PictureDataFromImage(img), nil
} }
type drawer interface {
Draw(pixel.Target)
}
type colorlight struct { type colorlight struct {
color pixel.RGBA color pixel.RGBA
point pixel.Vec point pixel.Vec
@ -43,7 +39,7 @@ type colorlight struct {
imd *imdraw.IMDraw 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 // create the light arc if not created already
if cl.imd == nil { if cl.imd == nil {
imd := imdraw.New(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 // draw the noise inside the light
dst.SetMatrix(pixel.IM) dst.SetMatrix(pixel.IM)
dst.SetComposeMethod(pixel.ComposeIn) dst.SetComposeMethod(pixel.ComposeIn)
noise.Draw(dst) noise.Draw(dst, pixel.IM.Moved(center))
// draw an image inside the noisy light // draw an image inside the noisy light
dst.SetColorMask(cl.color) dst.SetColorMask(cl.color)
dst.SetComposeMethod(pixel.ComposeIn) dst.SetComposeMethod(pixel.ComposeIn)
src.Draw(dst) src.Draw(dst, pixel.IM.Moved(center))
// draw the light reflected from the dust // draw the light reflected from the dust
dst.SetMatrix(pixel.IM.Scaled(0, cl.radius).Rotated(0, cl.angle).Moved(cl.point)) 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 := pixel.NewSprite(pandaPic, pandaPic.Bounds())
panda.SetMatrix(pixel.IM.Moved(win.Bounds().Center()))
noise := pixel.NewSprite(noisePic, noisePic.Bounds()) noise := pixel.NewSprite(noisePic, noisePic.Bounds())
noise.SetMatrix(pixel.IM.Moved(win.Bounds().Center()))
colors := []pixel.RGBA{ colors := []pixel.RGBA{
pixel.RGB(1, 0, 0), pixel.RGB(1, 0, 0),
@ -174,7 +168,7 @@ func run() {
// draw the panda visible outside the light // draw the panda visible outside the light
win.SetColorMask(pixel.Alpha(0.4)) win.SetColorMask(pixel.Alpha(0.4))
win.SetComposeMethod(pixel.ComposePlus) win.SetComposeMethod(pixel.ComposePlus)
panda.Draw(win) panda.Draw(win, pixel.IM.Moved(win.Bounds().Center()))
allLight.Clear(pixel.Alpha(0)) allLight.Clear(pixel.Alpha(0))
allLight.SetComposeMethod(pixel.ComposePlus) allLight.SetComposeMethod(pixel.ComposePlus)
@ -182,13 +176,13 @@ func run() {
// accumulate all the lights // accumulate all the lights
for i := range lights { for i := range lights {
oneLight.Clear(pixel.Alpha(0)) oneLight.Clear(pixel.Alpha(0))
lights[i].apply(panda, noise, oneLight) lights[i].apply(oneLight, oneLight.Bounds().Center(), panda, noise)
oneLight.Draw(allLight) oneLight.Draw(allLight, pixel.IM.Moved(allLight.Bounds().Center()))
} }
// compose the final result // compose the final result
win.SetColorMask(pixel.Alpha(1)) win.SetColorMask(pixel.Alpha(1))
allLight.Draw(win) allLight.Draw(win, pixel.IM.Moved(win.Bounds().Center()))
win.Update() win.Update()

View File

@ -215,7 +215,7 @@ func (ga *gopherAnim) draw(t pixel.Target, phys *gopherPhys) {
} }
// draw the correct frame with the correct position and direction // draw the correct frame with the correct position and direction
ga.sprite.Set(ga.sheet, ga.frame) ga.sprite.Set(ga.sheet, ga.frame)
ga.sprite.SetMatrix(pixel.IM. ga.sprite.Draw(t, pixel.IM.
ScaledXY(0, pixel.V( ScaledXY(0, pixel.V(
phys.rect.W()/ga.sprite.Frame().W(), phys.rect.W()/ga.sprite.Frame().W(),
phys.rect.H()/ga.sprite.Frame().H(), 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)). ScaledXY(0, pixel.V(-ga.dir, 1)).
Moved(phys.rect.Center()), Moved(phys.rect.Center()),
) )
ga.sprite.Draw(t)
} }
type goal struct { type goal struct {
@ -385,7 +384,7 @@ func run() {
win.Bounds().H()/canvas.Bounds().H(), win.Bounds().H()/canvas.Bounds().H(),
), ),
).Moved(win.Bounds().Center())) ).Moved(win.Bounds().Center()))
canvas.Draw(win) canvas.Draw(win, pixel.IM.Moved(canvas.Bounds().Center()))
win.Update() win.Update()
} }
} }

View File

@ -54,13 +54,14 @@ func (p *particles) DrawAll(t pixel.Target) {
for e := p.parts.Front(); e != nil; e = e.Next() { for e := p.parts.Front(); e != nil; e = e.Next() {
part := e.Value.(*particle) part := e.Value.(*particle)
part.Sprite.SetMatrix(pixel.IM. part.Sprite.DrawColorMask(
Scaled(0, part.Scale). t,
Rotated(0, part.Rot). pixel.IM.
Moved(part.Pos), Scaled(0, part.Scale).
Rotated(0, part.Rot).
Moved(part.Pos),
part.Mask,
) )
part.Sprite.SetColorMask(part.Mask)
part.Sprite.Draw(t)
} }
} }

View File

@ -66,7 +66,7 @@ func run() {
imd.Draw(canvas) imd.Draw(canvas)
win.Clear(colornames.Green) win.Clear(colornames.Green)
canvas.Draw(win) canvas.Draw(win, pixel.IM.Moved(win.Bounds().Center()))
win.Update() win.Update()
} }
} }

View File

@ -123,7 +123,7 @@ func (c *Canvas) SetBounds(bounds pixel.Rect) {
c.sprite = pixel.NewSprite(nil, pixel.Rect{}) c.sprite = pixel.NewSprite(nil, pixel.Rect{})
} }
c.sprite.Set(c, c.Bounds()) 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. // Bounds returns the rectangular bounds of the Canvas.
@ -245,12 +245,18 @@ func (c *Canvas) Pixels() []uint8 {
return pixels return pixels
} }
// Draw draws a rectangle equal to Canvas's Bounds containing the Canvas's content to another // Draw draws the content of the Canvas onto another Target, transformed by the given Matrix, just
// Target. // 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. // If the color mask is nil, a fully opaque white mask will be used causing no effect.
func (c *Canvas) Draw(t pixel.Target) { func (c *Canvas) DrawColorMask(t pixel.Target, matrix pixel.Matrix, mask color.Color) {
c.sprite.Draw(t) c.sprite.DrawColorMask(t, matrix, mask)
} }
type canvasTriangles struct { type canvasTriangles struct {

View File

@ -57,43 +57,35 @@ func (s *Sprite) Frame() Rect {
return s.frame return s.frame
} }
// SetMatrix sets a Matrix that this Sprite will be transformed by. This overrides any previously // Draw draws the Sprite onto the provided Target. The Sprite will be transformed by the given Matrix.
// set Matrix.
// //
// Note, that this has nothing to do with BasicTarget's SetMatrix method. This only affects this // This method is equivalent to calling DrawColorMask with nil color mask.
// Sprite and is usable with any Target. func (s *Sprite) Draw(t Target, matrix Matrix) {
func (s *Sprite) SetMatrix(matrix Matrix) { s.DrawColorMask(t, matrix, nil)
if s.matrix != matrix { }
// 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.matrix = matrix
s.calcData() dirty = true
} }
} if mask == nil {
mask = Alpha(1)
// Matrix returns the currently set Matrix. }
func (s *Sprite) Matrix() Matrix { if mask != s.mask {
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 {
s.mask = ToRGBA(mask) s.mask = ToRGBA(mask)
dirty = true
}
if dirty {
s.calcData() 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) s.d.Draw(t)
} }