add Picture.Original

This commit is contained in:
faiface 2017-03-06 19:04:57 +01:00
parent 53066d4759
commit 1083ca720d
4 changed files with 47 additions and 9 deletions

View File

@ -129,6 +129,7 @@ type PictureData struct {
Pix []NRGBA Pix []NRGBA
Stride int Stride int
Rect Rect Rect Rect
Orig *PictureData
} }
// MakePictureData creates a zero-initialized PictureData covering the given rectangle. // MakePictureData creates a zero-initialized PictureData covering the given rectangle.
@ -140,6 +141,7 @@ func MakePictureData(rect Rect) *PictureData {
Rect: rect, Rect: rect,
} }
pd.Pix = make([]NRGBA, w*h) pd.Pix = make([]NRGBA, w*h)
pd.Orig = pd
return pd return pd
} }
@ -265,9 +267,16 @@ func (pd *PictureData) Slice(r Rect) Picture {
Pix: pd.Pix[pd.offset(r.Pos):], Pix: pd.Pix[pd.offset(r.Pos):],
Stride: pd.Stride, Stride: pd.Stride,
Rect: r, Rect: r,
Orig: pd.Orig,
} }
} }
// Original returns the most original PictureData that this PictureData was obtained from using
// Slice-ing.
func (pd *PictureData) Original() Picture {
return pd.Orig
}
// Color returns the color located at the given position. // Color returns the color located at the given position.
func (pd *PictureData) Color(at Vec) NRGBA { func (pd *PictureData) Color(at Vec) NRGBA {
if !pd.Rect.Contains(at) { if !pd.Rect.Contains(at) {

View File

@ -77,11 +77,12 @@ func (d *Drawer) Draw(t Target) {
return return
} }
pic := d.pics[targetPicturePair{t, d.Picture}] pic := d.pics[targetPicturePair{t, d.Picture.Original()}]
if pic == nil { if pic == nil {
pic = t.MakePicture(d.Picture) pic = t.MakePicture(d.Picture.Original())
d.pics[targetPicturePair{t, d.Picture}] = pic d.pics[targetPicturePair{t, d.Picture.Original()}] = pic
} }
pic = pic.Slice(d.Picture.Bounds()).(TargetPicture)
pic.Draw(tri) pic.Draw(tri)
} }

View File

@ -109,6 +109,14 @@ type Picture interface {
// Slice returns a sub-Picture with specified Bounds. // Slice returns a sub-Picture with specified Bounds.
Slice(Rect) Picture Slice(Rect) Picture
// Original returns the most original Picture (may be itself) that this Picture was created
// from using Slice-ing.
//
// Since the Original and this Picture should share the underlying data and this Picture can
// be obtained just by slicing the Original, this method can be used for more efficient
// caching of Pictures.
Original() Picture
} }
// TargetPicture is a Picture generated by a Target using MakePicture method. This Picture can be drawn onto // TargetPicture is a Picture generated by a Target using MakePicture method. This Picture can be drawn onto

View File

@ -69,6 +69,17 @@ func (c *Canvas) MakeTriangles(t pixel.Triangles) pixel.TargetTriangles {
// //
// PictureColor is supported. // PictureColor is supported.
func (c *Canvas) MakePicture(p pixel.Picture) pixel.TargetPicture { func (c *Canvas) MakePicture(p pixel.Picture) pixel.TargetPicture {
if cp, ok := p.(*canvasPicture); ok {
return &canvasPicture{
tex: cp.tex,
orig: cp.orig,
size: cp.size,
bounds: cp.bounds,
original: cp.original,
c: c,
}
}
bounds := p.Bounds() bounds := p.Bounds()
bx, by, bw, bh := discreteBounds(bounds) bx, by, bw, bh := discreteBounds(bounds)
@ -94,13 +105,15 @@ func (c *Canvas) MakePicture(p pixel.Picture) pixel.TargetPicture {
tex = glhf.NewTexture(bw, bh, c.smooth, pixels) tex = glhf.NewTexture(bw, bh, c.smooth, pixels)
}) })
return &canvasPicture{ cp := &canvasPicture{
tex: tex, tex: tex,
orig: pixel.V(float64(bx), float64(by)), orig: pixel.V(float64(bx), float64(by)),
size: pixel.V(float64(bw), float64(bh)), size: pixel.V(float64(bw), float64(bh)),
bounds: bounds, bounds: bounds,
c: c, c: c,
} }
cp.original = cp
return cp
} }
// SetTransform sets a set of Transforms that every position in triangles will be put through. // SetTransform sets a set of Transforms that every position in triangles will be put through.
@ -258,7 +271,8 @@ type canvasPicture struct {
orig, size pixel.Vec orig, size pixel.Vec
bounds pixel.Rect bounds pixel.Rect
c *Canvas original *canvasPicture
c *Canvas
} }
func (cp *canvasPicture) Bounds() pixel.Rect { func (cp *canvasPicture) Bounds() pixel.Rect {
@ -267,13 +281,19 @@ func (cp *canvasPicture) Bounds() pixel.Rect {
func (cp *canvasPicture) Slice(r pixel.Rect) pixel.Picture { func (cp *canvasPicture) Slice(r pixel.Rect) pixel.Picture {
return &canvasPicture{ return &canvasPicture{
orig: cp.orig, tex: cp.tex,
size: cp.size, orig: cp.orig,
bounds: r, size: cp.size,
c: cp.c, bounds: r,
original: cp.original,
c: cp.c,
} }
} }
func (cp *canvasPicture) Original() pixel.Picture {
return cp.original
}
func (cp *canvasPicture) Draw(t pixel.TargetTriangles) { func (cp *canvasPicture) Draw(t pixel.TargetTriangles) {
ct := t.(*canvasTriangles) ct := t.(*canvasTriangles)
if cp.c != ct.c { if cp.c != ct.c {