Cleaning naming and usage of buffers package

This commit is contained in:
bloeys
2022-01-26 08:48:50 +04:00
parent 1109caef43
commit e38cd90a84
7 changed files with 167 additions and 144 deletions

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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
View 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
}
}

View File

@ -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)
} }

View File

@ -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()

View File

@ -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
} }