implement vertex array (vao+vbo)
This commit is contained in:
parent
4a52f3a7dd
commit
91763a9e1a
|
@ -1,5 +1,7 @@
|
|||
package pixelgl
|
||||
|
||||
import "github.com/go-gl/gl/v3.3-core/gl"
|
||||
|
||||
// VertexFormat defines a data format in a vertex buffer.
|
||||
//
|
||||
// Example:
|
||||
|
@ -7,6 +9,15 @@ package pixelgl
|
|||
// vf := VertexFormat{{Position, 2}, {Color, 4}, {TexCoord, 2}}
|
||||
type VertexFormat []VertexAttribute
|
||||
|
||||
// Size returns the total size of all vertex attributes in a vertex format.
|
||||
func (vf VertexFormat) Size() int {
|
||||
size := 0
|
||||
for _, va := range vf {
|
||||
size += va.Size
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
// VertexAttribute specifies a single attribute in a vertex buffer.
|
||||
// All vertex attributes are composed of float64s.
|
||||
//
|
||||
|
@ -32,3 +43,144 @@ const (
|
|||
TexCoord
|
||||
NumStandardVertexAttrib
|
||||
)
|
||||
|
||||
// VertexUsage specifies how often the vertex array data will be updated.
|
||||
type VertexUsage int
|
||||
|
||||
// Possible VertexUsage values are:
|
||||
// 1. StaticUsage - never or rarely updated
|
||||
// 2. DynamicUsage - often updated
|
||||
// 3. StreamUsage - updated every frame
|
||||
const (
|
||||
StaticUsage VertexUsage = gl.STATIC_DRAW
|
||||
DynamicUsage = gl.DYNAMIC_DRAW
|
||||
StreamUsage = gl.STREAM_DRAW
|
||||
)
|
||||
|
||||
// VertexDrawMode specifies how should the vertices be drawn.
|
||||
type VertexDrawMode int
|
||||
|
||||
// Possible VertexDrawMode values are:
|
||||
// 1. PointsDrawMode - just draw individual PointsDrawMode
|
||||
// 2. LinesDrawMode - take pairs of vertices and draw a line from each pair
|
||||
// 3. LineStripDrawMode - take each two subsequent vertices and draw a line from each two
|
||||
// 4. LineLoopDrawMode - same as line strip, but also draw a line between the first and the last vertex
|
||||
// 5. TrianglesDrawMode - take triples of vertices and draw a triangle from each triple
|
||||
// 6. TriangleStripDrawMode - take each three subsequent vertices and draw a triangle from each three
|
||||
// 7. TriangleFanDrawMode - take each two subsequent vertices excluding the first vertex and draw a triangle from the first vertex and the two
|
||||
const (
|
||||
PointsDrawMode VertexDrawMode = gl.POINTS
|
||||
LinesDrawMode = gl.LINES
|
||||
LineStripDrawMode = gl.LINE_STRIP
|
||||
LineLoopDrawMode = gl.LINE_LOOP
|
||||
TrianglesDrawMode = gl.TRIANGLES
|
||||
TriangleStripDrawMode = gl.TRIANGLE_STRIP
|
||||
TriangleFanDrawMode = gl.TRIANGLE_FAN
|
||||
)
|
||||
|
||||
// VertexArray is an OpenGL vertex array object that also holds it's own vertex buffer object.
|
||||
// From the user's points of view, VertexArray is an array of vertices that can be drawn.
|
||||
type VertexArray struct {
|
||||
parent BeginEnder
|
||||
format VertexFormat
|
||||
vao uint32
|
||||
vbo uint32
|
||||
mode VertexDrawMode
|
||||
count int
|
||||
}
|
||||
|
||||
// NewVertexArray creates a new vertex array and wrap another BeginEnder around it.
|
||||
func NewVertexArray(parent BeginEnder, format VertexFormat, mode VertexDrawMode, usage VertexUsage, data []float64) *VertexArray {
|
||||
va := &VertexArray{
|
||||
parent: parent,
|
||||
format: format,
|
||||
mode: mode,
|
||||
}
|
||||
Do(func() {
|
||||
gl.GenVertexArrays(1, &va.vao)
|
||||
gl.BindVertexArray(va.vao)
|
||||
|
||||
gl.GenBuffers(1, &va.vbo)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo)
|
||||
gl.BufferData(gl.ARRAY_BUFFER, 8*len(data), gl.Ptr(data), uint32(usage))
|
||||
|
||||
stride := format.Size()
|
||||
va.count = len(data) / stride
|
||||
|
||||
offset := 0
|
||||
for i, attr := range format {
|
||||
gl.VertexAttribPointer(
|
||||
uint32(i),
|
||||
int32(attr.Size),
|
||||
gl.DOUBLE,
|
||||
false,
|
||||
int32(stride),
|
||||
gl.PtrOffset(8*offset),
|
||||
)
|
||||
gl.EnableVertexAttribArray(uint32(i))
|
||||
offset += attr.Size
|
||||
}
|
||||
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||
gl.BindVertexArray(0)
|
||||
})
|
||||
return va
|
||||
}
|
||||
|
||||
// VertexFormat returns the format of the vertices inside a vertex array.
|
||||
//
|
||||
// Do not change this format!
|
||||
func (va *VertexArray) VertexFormat() VertexFormat {
|
||||
return va.format
|
||||
}
|
||||
|
||||
// SetDrawMode sets the draw mode of a vertex array. Subsequent calls to Draw will use this draw mode.
|
||||
func (va *VertexArray) SetDrawMode(mode VertexDrawMode) {
|
||||
Do(func() {
|
||||
va.mode = mode
|
||||
})
|
||||
}
|
||||
|
||||
// DrawMode returns the most recently set draw mode of a vertex array.
|
||||
func (va *VertexArray) DrawMode() VertexDrawMode {
|
||||
mode := DoVal(func() interface{} {
|
||||
return va.mode
|
||||
})
|
||||
return mode.(VertexDrawMode)
|
||||
}
|
||||
|
||||
// Draw draws a vertex array.
|
||||
func (va *VertexArray) Draw() {
|
||||
va.Begin()
|
||||
va.End()
|
||||
}
|
||||
|
||||
// UpdateData overwrites the current vertex array data starting at the index offset.
|
||||
//
|
||||
// Offset is not a number of bytes, instead, it's an index in the array.
|
||||
func (va *VertexArray) UpdateData(offset int, data []float64) {
|
||||
Do(func() {
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo)
|
||||
gl.BufferSubData(gl.ARRAY_BUFFER, 8*offset, 8*len(data), gl.Ptr(data))
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||
})
|
||||
}
|
||||
|
||||
// Begin binds a vertex array and it's associated vertex buffer.
|
||||
func (va *VertexArray) Begin() {
|
||||
va.parent.Begin()
|
||||
Do(func() {
|
||||
gl.BindVertexArray(va.vao)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo)
|
||||
})
|
||||
}
|
||||
|
||||
// End draws a vertex array and unbinds it alongside with it's associated vertex buffer.
|
||||
func (va *VertexArray) End() {
|
||||
Do(func() {
|
||||
gl.DrawArrays(uint32(va.mode), 0, int32(va.count))
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||
gl.BindVertexArray(0)
|
||||
})
|
||||
va.parent.End()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue