mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Cleaning naming and usage of buffers package
This commit is contained in:
@ -11,20 +11,20 @@ type BufUsage int
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
//Buffer is set only once and used many times
|
//Buffer is set only once and used many times
|
||||||
BufUsageStatic BufUsage = iota
|
BufUsage_Static BufUsage = iota
|
||||||
//Buffer is changed a lot and used many times
|
//Buffer is changed a lot and used many times
|
||||||
BufUsageDynamic
|
BufUsage_Dynamic
|
||||||
//Buffer is set only once and used by the GPU at most a few times
|
//Buffer is set only once and used by the GPU at most a few times
|
||||||
BufUsageStream
|
BufUsage_Stream
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b BufUsage) ToGL() uint32 {
|
func (b BufUsage) ToGL() uint32 {
|
||||||
switch b {
|
switch b {
|
||||||
case BufUsageStatic:
|
case BufUsage_Static:
|
||||||
return gl.STATIC_DRAW
|
return gl.STATIC_DRAW
|
||||||
case BufUsageDynamic:
|
case BufUsage_Dynamic:
|
||||||
return gl.DYNAMIC_DRAW
|
return gl.DYNAMIC_DRAW
|
||||||
case BufUsageStream:
|
case BufUsage_Stream:
|
||||||
return gl.STREAM_DRAW
|
return gl.STREAM_DRAW
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,15 +5,6 @@ import (
|
|||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BufferLayoutElement struct {
|
|
||||||
Offset int
|
|
||||||
DataType
|
|
||||||
}
|
|
||||||
|
|
||||||
type BufferLayout struct {
|
|
||||||
Elements []BufferLayoutElement
|
|
||||||
}
|
|
||||||
|
|
||||||
type Buffer struct {
|
type Buffer struct {
|
||||||
VAOID uint32
|
VAOID uint32
|
||||||
//BufID is the ID of the VBO
|
//BufID is the ID of the VBO
|
||||||
@ -21,8 +12,9 @@ type Buffer struct {
|
|||||||
//IndexBufID is the ID of the index/element buffer
|
//IndexBufID is the ID of the index/element buffer
|
||||||
IndexBufID uint32
|
IndexBufID uint32
|
||||||
IndexBufCount int32
|
IndexBufCount int32
|
||||||
Layout BufferLayout
|
|
||||||
Stride int32
|
Stride int32
|
||||||
|
|
||||||
|
layout []Element
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Buffer) Bind() {
|
func (b *Buffer) Bind() {
|
||||||
@ -33,23 +25,12 @@ func (b *Buffer) UnBind() {
|
|||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Buffer) CalcValues() {
|
|
||||||
|
|
||||||
b.Stride = 0
|
|
||||||
for i := 0; i < len(b.Layout.Elements); i++ {
|
|
||||||
|
|
||||||
info := GetDataTypeInfo(b.Layout.Elements[i].DataType)
|
|
||||||
b.Layout.Elements[i].Offset = int(b.Stride)
|
|
||||||
b.Stride += info.GetSize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Buffer) SetData(values []float32) {
|
func (b *Buffer) SetData(values []float32) {
|
||||||
|
|
||||||
gl.BindVertexArray(b.VAOID)
|
gl.BindVertexArray(b.VAOID)
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, b.BufID)
|
gl.BindBuffer(gl.ARRAY_BUFFER, b.BufID)
|
||||||
|
|
||||||
gl.BufferData(gl.ARRAY_BUFFER, len(values)*4, gl.Ptr(values), BufUsageStatic.ToGL())
|
gl.BufferData(gl.ARRAY_BUFFER, len(values)*4, gl.Ptr(values), BufUsage_Static.ToGL())
|
||||||
|
|
||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||||
@ -61,18 +42,33 @@ func (b *Buffer) SetIndexBufData(values []uint32) {
|
|||||||
gl.BindVertexArray(b.VAOID)
|
gl.BindVertexArray(b.VAOID)
|
||||||
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, b.IndexBufID)
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, b.IndexBufID)
|
||||||
|
|
||||||
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(values)*4, gl.Ptr(values), BufUsageStatic.ToGL())
|
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(values)*4, gl.Ptr(values), BufUsage_Static.ToGL())
|
||||||
|
|
||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBuffer(layout BufferLayout) Buffer {
|
func (b *Buffer) GetLayout() []Element {
|
||||||
|
e := make([]Element, len(b.layout))
|
||||||
|
copy(e, b.layout)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
b := Buffer{
|
func (b *Buffer) SetLayout(layout ...Element) {
|
||||||
Layout: layout,
|
|
||||||
|
b.layout = layout
|
||||||
|
|
||||||
|
b.Stride = 0
|
||||||
|
for i := 0; i < len(b.layout); i++ {
|
||||||
|
|
||||||
|
b.layout[i].Offset = int(b.Stride)
|
||||||
|
b.Stride += b.layout[i].Size()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBuffer(layout ...Element) Buffer {
|
||||||
|
|
||||||
|
b := Buffer{}
|
||||||
gl.GenVertexArrays(1, &b.VAOID)
|
gl.GenVertexArrays(1, &b.VAOID)
|
||||||
if b.VAOID == 0 {
|
if b.VAOID == 0 {
|
||||||
logging.ErrLog.Println("Failed to create openGL vertex array object")
|
logging.ErrLog.Println("Failed to create openGL vertex array object")
|
||||||
@ -88,6 +84,6 @@ func NewBuffer(layout BufferLayout) Buffer {
|
|||||||
logging.ErrLog.Println("Failed to create openGL buffer")
|
logging.ErrLog.Println("Failed to create openGL buffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
b.CalcValues()
|
b.SetLayout(layout...)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,86 +0,0 @@
|
|||||||
package buffers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/bloeys/nmage/asserts"
|
|
||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DataType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
DataTypeUnknown DataType = iota
|
|
||||||
DataTypeUint32
|
|
||||||
DataTypeInt32
|
|
||||||
DataTypeFloat32
|
|
||||||
DataTypeFloat64
|
|
||||||
|
|
||||||
DataTypeVec2
|
|
||||||
DataTypeVec3
|
|
||||||
DataTypeVec4
|
|
||||||
)
|
|
||||||
|
|
||||||
type DataTypeInfo struct {
|
|
||||||
//ElementSize is size in bytes of one element (e.g. for vec3 its 4)
|
|
||||||
ElementSize int32
|
|
||||||
//ElementCount is number of elements (e.g. for vec3 its 3)
|
|
||||||
ElementCount int32
|
|
||||||
//ElementType is the type of each primitive (e.g. for vec3 its gl.FLOAT)
|
|
||||||
ElementType uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
//GetSize returns the total size in bytes (e.g. for vec3 its 4*3)
|
|
||||||
func (dti *DataTypeInfo) GetSize() int32 {
|
|
||||||
return dti.ElementSize * dti.ElementCount
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetDataTypeInfo(dt DataType) DataTypeInfo {
|
|
||||||
|
|
||||||
switch dt {
|
|
||||||
case DataTypeUint32:
|
|
||||||
fallthrough
|
|
||||||
case DataTypeInt32:
|
|
||||||
return DataTypeInfo{
|
|
||||||
ElementSize: 4,
|
|
||||||
ElementCount: 1,
|
|
||||||
ElementType: gl.INT,
|
|
||||||
}
|
|
||||||
|
|
||||||
case DataTypeFloat32:
|
|
||||||
return DataTypeInfo{
|
|
||||||
ElementSize: 4,
|
|
||||||
ElementCount: 1,
|
|
||||||
ElementType: gl.FLOAT,
|
|
||||||
}
|
|
||||||
case DataTypeFloat64:
|
|
||||||
return DataTypeInfo{
|
|
||||||
ElementSize: 8,
|
|
||||||
ElementCount: 1,
|
|
||||||
ElementType: gl.DOUBLE,
|
|
||||||
}
|
|
||||||
|
|
||||||
case DataTypeVec2:
|
|
||||||
return DataTypeInfo{
|
|
||||||
ElementSize: 4,
|
|
||||||
ElementCount: 2,
|
|
||||||
ElementType: gl.FLOAT,
|
|
||||||
}
|
|
||||||
case DataTypeVec3:
|
|
||||||
return DataTypeInfo{
|
|
||||||
ElementSize: 4,
|
|
||||||
ElementCount: 3,
|
|
||||||
ElementType: gl.FLOAT,
|
|
||||||
}
|
|
||||||
case DataTypeVec4:
|
|
||||||
return DataTypeInfo{
|
|
||||||
ElementSize: 4,
|
|
||||||
ElementCount: 4,
|
|
||||||
ElementType: gl.FLOAT,
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
|
||||||
return DataTypeInfo{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
122
buffers/element.go
Executable file
122
buffers/element.go
Executable file
@ -0,0 +1,122 @@
|
|||||||
|
package buffers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/bloeys/nmage/asserts"
|
||||||
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Element represents an element that makes up a buffer (e.g. Vec3 at an offset of 12 bytes)
|
||||||
|
type Element struct {
|
||||||
|
Offset int
|
||||||
|
ElementType
|
||||||
|
}
|
||||||
|
|
||||||
|
//ElementType is the type of an element thats makes up a buffer (e.g. Vec3)
|
||||||
|
type ElementType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
DataTypeUnknown ElementType = iota
|
||||||
|
DataTypeUint32
|
||||||
|
DataTypeInt32
|
||||||
|
DataTypeFloat32
|
||||||
|
|
||||||
|
DataTypeVec2
|
||||||
|
DataTypeVec3
|
||||||
|
DataTypeVec4
|
||||||
|
)
|
||||||
|
|
||||||
|
func (dt ElementType) GLType() uint32 {
|
||||||
|
|
||||||
|
switch dt {
|
||||||
|
case DataTypeUint32:
|
||||||
|
return gl.UNSIGNED_INT
|
||||||
|
case DataTypeInt32:
|
||||||
|
return gl.INT
|
||||||
|
|
||||||
|
case DataTypeFloat32:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeVec2:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeVec3:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeVec4:
|
||||||
|
return gl.FLOAT
|
||||||
|
|
||||||
|
default:
|
||||||
|
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//CompSize returns the size in bytes for one component of the type (e.g. for Vec2 its 4)
|
||||||
|
func (dt ElementType) CompSize() int32 {
|
||||||
|
|
||||||
|
switch dt {
|
||||||
|
case DataTypeUint32:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeFloat32:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeInt32:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeVec2:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeVec3:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeVec4:
|
||||||
|
return 4
|
||||||
|
|
||||||
|
default:
|
||||||
|
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//CompCount returns the number of components in the element (e.g. for Vec2 its 2)
|
||||||
|
func (dt ElementType) CompCount() int32 {
|
||||||
|
|
||||||
|
switch dt {
|
||||||
|
case DataTypeUint32:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeFloat32:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeInt32:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
case DataTypeVec2:
|
||||||
|
return 2
|
||||||
|
case DataTypeVec3:
|
||||||
|
return 3
|
||||||
|
case DataTypeVec4:
|
||||||
|
return 4
|
||||||
|
|
||||||
|
default:
|
||||||
|
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Size returns the total size in bytes (e.g. for vec3 its 3*4=12 bytes)
|
||||||
|
func (dt ElementType) Size() int32 {
|
||||||
|
|
||||||
|
switch dt {
|
||||||
|
case DataTypeUint32:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeFloat32:
|
||||||
|
fallthrough
|
||||||
|
case DataTypeInt32:
|
||||||
|
return 4
|
||||||
|
|
||||||
|
case DataTypeVec2:
|
||||||
|
return 2 * 4
|
||||||
|
case DataTypeVec3:
|
||||||
|
return 3 * 4
|
||||||
|
case DataTypeVec4:
|
||||||
|
return 4 * 4
|
||||||
|
|
||||||
|
default:
|
||||||
|
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
9
main.go
9
main.go
@ -92,7 +92,7 @@ func main() {
|
|||||||
initImGUI()
|
initImGUI()
|
||||||
|
|
||||||
//Enable vertex attributes
|
//Enable vertex attributes
|
||||||
simpleMat.SetAttribute(cubeMesh.BufObjV2)
|
simpleMat.SetAttribute(cubeMesh.Buf)
|
||||||
|
|
||||||
//Movement, scale and rotation
|
//Movement, scale and rotation
|
||||||
translationMat := gglm.NewTranslationMat(gglm.NewVec3(0, 0, 0))
|
translationMat := gglm.NewTranslationMat(gglm.NewVec3(0, 0, 0))
|
||||||
@ -351,15 +351,14 @@ func draw() {
|
|||||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||||
|
|
||||||
simpleMat.Bind()
|
simpleMat.Bind()
|
||||||
cubeMesh.BufObjV2.Bind()
|
cubeMesh.Buf.Bind()
|
||||||
tempModelMat := modelMat.Clone()
|
tempModelMat := modelMat.Clone()
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, cubeMesh.BufObjV2.BufID)
|
|
||||||
|
|
||||||
rowSize := 10
|
rowSize := 100
|
||||||
for y := 0; y < rowSize; y++ {
|
for y := 0; y < rowSize; y++ {
|
||||||
for x := 0; x < rowSize; x++ {
|
for x := 0; x < rowSize; x++ {
|
||||||
simpleMat.SetUnifMat4("modelMat", &tempModelMat.Translate(gglm.NewVec3(-1, 0, 0)).Mat4)
|
simpleMat.SetUnifMat4("modelMat", &tempModelMat.Translate(gglm.NewVec3(-1, 0, 0)).Mat4)
|
||||||
gl.DrawElements(gl.TRIANGLES, cubeMesh.BufObjV2.IndexBufCount, gl.UNSIGNED_INT, gl.PtrOffset(0))
|
gl.DrawElements(gl.TRIANGLES, cubeMesh.Buf.IndexBufCount, gl.UNSIGNED_INT, gl.PtrOffset(0))
|
||||||
}
|
}
|
||||||
simpleMat.SetUnifMat4("modelMat", &tempModelMat.Translate(gglm.NewVec3(float32(rowSize), -1, 0)).Mat4)
|
simpleMat.SetUnifMat4("modelMat", &tempModelMat.Translate(gglm.NewVec3(float32(rowSize), -1, 0)).Mat4)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,12 +32,10 @@ func (m *Material) SetAttribute(bufObj buffers.Buffer) {
|
|||||||
//NOTE: VBOs are only bound at 'VertexAttribPointer', not BindBUffer, so we need to bind the buffer and vao here
|
//NOTE: VBOs are only bound at 'VertexAttribPointer', not BindBUffer, so we need to bind the buffer and vao here
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, bufObj.BufID)
|
gl.BindBuffer(gl.ARRAY_BUFFER, bufObj.BufID)
|
||||||
|
|
||||||
for i := 0; i < len(bufObj.Layout.Elements); i++ {
|
layout := bufObj.GetLayout()
|
||||||
|
for i := 0; i < len(layout); i++ {
|
||||||
gl.EnableVertexAttribArray(uint32(i))
|
gl.EnableVertexAttribArray(uint32(i))
|
||||||
|
gl.VertexAttribPointer(uint32(i), layout[i].ElementType.CompCount(), layout[i].ElementType.GLType(), false, bufObj.Stride, gl.PtrOffset(layout[i].Offset))
|
||||||
info := buffers.GetDataTypeInfo(bufObj.Layout.Elements[i].DataType)
|
|
||||||
gl.VertexAttribPointer(uint32(i), info.ElementCount, info.ElementType, false, bufObj.Stride, gl.PtrOffset(bufObj.Layout.Elements[i].Offset))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bufObj.UnBind()
|
bufObj.UnBind()
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
type Mesh struct {
|
type Mesh struct {
|
||||||
Name string
|
Name string
|
||||||
BufObjV2 buffers.Buffer
|
Buf buffers.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh, error) {
|
func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh, error) {
|
||||||
@ -28,23 +28,17 @@ func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mesh := &Mesh{Name: name}
|
mesh := &Mesh{Name: name}
|
||||||
|
|
||||||
sceneMesh := scene.Meshes[0]
|
sceneMesh := scene.Meshes[0]
|
||||||
|
mesh.Buf = buffers.NewBuffer()
|
||||||
|
|
||||||
dataSize := len(sceneMesh.Vertices)*3 + len(sceneMesh.Normals)*3
|
dataSize := len(sceneMesh.Vertices)*3 + len(sceneMesh.Normals)*3
|
||||||
|
layoutToUse := []buffers.Element{{ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec3}}
|
||||||
mesh.BufObjV2 = buffers.NewBuffer(buffers.BufferLayout{
|
|
||||||
Elements: []buffers.BufferLayoutElement{
|
|
||||||
{DataType: buffers.DataTypeVec3},
|
|
||||||
{DataType: buffers.DataTypeVec3},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if len(sceneMesh.ColorSets) > 0 {
|
if len(sceneMesh.ColorSets) > 0 {
|
||||||
mesh.BufObjV2.Layout.Elements = append(mesh.BufObjV2.Layout.Elements, buffers.BufferLayoutElement{DataType: buffers.DataTypeVec4})
|
layoutToUse = append(layoutToUse, buffers.Element{ElementType: buffers.DataTypeVec4})
|
||||||
dataSize += len(sceneMesh.ColorSets) * 4
|
dataSize += len(sceneMesh.ColorSets) * 4
|
||||||
mesh.BufObjV2.CalcValues()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mesh.Buf.SetLayout(layoutToUse...)
|
||||||
positions := flattenVec3(sceneMesh.Vertices)
|
positions := flattenVec3(sceneMesh.Vertices)
|
||||||
normals := flattenVec3(sceneMesh.Normals)
|
normals := flattenVec3(sceneMesh.Normals)
|
||||||
colors := []float32{}
|
colors := []float32{}
|
||||||
@ -66,8 +60,8 @@ func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh,
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.BufObjV2.SetData(values)
|
mesh.Buf.SetData(values)
|
||||||
mesh.BufObjV2.SetIndexBufData(flattenFaces(sceneMesh.Faces))
|
mesh.Buf.SetIndexBufData(flattenFaces(sceneMesh.Faces))
|
||||||
return mesh, nil
|
return mesh, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user