/
shape.go
147 lines (112 loc) · 4.46 KB
/
shape.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package paunch
import (
gl "github.com/chsc/gogl/gl21"
)
// Shape is an object that represents a vector shape, such as a triangle or
// other polygon, that can be drawn on screen.
type Shape struct {
mode gl.Enum
size int
vertexBuffer gl.Uint
verticies []float32
scaleX float64
scaleY float64
}
// NewShape creates a new Shape object based on the verticies and shape type.
func NewShape(shapeType ShapeType, verticies []float64) (*Shape, error) {
verticies32 := make([]float32, len(verticies))
for i, val := range verticies {
verticies32[i] = float32(val)
}
shape := &Shape{mode: gl.Enum(shapeType), size: len(verticies), vertexBuffer: 0, verticies: verticies32,
scaleX: 1, scaleY: 1}
gl.GenBuffers(1, &shape.vertexBuffer)
gl.BindBuffer(gl.ARRAY_BUFFER, gl.Uint(shape.vertexBuffer))
gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(shape.size*4), gl.Pointer(&shape.verticies[0]), gl.DYNAMIC_DRAW)
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
return shape, checkForErrors()
}
// NewShapeFromShape creates a copy of an existing Shape object.
func NewShapeFromShape(copyShape *Shape) (*Shape, error) {
shape := &Shape{mode: copyShape.mode, size: copyShape.size, verticies: make([]float32, len(copyShape.verticies)),
scaleX: copyShape.scaleX, scaleY: copyShape.scaleY}
copy(shape.verticies, copyShape.verticies)
gl.GenBuffers(1, &shape.vertexBuffer)
gl.BindBuffer(gl.ARRAY_BUFFER, shape.vertexBuffer)
gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(len(shape.verticies)*4), gl.Pointer(&shape.verticies[0]), gl.DYNAMIC_DRAW)
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
return shape, checkForErrors()
}
// SetScaling sets the scaling factor of the Shape object. For instance, an x
// and y scale value of two will make the Shape object twice as large.
func (shape *Shape) SetScaling(scaleX, scaleY float64) {
shape.scaleX = scaleX
shape.scaleY = scaleY
verticies := make([]float32, len(shape.verticies))
xTransform := shape.verticies[0] - (shape.verticies[0] * float32(scaleX))
yTransform := shape.verticies[1] - (shape.verticies[1] * float32(scaleY))
for i := range verticies {
if i%2 == 0 {
verticies[i] = shape.verticies[i] * float32(scaleX)
verticies[i] += xTransform
} else {
verticies[i] = shape.verticies[i] * float32(scaleY)
verticies[i] += yTransform
}
}
gl.BindBuffer(gl.ARRAY_BUFFER, shape.vertexBuffer)
gl.BufferSubData(gl.ARRAY_BUFFER, 0, gl.Sizeiptr(len(verticies)*4), gl.Pointer(&verticies[0]))
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}
// Draw draws the Shape object.
func (shape *Shape) Draw() error {
gl.BindBuffer(gl.ARRAY_BUFFER, shape.vertexBuffer)
vertexAttribLoc := gl.GetAttribLocation(paunchEffect.program, gl.GLString("position"))
gl.VertexAttribPointer(gl.Uint(vertexAttribLoc), 2, gl.FLOAT, gl.FALSE, 0, gl.Offset(nil, 0))
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
gl.EnableVertexAttribArray(gl.Uint(vertexAttribLoc))
gl.DrawArrays(shape.mode, 0, gl.Sizei(shape.size/2))
gl.DisableVertexAttribArray(gl.Uint(vertexAttribLoc))
//gl.DisableVertexAttribArray(gl.Uint(1))
//gl.BindTexture(gl.TEXTURE_2D, 0)
return checkForErrors()
}
// Move moves the Shape object a specified distance.
func (shape *Shape) Move(x, y float64) {
var verticies []float32
for i := 0; i < len(shape.verticies); i += 2 {
shape.verticies[i] += float32(x)
shape.verticies[i+1] += float32(y)
}
if shape.scaleX != 1 || shape.scaleY != 1 {
verticies = make([]float32, len(shape.verticies))
xTransform := shape.verticies[0] - (shape.verticies[0] * float32(shape.scaleX))
yTransform := shape.verticies[1] - (shape.verticies[1] * float32(shape.scaleY))
for i := range verticies {
if i%2 == 0 {
verticies[i] = shape.verticies[i] * float32(shape.scaleX)
verticies[i] += xTransform
} else {
verticies[i] = shape.verticies[i] * float32(shape.scaleY)
verticies[i] += yTransform
}
}
} else {
verticies = shape.verticies
}
gl.BindBuffer(gl.ARRAY_BUFFER, shape.vertexBuffer)
gl.BufferSubData(gl.ARRAY_BUFFER, 0, gl.Sizeiptr(len(verticies)*4), gl.Pointer(&verticies[0]))
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}
// SetPosition sets the position of the Shape object relative to first
// specified vertex.
func (shape *Shape) SetPosition(x, y float64) {
xDisp := x - float64(shape.verticies[0])
yDisp := y - float64(shape.verticies[1])
shape.Move(xDisp, yDisp)
}
// Position returns the X and Y position relative to the first specified
// vertex.
func (shape *Shape) Position() (x, y float64) {
return float64(shape.verticies[0]), float64(shape.verticies[1])
}