go-opengl-pixel/batch.go

135 lines
3.1 KiB
Go
Raw Normal View History

2017-01-12 06:47:44 -06:00
package pixel
import (
2017-02-24 07:25:35 -06:00
"fmt"
2017-01-12 06:47:44 -06:00
"image/color"
2017-02-23 18:21:23 -06:00
"math"
2017-01-12 06:47:44 -06:00
"github.com/go-gl/mathgl/mgl32"
)
// Batch is a Target that allows for efficient drawing of many objects with the same Picture (but
// different slices of the same Picture are allowed).
//
// To put an object into a Batch, just draw it onto it:
// object.Draw(batch)
type Batch struct {
2017-02-23 18:21:23 -06:00
cont Drawer
2017-01-12 06:47:44 -06:00
mat mgl32.Mat3
col NRGBA
}
2017-02-23 18:21:23 -06:00
var _ BasicTarget = (*Batch)(nil)
2017-01-12 06:47:44 -06:00
// NewBatch creates an empty Batch with the specified Picture and container.
//
// The container is where objects get accumulated. Batch will support precisely those vertex
// properties, that the supplied container supports.
//
// Note, that if the container does not support TrianglesColor, color masking will not work.
2017-02-23 18:21:23 -06:00
func NewBatch(container Triangles, pic Picture) *Batch {
2017-01-12 06:47:44 -06:00
return &Batch{
2017-02-23 18:21:23 -06:00
cont: Drawer{Triangles: container, Picture: pic},
2017-01-12 06:47:44 -06:00
}
}
// Clear removes all objects from the Batch.
func (b *Batch) Clear() {
2017-02-23 18:21:23 -06:00
b.cont.Triangles.SetLen(0)
2017-01-28 13:01:59 -06:00
b.cont.Dirty()
2017-01-12 06:47:44 -06:00
}
// Draw draws all objects that are currently in the Batch onto another Target.
func (b *Batch) Draw(t Target) {
b.cont.Draw(t)
}
// SetTransform sets transforms used in the following draws onto the Batch.
func (b *Batch) SetTransform(t ...Transform) {
b.mat = transformToMat(t...)
}
2017-02-23 18:21:23 -06:00
// SetColorMask sets a mask color used in the following draws onto the Batch.
func (b *Batch) SetColorMask(c color.Color) {
2017-01-12 06:47:44 -06:00
if c == nil {
b.col = NRGBA{1, 1, 1, 1}
return
}
b.col = NRGBAModel.Convert(c).(NRGBA)
}
2017-02-23 18:21:23 -06:00
// MakeTriangles returns a specialized copy of the provided Triangles that draws onto this Batch.
func (b *Batch) MakeTriangles(t Triangles) TargetTriangles {
bt := &batchTriangles{
Triangles: t.Copy(),
orig: MakeTrianglesData(t.Len()),
trans: MakeTrianglesData(t.Len()),
b: b,
}
bt.orig.Update(t)
bt.trans.Update(bt.orig)
2017-02-23 18:21:23 -06:00
return bt
}
// MakePicture returns a specialized copy of the provided Picture that draws onto this Batch.
func (b *Batch) MakePicture(p Picture) TargetPicture {
return &batchPicture{
Picture: p,
2017-02-24 07:25:35 -06:00
b: b,
2017-02-23 18:21:23 -06:00
}
}
2017-01-12 06:47:44 -06:00
type batchTriangles struct {
Triangles
orig, trans *TrianglesData
2017-01-12 06:47:44 -06:00
2017-02-23 18:21:23 -06:00
b *Batch
2017-01-12 06:47:44 -06:00
}
2017-02-23 18:21:23 -06:00
func (bt *batchTriangles) draw(bp *batchPicture) {
for i := range *bt.trans {
2017-02-23 18:21:23 -06:00
transPos := bt.b.mat.Mul3x1(mgl32.Vec3{
float32((*bt.orig)[i].Position.X()),
float32((*bt.orig)[i].Position.Y()),
2017-01-12 06:47:44 -06:00
1,
})
(*bt.trans)[i].Position = V(float64(transPos.X()), float64(transPos.Y()))
(*bt.trans)[i].Color = (*bt.orig)[i].Color.Mul(bt.b.col)
2017-02-23 18:21:23 -06:00
if bp == nil {
(*bt.trans)[i].Picture = V(math.Inf(+1), math.Inf(+1))
}
2017-01-12 06:47:44 -06:00
}
2017-01-28 13:01:59 -06:00
bt.Triangles.Update(bt.trans)
2017-02-23 18:21:23 -06:00
cont := bt.b.cont.Triangles
cont.SetLen(cont.Len() + bt.Triangles.Len())
cont.Slice(cont.Len()-bt.Triangles.Len(), cont.Len()).Update(bt.Triangles)
bt.b.cont.Dirty()
}
func (bt *batchTriangles) Draw() {
bt.draw(nil)
}
type batchPicture struct {
Picture
2017-02-24 07:25:35 -06:00
b *Batch
2017-02-23 18:21:23 -06:00
}
func (bp *batchPicture) Slice(r Rect) Picture {
return &batchPicture{
Picture: bp.Picture.Slice(r),
}
}
func (bp *batchPicture) Draw(t TargetTriangles) {
2017-02-24 07:25:35 -06:00
bt := t.(*batchTriangles)
if bp.b != bt.b {
2017-02-28 11:24:31 -06:00
panic(fmt.Errorf("%T.Draw: TargetTriangles generated by different Batch", bp))
2017-02-24 07:25:35 -06:00
}
bt.draw(bp)
2017-01-12 06:47:44 -06:00
}