2016-12-03 09:25:41 -06:00
|
|
|
package pixel
|
|
|
|
|
|
|
|
import (
|
2017-01-04 17:19:45 -06:00
|
|
|
"fmt"
|
2016-12-03 09:25:41 -06:00
|
|
|
"image/color"
|
|
|
|
)
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// TrianglesData specifies a list of Triangles vertices with three common properties: Position,
|
|
|
|
// Color and Texture.
|
|
|
|
type TrianglesData []struct {
|
|
|
|
Position Vec
|
|
|
|
Color color.Color
|
|
|
|
Texture Vec
|
2016-12-06 10:53:10 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Len returns the number of vertices in TrianglesData.
|
|
|
|
func (td *TrianglesData) Len() int {
|
|
|
|
return len(*td)
|
2016-12-06 10:53:10 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Draw is unimplemented for TrianglesData and panics.
|
|
|
|
func (td *TrianglesData) Draw() {
|
|
|
|
panic(fmt.Errorf("%T.Draw: invalid operation", td))
|
2016-12-06 10:53:10 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Update copies vertex properties from the supplied Triangles into this TrianglesData.
|
2017-01-01 15:12:12 -06:00
|
|
|
//
|
2017-01-04 17:19:45 -06:00
|
|
|
// TrianglesPosition, TrianglesColor and TrianglesTexture are supported.
|
|
|
|
func (td *TrianglesData) Update(t Triangles) {
|
|
|
|
if t.Len() > td.Len() {
|
|
|
|
*td = append(*td, make(TrianglesData, t.Len()-td.Len())...)
|
2016-12-06 10:53:10 -06:00
|
|
|
}
|
2017-01-04 17:19:45 -06:00
|
|
|
if t.Len() < td.Len() {
|
|
|
|
*td = (*td)[:t.Len()]
|
2017-01-01 15:12:12 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// fast path optimization
|
|
|
|
if t, ok := t.(*TrianglesData); ok {
|
|
|
|
copy(*td, *t)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if t, ok := t.(*TrianglesColorData); ok {
|
|
|
|
copy(*td, *(*TrianglesData)(t))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if t, ok := t.(*TrianglesTextureData); ok {
|
|
|
|
copy(*td, *(*TrianglesData)(t))
|
|
|
|
return
|
|
|
|
}
|
2016-12-14 10:53:29 -06:00
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// slow path manual copy
|
|
|
|
if t, ok := t.(TrianglesPosition); ok {
|
|
|
|
for i := range *td {
|
|
|
|
(*td)[i].Position = t.Position(i)
|
2016-12-14 10:53:29 -06:00
|
|
|
}
|
2017-01-04 17:19:45 -06:00
|
|
|
}
|
|
|
|
if t, ok := t.(TrianglesColor); ok {
|
|
|
|
for i := range *td {
|
|
|
|
(*td)[i].Color = t.Color(i)
|
2016-12-17 19:06:50 -06:00
|
|
|
}
|
|
|
|
}
|
2017-01-04 17:19:45 -06:00
|
|
|
if t, ok := t.(TrianglesTexture); ok {
|
|
|
|
for i := range *td {
|
|
|
|
(*td)[i].Texture = t.Texture(i)
|
2016-12-20 07:56:45 -06:00
|
|
|
}
|
2016-12-20 07:23:50 -06:00
|
|
|
}
|
2016-12-17 19:06:50 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Position returns the position property of i-th vertex.
|
|
|
|
func (td *TrianglesData) Position(i int) Vec {
|
|
|
|
return (*td)[i].Position
|
2016-12-14 10:53:29 -06:00
|
|
|
}
|
2016-12-06 10:53:10 -06:00
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Color returns the color property of i-th vertex.
|
|
|
|
func (td *TrianglesData) Color(i int) color.Color {
|
|
|
|
return (*td)[i].Color
|
2016-12-06 10:53:10 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Texture returns the texture property of i-th vertex.
|
|
|
|
func (td *TrianglesData) Texture(i int) Vec {
|
|
|
|
return (*td)[i].Texture
|
2016-12-03 13:20:16 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// TrianglesColorData is same as TrianglesData, except is lacks Texture property.
|
|
|
|
type TrianglesColorData TrianglesData
|
2016-12-03 13:20:16 -06:00
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Len returns the number of vertices in TrianglesColorData.
|
|
|
|
func (td *TrianglesColorData) Len() int {
|
|
|
|
return (*TrianglesData)(td).Len()
|
2016-12-03 13:20:16 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Draw is unimplemented for TrianglesColorData and panics.
|
|
|
|
func (td *TrianglesColorData) Draw() {
|
|
|
|
(*TrianglesData)(td).Draw()
|
2016-12-03 13:20:16 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Update copies vertex properties from the supplied Triangles into this TrianglesColorData.
|
|
|
|
func (td *TrianglesColorData) Update(t Triangles) {
|
|
|
|
(*TrianglesData)(td).Update(t)
|
2016-12-03 13:20:16 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Position returns the position property of i-th vertex.
|
|
|
|
func (td *TrianglesColorData) Position(i int) Vec {
|
|
|
|
return (*TrianglesData)(td).Position(i)
|
2016-12-03 13:20:16 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Color returns the color property of i-th vertex.
|
|
|
|
func (td *TrianglesColorData) Color(i int) color.Color {
|
|
|
|
return (*TrianglesData)(td).Color(i)
|
2016-12-03 13:20:16 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// TrianglesTextureData is same as TrianglesData, except is lacks Color property.
|
|
|
|
type TrianglesTextureData TrianglesData
|
2016-12-03 13:20:16 -06:00
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Len returns the number of vertices in TrianglesTextureData.
|
|
|
|
func (td *TrianglesTextureData) Len() int {
|
|
|
|
return (*TrianglesData)(td).Len()
|
2016-12-03 13:20:16 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Draw is unimplemented for TrianglesTextureData and panics.
|
|
|
|
func (td *TrianglesTextureData) Draw() {
|
|
|
|
(*TrianglesData)(td).Draw()
|
2016-12-03 09:25:41 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Update copies vertex properties from the supplied Triangles into this TrianglesTextureData.
|
|
|
|
func (td *TrianglesTextureData) Update(t Triangles) {
|
|
|
|
(*TrianglesData)(td).Update(t)
|
2016-12-03 09:25:41 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Position returns the position property of i-th vertex.
|
|
|
|
func (td *TrianglesTextureData) Position(i int) Vec {
|
|
|
|
return (*TrianglesData)(td).Position(i)
|
2016-12-03 09:25:41 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Texture returns the texture property of i-th vertex.
|
|
|
|
func (td *TrianglesTextureData) Texture(i int) Vec {
|
|
|
|
return (*TrianglesData)(td).Texture(i)
|
2016-12-03 09:25:41 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// TrianglesDrawer is a helper type that wraps Triangles and turns them into a Drawer.
|
2016-12-03 09:25:41 -06:00
|
|
|
//
|
2017-01-04 17:19:45 -06:00
|
|
|
// It does so by creating a separate Triangles instance for each Target. The instances are
|
|
|
|
// correctly updated alongside the wrapped Triangles.
|
|
|
|
type TrianglesDrawer struct {
|
|
|
|
Triangles
|
2016-12-03 09:25:41 -06:00
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
tris map[Target]Triangles
|
|
|
|
dirty bool
|
2016-12-03 12:51:43 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
func (td *TrianglesDrawer) flush() {
|
|
|
|
if !td.dirty {
|
|
|
|
return
|
2016-12-08 08:25:00 -06:00
|
|
|
}
|
2017-01-04 17:19:45 -06:00
|
|
|
td.dirty = false
|
2016-12-08 08:25:00 -06:00
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
for _, t := range td.tris {
|
|
|
|
t.Update(td.Triangles)
|
2016-12-14 10:53:29 -06:00
|
|
|
}
|
2017-01-04 17:19:45 -06:00
|
|
|
}
|
2016-12-03 12:51:43 -06:00
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Draw draws the wrapped Triangles onto the provided Target.
|
|
|
|
func (td *TrianglesDrawer) Draw(target Target) {
|
|
|
|
if td.tris == nil {
|
|
|
|
td.tris = make(map[Target]Triangles)
|
|
|
|
}
|
2016-12-19 18:23:33 -06:00
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
td.flush()
|
2016-12-03 12:51:43 -06:00
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
tri := td.tris[target]
|
|
|
|
if tri == nil {
|
|
|
|
tri = target.MakeTriangles(td.Triangles)
|
|
|
|
td.tris[target] = tri
|
|
|
|
}
|
|
|
|
tri.Draw()
|
2016-12-03 12:51:43 -06:00
|
|
|
}
|
|
|
|
|
2017-01-04 17:19:45 -06:00
|
|
|
// Update updates the wrapped Triangles with the supplied Triangles. Call only this method to
|
|
|
|
// update the wrapped Triangles, otherwise the TrianglesDrawer will not work correctly.
|
|
|
|
func (td *TrianglesDrawer) Update(t Triangles) {
|
|
|
|
td.dirty = true
|
|
|
|
td.Triangles.Update(t)
|
2016-12-03 13:20:16 -06:00
|
|
|
}
|