remove Slice and Original from Picture interface

This commit is contained in:
faiface 2017-03-30 23:34:07 +02:00
parent 5d98f28ca0
commit 0b3cfac547
5 changed files with 27 additions and 134 deletions

View File

@ -81,14 +81,13 @@ func (b *Batch) MakeTriangles(t Triangles) TargetTriangles {
// MakePicture returns a specialized copy of the provided Picture that draws onto this Batch. // MakePicture returns a specialized copy of the provided Picture that draws onto this Batch.
func (b *Batch) MakePicture(p Picture) TargetPicture { func (b *Batch) MakePicture(p Picture) TargetPicture {
if p.Original() != b.cont.Picture.Original() { if p != b.cont.Picture {
panic(fmt.Errorf("(%T).MakePicture: Picture is not a slice of Batch's Picture", b)) panic(fmt.Errorf("(%T).MakePicture: Picture is not the Batch's Picture", b))
} }
bp := &batchPicture{ bp := &batchPicture{
pic: p, pic: p,
dst: b, dst: b,
} }
bp.orig = bp
return bp return bp
} }
@ -149,27 +148,14 @@ func (bt *batchTriangles) Draw() {
} }
type batchPicture struct { type batchPicture struct {
pic Picture pic Picture
orig *batchPicture dst *Batch
dst *Batch
} }
func (bp *batchPicture) Bounds() Rect { func (bp *batchPicture) Bounds() Rect {
return bp.pic.Bounds() return bp.pic.Bounds()
} }
func (bp *batchPicture) Slice(r Rect) Picture {
return &batchPicture{
pic: bp.pic.Slice(r),
orig: bp.orig,
dst: bp.dst,
}
}
func (bp *batchPicture) Original() Picture {
return bp.orig
}
func (bp *batchPicture) Draw(t TargetTriangles) { func (bp *batchPicture) Draw(t TargetTriangles) {
bt := t.(*batchTriangles) bt := t.(*batchTriangles)
if bp.dst != bt.dst { if bp.dst != bt.dst {

18
data.go
View File

@ -132,7 +132,6 @@ type PictureData struct {
Pix []color.NRGBA Pix []color.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.
@ -144,7 +143,6 @@ func MakePictureData(rect Rect) *PictureData {
Rect: rect, Rect: rect,
} }
pd.Pix = make([]color.NRGBA, w*h) pd.Pix = make([]color.NRGBA, w*h)
pd.Orig = pd
return pd return pd
} }
@ -263,22 +261,6 @@ func (pd *PictureData) Bounds() Rect {
return pd.Rect return pd.Rect
} }
// Slice returns a sub-Picture of this PictureData inside the supplied rectangle.
func (pd *PictureData) Slice(r Rect) Picture {
return &PictureData{
Pix: pd.Pix[pd.Index(r.Min):],
Stride: pd.Stride,
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

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

View File

@ -108,19 +108,6 @@ type Picture interface {
// Bounds returns the rectangle of the Picture. All data is located witih this rectangle. // Bounds returns the rectangle of the Picture. All data is located witih this rectangle.
// Querying properties outside the rectangle should return default value of that property. // Querying properties outside the rectangle should return default value of that property.
Bounds() Rect Bounds() Rect
// Slice returns a sub-Picture with specified Bounds.
//
// A result of Slice-ing outside the original Bounds is unspecified.
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

@ -92,9 +92,8 @@ func (c *Canvas) MakePicture(p pixel.Picture) pixel.TargetPicture {
// Canvas special case // Canvas special case
if canvas, ok := p.(*Canvas); ok { if canvas, ok := p.(*Canvas); ok {
return &canvasCanvasPicture{ return &canvasCanvasPicture{
src: canvas, src: canvas,
dst: c, dst: c,
bounds: c.bounds,
} }
} }
@ -140,12 +139,11 @@ func (c *Canvas) MakePicture(p pixel.Picture) pixel.TargetPicture {
cp := &canvasPicture{ cp := &canvasPicture{
tex: tex, tex: tex,
pixels: pixels, pixels: pixels,
borders: pixel.R( bounds: pixel.R(
float64(bx), float64(by), float64(bx), float64(by),
float64(bw), float64(bh), float64(bw), float64(bh),
), ),
bounds: bounds, dst: c,
dst: c,
} }
cp.orig = cp cp.orig = cp
return cp return cp
@ -261,25 +259,6 @@ func (c *Canvas) Clear(color color.Color) {
}) })
} }
// Slice returns a sub-Canvas with the specified Bounds.
//
// The type of the returned value is *Canvas, the type of the return value is a general
// pixel.Picture just so that Canvas implements pixel.Picture interface.
func (c *Canvas) Slice(bounds pixel.Rect) pixel.Picture {
sc := new(Canvas)
*sc = *c
sc.bounds = bounds
return sc
}
// Original returns the most original Canvas that this Canvas was created from using Slice-ing.
//
// The type of the returned value is *Canvas, the type of the return value is a general
// pixel.Picture just so that Canvas implements pixel.Picture interface.
func (c *Canvas) Original() pixel.Picture {
return c.orig
}
// Color returns the color of the pixel over the given position inside the Canvas. // Color returns the color of the pixel over the given position inside the Canvas.
func (c *Canvas) Color(at pixel.Vec) pixel.NRGBA { func (c *Canvas) Color(at pixel.Vec) pixel.NRGBA {
if c.orig.dirty { if c.orig.dirty {
@ -311,7 +290,7 @@ type canvasTriangles struct {
dst *Canvas dst *Canvas
} }
func (ct *canvasTriangles) draw(tex *glhf.Texture, borders, bounds pixel.Rect) { func (ct *canvasTriangles) draw(tex *glhf.Texture, bounds pixel.Rect) {
ct.dst.orig.dirty = true ct.dst.orig.dirty = true
// save the current state vars to avoid race condition // save the current state vars to avoid race condition
@ -339,12 +318,6 @@ func (ct *canvasTriangles) draw(tex *glhf.Texture, borders, bounds pixel.Rect) {
} else { } else {
tex.Begin() tex.Begin()
ct.dst.s.SetUniformAttr(canvasTexBorders, mgl32.Vec4{
float32(borders.Min.X()),
float32(borders.Min.Y()),
float32(borders.W()),
float32(borders.H()),
})
ct.dst.s.SetUniformAttr(canvasTexBounds, mgl32.Vec4{ ct.dst.s.SetUniformAttr(canvasTexBounds, mgl32.Vec4{
float32(bounds.Min.X()), float32(bounds.Min.X()),
float32(bounds.Min.Y()), float32(bounds.Min.Y()),
@ -369,14 +342,13 @@ func (ct *canvasTriangles) draw(tex *glhf.Texture, borders, bounds pixel.Rect) {
} }
func (ct *canvasTriangles) Draw() { func (ct *canvasTriangles) Draw() {
ct.draw(nil, pixel.Rect{}, pixel.Rect{}) ct.draw(nil, pixel.Rect{})
} }
type canvasPicture struct { type canvasPicture struct {
tex *glhf.Texture tex *glhf.Texture
pixels []uint8 pixels []uint8
borders pixel.Rect bounds pixel.Rect
bounds pixel.Rect
orig *canvasPicture orig *canvasPicture
dst *Canvas dst *Canvas
@ -386,22 +358,11 @@ func (cp *canvasPicture) Bounds() pixel.Rect {
return cp.bounds return cp.bounds
} }
func (cp *canvasPicture) Slice(r pixel.Rect) pixel.Picture {
sp := new(canvasPicture)
*sp = *cp
sp.bounds = r
return sp
}
func (cp *canvasPicture) Original() pixel.Picture {
return cp.orig
}
func (cp *canvasPicture) Color(at pixel.Vec) pixel.NRGBA { func (cp *canvasPicture) Color(at pixel.Vec) pixel.NRGBA {
if !cp.bounds.Contains(at) { if !cp.bounds.Contains(at) {
return pixel.NRGBA{} return pixel.NRGBA{}
} }
bx, by, bw, _ := intBounds(cp.borders) bx, by, bw, _ := intBounds(cp.bounds)
x, y := int(at.X())-bx, int(at.Y())-by x, y := int(at.X())-bx, int(at.Y())-by
off := y*bw + x off := y*bw + x
return pixel.NRGBA{ return pixel.NRGBA{
@ -417,32 +378,19 @@ func (cp *canvasPicture) Draw(t pixel.TargetTriangles) {
if cp.dst != ct.dst { if cp.dst != ct.dst {
panic(fmt.Errorf("(%T).Draw: TargetTriangles generated by different Canvas", cp)) panic(fmt.Errorf("(%T).Draw: TargetTriangles generated by different Canvas", cp))
} }
ct.draw(cp.tex, cp.borders, cp.bounds) ct.draw(cp.tex, cp.bounds)
} }
type canvasCanvasPicture struct { type canvasCanvasPicture struct {
src, dst *Canvas src, dst *Canvas
bounds pixel.Rect
orig *canvasCanvasPicture
} }
func (ccp *canvasCanvasPicture) Bounds() pixel.Rect { func (ccp *canvasCanvasPicture) Bounds() pixel.Rect {
return ccp.bounds return ccp.src.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) Color(at pixel.Vec) pixel.NRGBA { func (ccp *canvasCanvasPicture) Color(at pixel.Vec) pixel.NRGBA {
if !ccp.bounds.Contains(at) { if !ccp.Bounds().Contains(at) {
return pixel.NRGBA{} return pixel.NRGBA{}
} }
return ccp.src.Color(at) return ccp.src.Color(at)
@ -453,7 +401,7 @@ func (ccp *canvasCanvasPicture) Draw(t pixel.TargetTriangles) {
if ccp.dst != ct.dst { if ccp.dst != ct.dst {
panic(fmt.Errorf("(%T).Draw: TargetTriangles generated by different Canvas", ccp)) panic(fmt.Errorf("(%T).Draw: TargetTriangles generated by different Canvas", ccp))
} }
ct.draw(ccp.src.orig.f.Texture(), ccp.src.orig.borders, ccp.bounds) ct.draw(ccp.src.orig.f.Texture(), ccp.Bounds())
} }
const ( const (
@ -474,16 +422,14 @@ const (
canvasTransform int = iota canvasTransform int = iota
canvasColorMask canvasColorMask
canvasBounds canvasBounds
canvasTexBorders
canvasTexBounds canvasTexBounds
) )
var canvasUniformFormat = glhf.AttrFormat{ var canvasUniformFormat = glhf.AttrFormat{
canvasTransform: {Name: "transform", Type: glhf.Mat3}, canvasTransform: {Name: "transform", Type: glhf.Mat3},
canvasColorMask: {Name: "colorMask", Type: glhf.Vec4}, canvasColorMask: {Name: "colorMask", Type: glhf.Vec4},
canvasBounds: {Name: "bounds", Type: glhf.Vec4}, canvasBounds: {Name: "bounds", Type: glhf.Vec4},
canvasTexBorders: {Name: "texBorders", Type: glhf.Vec4}, canvasTexBounds: {Name: "texBounds", Type: glhf.Vec4},
canvasTexBounds: {Name: "texBounds", Type: glhf.Vec4},
} }
var canvasVertexShader = ` var canvasVertexShader = `
@ -532,15 +478,8 @@ void main() {
} else { } else {
color = vec4(0, 0, 0, 0); color = vec4(0, 0, 0, 0);
color += (1 - Intensity) * colorMask * Color; color += (1 - Intensity) * colorMask * Color;
vec2 t = (Texture - texBounds.xy) / texBounds.zw;
float bx = texBounds.x; color += Intensity * colorMask * Color * texture(tex, t);
float by = texBounds.y;
float bw = texBounds.z;
float bh = texBounds.w;
if (bx <= Texture.x && Texture.x <= bx + bw && by <= Texture.y && Texture.y <= by + bh) {
vec2 t = (Texture - texBorders.xy) / texBorders.zw;
color += Intensity * colorMask * Color * texture(tex, t);
}
} }
} }
` `