/
vao2.go
120 lines (100 loc) · 2.74 KB
/
vao2.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
package gfx
import (
"github.com/go-gl/gl/v4.5-core/gl"
"github.com/golang/glog"
)
// vao is a Vertex Array Object (VAO) that can be rendered and deleted.
type vao struct {
// mode is like gl.LINES or gl.TRIANGLES passed to gl.DrawElements.
mode uint32
// array is the VAO name for gl.BindVertexArray.
array uint32
// count is the number of elements for gl.DrawElements.
count int32
// texture is the texture name for gl.BindTexture.
texture uint32
// hasTexture is true if a texture was binded.
hasTexture bool
}
func newVAO(data *VAOVertexData) *vao {
glog.V(2).Infof("creating vao: v(%d) tc(%d) c(%d) i(%d)", len(data.Vertices), len(data.TexCoords), len(data.Colors), len(data.Indices))
if len(data.Vertices) == 0 {
return &vao{}
}
if len(data.Indices) == 0 {
return &vao{}
}
vbo := glArrayBuffer(data.Vertices)
ibo := glElementArrayBuffer(data.Indices)
var tbo uint32
if len(data.TexCoords) != 0 {
tbo = glArrayBuffer(data.TexCoords)
}
var cbo uint32
if len(data.Colors) != 0 {
cbo = glArrayBuffer(data.Colors)
}
var array uint32
gl.GenVertexArrays(1, &array)
gl.BindVertexArray(array)
{
gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
gl.EnableVertexAttribArray(positionLocation)
gl.VertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, gl.PtrOffset(0))
if len(data.TexCoords) != 0 {
gl.BindBuffer(gl.ARRAY_BUFFER, tbo)
gl.EnableVertexAttribArray(texCoordLocation)
gl.VertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, gl.PtrOffset(0))
}
if len(data.Colors) != 0 {
gl.BindBuffer(gl.ARRAY_BUFFER, cbo)
gl.EnableVertexAttribArray(colorLocation)
gl.VertexAttribPointer(colorLocation, 3, gl.FLOAT, false, 0, gl.PtrOffset(0))
}
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo)
}
gl.BindVertexArray(0)
v := &vao{
mode: uint32(data.Mode),
array: array,
count: int32(len(data.Indices)),
}
if data.TextureRGBA != nil {
v.texture = glTexture(data.TextureRGBA)
v.hasTexture = true
}
return v
}
// Render renders the VAO.
func (v *vao) render() {
if v.count == 0 {
return // No buffer data. Nothing to render.
}
if v.hasTexture {
setFragMode(fragTextureMode)
gl.BindTexture(gl.TEXTURE_2D, v.texture)
defer func() {
setFragMode(fragColorMode)
gl.BindTexture(gl.TEXTURE_2D, 0)
}()
}
gl.BindVertexArray(v.array)
gl.DrawElements(v.mode, v.count, gl.UNSIGNED_SHORT, gl.Ptr(nil))
gl.BindVertexArray(0)
}
func (v *vao) delete() {
glog.V(2).Infof("deleting vao: array(%d) mode(%v) count(%d) texture(%d) hasTexture(%t)", v.array, v.mode, v.count, v.texture, v.hasTexture)
defer func() {
v.array = 0
v.mode = 0
v.count = 0
v.texture = 0
v.hasTexture = false
}()
if v.count != 0 {
gl.DeleteVertexArrays(1, &v.array)
}
if v.hasTexture {
gl.DeleteTextures(1, &v.texture)
}
}