Newer
Older
package pixel
// Drawer glues all the fundamental interfaces (Target, Triangles, Picture) into a coherent and the
// only intended usage pattern.
//
// Drawer makes it possible to draw any combination of Triangles and Picture onto any Target
// efficiently.
//
// To create a Drawer, just assign it's Triangles and Picture fields:
// d := pixel.Drawer{Triangles: t, Picture: p}
//
// If Triangles is nil, nothing will be drawn. If Picture is nil, Triangles will be drawn without a
// Picture.
//
// Whenever you change the Triangles, call Dirty to notify Drawer that Triangles changed. You don't
// need to notify Drawer about a change of the Picture.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
type Drawer struct {
Triangles Triangles
Picture Picture
tris map[Target]TargetTriangles
clean map[Target]bool
pics map[targetPicturePair]TargetPicture
inited bool
}
type targetPicturePair struct {
Target Target
Picture Picture
}
func (d *Drawer) lazyInit() {
if !d.inited {
d.tris = make(map[Target]TargetTriangles)
d.clean = make(map[Target]bool)
d.pics = make(map[targetPicturePair]TargetPicture)
d.inited = true
}
}
// Dirty marks the Triangles of this Drawer as changed. If not called, changes will not be visible
// when drawing.
func (d *Drawer) Dirty() {
d.lazyInit()
for t := range d.clean {
d.clean[t] = false
}
}
// Draw efficiently draws Triangles with Picture onto the provided Target.
//
// If Triangles is nil, nothing will be drawn. If Picture is nil, Triangles will be drawn without a
// Picture.
func (d *Drawer) Draw(t Target) {
d.lazyInit()
if d.Triangles == nil {
return
}
tri := d.tris[t]
if tri == nil {
tri = t.MakeTriangles(d.Triangles)
d.tris[t] = tri
d.clean[t] = true
}
if !d.clean[t] {
tri.SetLen(d.Triangles.Len())
tri.Update(d.Triangles)
d.clean[t] = true
}
if d.Picture == nil {
tri.Draw()
return
}
pic := d.pics[targetPicturePair{t, d.Picture}]
pic = t.MakePicture(d.Picture)
d.pics[targetPicturePair{t, d.Picture}] = pic