From f7fe00fe4d491434bdedaea25fe22acad6205daf Mon Sep 17 00:00:00 2001
From: faiface <faiface@ksp.sk>
Date: Thu, 12 Jan 2017 11:44:54 +0100
Subject: [PATCH] add Copy method to Triangles interface

---
 graphics.go  | 32 ++++++++++++++++++++++++++++++--
 interface.go |  3 +++
 util.go      | 10 ++++++++++
 window.go    | 14 ++++++++++----
 4 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/graphics.go b/graphics.go
index 6dc1108..8b58afb 100644
--- a/graphics.go
+++ b/graphics.go
@@ -79,6 +79,13 @@ func (td *TrianglesData) Append(t Triangles) {
 	*td = append(*td, newTd...)
 }
 
+// Copy returns an exact independent copy of this TrianglesData.
+func (td *TrianglesData) Copy() Triangles {
+	copyTd := make(TrianglesData, td.Len())
+	copyTd.Update(td)
+	return &copyTd
+}
+
 // Position returns the position property of i-th vertex.
 func (td *TrianglesData) Position(i int) Vec {
 	return (*td)[i].Position
@@ -117,6 +124,11 @@ func (td *TrianglesColorData) Append(t Triangles) {
 	(*TrianglesData)(td).Append(t)
 }
 
+// Copy returns an exact independent copy of this TrianglesColorData.
+func (td *TrianglesColorData) Copy() Triangles {
+	return (*TrianglesColorData)((*TrianglesData)(td).Copy().(*TrianglesData))
+}
+
 // Position returns the position property of i-th vertex.
 func (td *TrianglesColorData) Position(i int) Vec {
 	return (*TrianglesData)(td).Position(i)
@@ -150,6 +162,11 @@ func (td *TrianglesTextureData) Append(t Triangles) {
 	(*TrianglesData)(td).Append(t)
 }
 
+// Copy returns an exact independent copy of this TrianglesTextureData.
+func (td *TrianglesTextureData) Copy() Triangles {
+	return (*TrianglesTextureData)((*TrianglesData)(td).Copy().(*TrianglesData))
+}
+
 // Position returns the position property of i-th vertex.
 func (td *TrianglesTextureData) Position(i int) Vec {
 	return (*TrianglesData)(td).Position(i)
@@ -198,13 +215,24 @@ func (td *TrianglesDrawer) Draw(target Target) {
 	tri.Draw()
 }
 
-// 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.
+// 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)
 }
 
+// Append appends the supplied Triangles to the wrapped Triangles.
+//
+// Call only this method to append to the wrapped Triangles, otherwise the TrianglesDrawer will not
+// work correctly.
+func (td *TrianglesDrawer) Append(t Triangles) {
+	td.dirty = true
+	td.Triangles.Append(t)
+}
+
 // Sprite is a picture, positioned somewhere, with an optional mask color.
 type Sprite struct {
 	td        TrianglesDrawer
diff --git a/interface.go b/interface.go
index 9dc400e..6130b81 100644
--- a/interface.go
+++ b/interface.go
@@ -49,6 +49,9 @@ type Triangles interface {
 	//
 	// Behavior regarding unsupported properties should be same as with Update.
 	Append(Triangles)
+
+	// Copy creates an exact independent copy of this Triangles (with the same underlying type).
+	Copy() Triangles
 }
 
 // Drawer is something that can be drawn onto any Target.
diff --git a/util.go b/util.go
index 24e6199..ce46294 100644
--- a/util.go
+++ b/util.go
@@ -1,5 +1,7 @@
 package pixel
 
+import "github.com/go-gl/mathgl/mgl32"
+
 func clamp(x, low, high float64) float64 {
 	if x < low {
 		return low
@@ -9,3 +11,11 @@ func clamp(x, low, high float64) float64 {
 	}
 	return x
 }
+
+func transformToMat(t ...Transform) mgl32.Mat3 {
+	mat := mgl32.Ident3()
+	for i := range t {
+		mat = mat.Mul3(t[i].Mat())
+	}
+	return mat
+}
diff --git a/window.go b/window.go
index 177ea73..8eb9d29 100644
--- a/window.go
+++ b/window.go
@@ -470,6 +470,15 @@ func (wt *windowTriangles) Append(t Triangles) {
 	wt.submitData()
 }
 
+func (wt *windowTriangles) Copy() Triangles {
+	copyWt := &windowTriangles{
+		w:  wt.w,
+		vs: pixelgl.MakeVertexSlice(wt.w.shader, 0, 0),
+	}
+	copyWt.Update(wt)
+	return copyWt
+}
+
 func (wt *windowTriangles) Position(i int) Vec {
 	v := wt.data[i][positionVec2].(mgl32.Vec2)
 	return V(float64(v.X()), float64(v.Y()))
@@ -512,10 +521,7 @@ func (w *Window) SetPicture(p *Picture) {
 //
 // Transforms are applied right-to-left.
 func (w *Window) SetTransform(t ...Transform) {
-	w.mat = mgl32.Ident3()
-	for i := range t {
-		w.mat = w.mat.Mul3(t[i].Mat())
-	}
+	w.mat = transformToMat(t...)
 }
 
 // SetMaskColor sets a global mask color for the Window.
-- 
GitLab