mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Support interleaved buffers
This commit is contained in:
@ -5,14 +5,11 @@ import (
|
|||||||
"github.com/bloeys/nmage/logging"
|
"github.com/bloeys/nmage/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
func True(check bool, msg string) {
|
func T(check bool, msg string) {
|
||||||
if consts.Debug && !check {
|
|
||||||
logging.ErrLog.Panicln(msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func False(check bool, msg string) {
|
if !consts.Debug || check {
|
||||||
if consts.Debug && check {
|
return
|
||||||
logging.ErrLog.Panicln(msg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logging.ErrLog.Panicln("Assert failed:", msg)
|
||||||
}
|
}
|
||||||
|
|||||||
33
buffers/buf_usage.go
Executable file
33
buffers/buf_usage.go
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
package buffers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/bloeys/nmage/asserts"
|
||||||
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BufUsage int
|
||||||
|
|
||||||
|
const (
|
||||||
|
//Buffer is set only once and used many times
|
||||||
|
BufUsageStatic BufUsage = iota
|
||||||
|
//Buffer is changed a lot and used many times
|
||||||
|
BufUsageDynamic
|
||||||
|
//Buffer is set only once and used by the GPU at most a few times
|
||||||
|
BufUsageStream
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b BufUsage) ToGL() uint32 {
|
||||||
|
switch b {
|
||||||
|
case BufUsageStatic:
|
||||||
|
return gl.STATIC_DRAW
|
||||||
|
case BufUsageDynamic:
|
||||||
|
return gl.DYNAMIC_DRAW
|
||||||
|
case BufUsageStream:
|
||||||
|
return gl.STREAM_DRAW
|
||||||
|
}
|
||||||
|
|
||||||
|
asserts.T(false, fmt.Sprintf("Unexpected BufUsage value '%v'", b))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
@ -5,169 +5,89 @@ import (
|
|||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BufGLType int
|
type BufferLayoutElement struct {
|
||||||
|
Offset int
|
||||||
const (
|
DataType
|
||||||
BufGLTypeUnknown BufGLType = 0
|
|
||||||
//Generic array of data. Should be used for most data like vertex positions, vertex colors etc.
|
|
||||||
BufGLTypeArray BufGLType = gl.ARRAY_BUFFER
|
|
||||||
BufGLTypeIndices BufGLType = gl.ELEMENT_ARRAY_BUFFER
|
|
||||||
)
|
|
||||||
|
|
||||||
type BufType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
BufTypeUnknown BufType = iota
|
|
||||||
BufTypeVertPos
|
|
||||||
BufTypeColor
|
|
||||||
BufTypeIndex
|
|
||||||
BufTypeNormal
|
|
||||||
)
|
|
||||||
|
|
||||||
func (bt BufType) GetBufferGLType() BufGLType {
|
|
||||||
switch bt {
|
|
||||||
|
|
||||||
case BufTypeNormal:
|
|
||||||
fallthrough
|
|
||||||
case BufTypeColor:
|
|
||||||
fallthrough
|
|
||||||
case BufTypeVertPos:
|
|
||||||
return BufGLTypeArray
|
|
||||||
|
|
||||||
case BufTypeIndex:
|
|
||||||
return BufGLTypeIndices
|
|
||||||
default:
|
|
||||||
logging.WarnLog.Println("Unknown BufferType. BufferType: ", bt)
|
|
||||||
return BufGLTypeUnknown
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type BufUsage int
|
type BufferLayout struct {
|
||||||
|
Elements []BufferLayoutElement
|
||||||
const (
|
}
|
||||||
//Buffer is set only once and used many times
|
|
||||||
BufUsageStatic BufUsage = gl.STATIC_DRAW
|
|
||||||
//Buffer is changed a lot and used many times
|
|
||||||
BufUsageDynamic BufUsage = gl.DYNAMIC_DRAW
|
|
||||||
//Buffer is set only once and used by the GPU at most a few times
|
|
||||||
BufUsageStream BufUsage = gl.STREAM_DRAW
|
|
||||||
)
|
|
||||||
|
|
||||||
type Buffer struct {
|
type Buffer struct {
|
||||||
ID uint32
|
VAOID uint32
|
||||||
Type BufType
|
//BufID is the ID of the VBO
|
||||||
GLType BufGLType
|
BufID uint32
|
||||||
DataTypeInfo
|
//IndexBufID is the ID of the index/element buffer
|
||||||
|
IndexBufID uint32
|
||||||
//DataLen is the number of elements in the uploaded to the buffer
|
IndexBufCount int32
|
||||||
DataLen int32
|
Layout BufferLayout
|
||||||
|
Stride int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Buffer) Activate() {
|
func (b *Buffer) Bind() {
|
||||||
gl.BindBuffer(uint32(b.GLType), b.ID)
|
gl.BindVertexArray(b.VAOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Buffer) Deactivate() {
|
func (b *Buffer) UnBind() {
|
||||||
gl.BindBuffer(uint32(b.GLType), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type BufferObject struct {
|
|
||||||
VAOID uint32
|
|
||||||
VertPosBuf *Buffer
|
|
||||||
NormalBuf *Buffer
|
|
||||||
ColorBuf *Buffer
|
|
||||||
IndexBuf *Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bo *BufferObject) GenBuffer(data []float32, bufUsage BufUsage, bufType BufType, bufDataType DataType) {
|
|
||||||
|
|
||||||
gl.BindVertexArray(bo.VAOID)
|
|
||||||
|
|
||||||
//Create vertex buffer object
|
|
||||||
var vboID uint32
|
|
||||||
gl.GenBuffers(1, &vboID)
|
|
||||||
if vboID == 0 {
|
|
||||||
logging.ErrLog.Println("Failed to create openGL buffer")
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := &Buffer{
|
|
||||||
ID: vboID,
|
|
||||||
Type: bufType,
|
|
||||||
GLType: bufType.GetBufferGLType(),
|
|
||||||
DataTypeInfo: GetDataTypeInfo(bufDataType),
|
|
||||||
DataLen: int32(len(data)),
|
|
||||||
}
|
|
||||||
bo.SetBuffer(buf)
|
|
||||||
|
|
||||||
//Fill buffer with data
|
|
||||||
gl.BindBuffer(uint32(buf.GLType), buf.ID)
|
|
||||||
gl.BufferData(uint32(buf.GLType), int(buf.DataTypeInfo.ElementSize)*len(data), gl.Ptr(data), uint32(bufUsage))
|
|
||||||
|
|
||||||
//Unbind everything
|
|
||||||
gl.BindVertexArray(0)
|
|
||||||
gl.BindBuffer(uint32(buf.GLType), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bo *BufferObject) GenBufferUint32(data []uint32, bufUsage BufUsage, bufType BufType, bufDataType DataType) {
|
|
||||||
|
|
||||||
gl.BindVertexArray(bo.VAOID)
|
|
||||||
|
|
||||||
//Create vertex buffer object
|
|
||||||
var vboID uint32
|
|
||||||
gl.GenBuffers(1, &vboID)
|
|
||||||
if vboID == 0 {
|
|
||||||
logging.ErrLog.Println("Failed to create openGL buffer")
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := &Buffer{
|
|
||||||
ID: vboID,
|
|
||||||
Type: bufType,
|
|
||||||
GLType: bufType.GetBufferGLType(),
|
|
||||||
DataTypeInfo: GetDataTypeInfo(bufDataType),
|
|
||||||
DataLen: int32(len(data)),
|
|
||||||
}
|
|
||||||
bo.SetBuffer(buf)
|
|
||||||
|
|
||||||
//Fill buffer with data
|
|
||||||
gl.BindBuffer(uint32(buf.GLType), buf.ID)
|
|
||||||
gl.BufferData(uint32(buf.GLType), int(buf.DataTypeInfo.ElementSize)*len(data), gl.Ptr(data), uint32(bufUsage))
|
|
||||||
|
|
||||||
//Unbind everything
|
|
||||||
gl.BindVertexArray(0)
|
|
||||||
gl.BindBuffer(uint32(buf.GLType), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bo *BufferObject) SetBuffer(buf *Buffer) {
|
|
||||||
|
|
||||||
switch buf.Type {
|
|
||||||
case BufTypeVertPos:
|
|
||||||
bo.VertPosBuf = buf
|
|
||||||
case BufTypeNormal:
|
|
||||||
bo.NormalBuf = buf
|
|
||||||
case BufTypeColor:
|
|
||||||
bo.ColorBuf = buf
|
|
||||||
case BufTypeIndex:
|
|
||||||
bo.IndexBuf = buf
|
|
||||||
default:
|
|
||||||
logging.WarnLog.Println("Unknown buffer type in SetBuffer. Type:", buf.Type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bo *BufferObject) Bind() {
|
|
||||||
gl.BindVertexArray(bo.VAOID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bo *BufferObject) UnBind() {
|
|
||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBufferObject() *BufferObject {
|
func (b *Buffer) CalcValues() {
|
||||||
|
|
||||||
var vaoID uint32
|
b.Stride = 0
|
||||||
gl.GenVertexArrays(1, &vaoID)
|
for i := 0; i < len(b.Layout.Elements); i++ {
|
||||||
if vaoID == 0 {
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
gl.BindVertexArray(b.VAOID)
|
||||||
|
gl.BindBuffer(gl.ARRAY_BUFFER, b.BufID)
|
||||||
|
|
||||||
|
gl.BufferData(gl.ARRAY_BUFFER, len(values)*4, gl.Ptr(values), BufUsageStatic.ToGL())
|
||||||
|
|
||||||
|
gl.BindVertexArray(0)
|
||||||
|
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) SetIndexBufData(values []uint32) {
|
||||||
|
|
||||||
|
b.IndexBufCount = int32(len(values))
|
||||||
|
gl.BindVertexArray(b.VAOID)
|
||||||
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, b.IndexBufID)
|
||||||
|
|
||||||
|
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(values)*4, gl.Ptr(values), BufUsageStatic.ToGL())
|
||||||
|
|
||||||
|
gl.BindVertexArray(0)
|
||||||
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBuffer(layout BufferLayout) Buffer {
|
||||||
|
|
||||||
|
b := Buffer{
|
||||||
|
Layout: layout,
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.GenVertexArrays(1, &b.VAOID)
|
||||||
|
if b.VAOID == 0 {
|
||||||
logging.ErrLog.Println("Failed to create openGL vertex array object")
|
logging.ErrLog.Println("Failed to create openGL vertex array object")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &BufferObject{VAOID: vaoID}
|
gl.GenBuffers(1, &b.BufID)
|
||||||
|
if b.BufID == 0 {
|
||||||
|
logging.ErrLog.Println("Failed to create openGL buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.GenBuffers(1, &b.IndexBufID)
|
||||||
|
if b.IndexBufID == 0 {
|
||||||
|
logging.ErrLog.Println("Failed to create openGL buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
b.CalcValues()
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
package buffers
|
package buffers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bloeys/nmage/logging"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/bloeys/nmage/asserts"
|
||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,8 +28,6 @@ type DataTypeInfo struct {
|
|||||||
ElementCount int32
|
ElementCount int32
|
||||||
//ElementType is the type of each primitive (e.g. for vec3 its gl.FLOAT)
|
//ElementType is the type of each primitive (e.g. for vec3 its gl.FLOAT)
|
||||||
ElementType uint32
|
ElementType uint32
|
||||||
//GLType is the type of the variable represented (e.g. for vec3 its gl.FLOAT_VEC2)
|
|
||||||
GLType uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetSize returns the total size in bytes (e.g. for vec3 its 4*3)
|
//GetSize returns the total size in bytes (e.g. for vec3 its 4*3)
|
||||||
@ -45,7 +45,6 @@ func GetDataTypeInfo(dt DataType) DataTypeInfo {
|
|||||||
ElementSize: 4,
|
ElementSize: 4,
|
||||||
ElementCount: 1,
|
ElementCount: 1,
|
||||||
ElementType: gl.INT,
|
ElementType: gl.INT,
|
||||||
GLType: gl.INT,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case DataTypeFloat32:
|
case DataTypeFloat32:
|
||||||
@ -53,14 +52,12 @@ func GetDataTypeInfo(dt DataType) DataTypeInfo {
|
|||||||
ElementSize: 4,
|
ElementSize: 4,
|
||||||
ElementCount: 1,
|
ElementCount: 1,
|
||||||
ElementType: gl.FLOAT,
|
ElementType: gl.FLOAT,
|
||||||
GLType: gl.FLOAT,
|
|
||||||
}
|
}
|
||||||
case DataTypeFloat64:
|
case DataTypeFloat64:
|
||||||
return DataTypeInfo{
|
return DataTypeInfo{
|
||||||
ElementSize: 8,
|
ElementSize: 8,
|
||||||
ElementCount: 1,
|
ElementCount: 1,
|
||||||
ElementType: gl.DOUBLE,
|
ElementType: gl.DOUBLE,
|
||||||
GLType: gl.DOUBLE,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case DataTypeVec2:
|
case DataTypeVec2:
|
||||||
@ -68,25 +65,22 @@ func GetDataTypeInfo(dt DataType) DataTypeInfo {
|
|||||||
ElementSize: 4,
|
ElementSize: 4,
|
||||||
ElementCount: 2,
|
ElementCount: 2,
|
||||||
ElementType: gl.FLOAT,
|
ElementType: gl.FLOAT,
|
||||||
GLType: gl.FLOAT_VEC2,
|
|
||||||
}
|
}
|
||||||
case DataTypeVec3:
|
case DataTypeVec3:
|
||||||
return DataTypeInfo{
|
return DataTypeInfo{
|
||||||
ElementSize: 4,
|
ElementSize: 4,
|
||||||
ElementCount: 3,
|
ElementCount: 3,
|
||||||
ElementType: gl.FLOAT,
|
ElementType: gl.FLOAT,
|
||||||
GLType: gl.FLOAT_VEC3,
|
|
||||||
}
|
}
|
||||||
case DataTypeVec4:
|
case DataTypeVec4:
|
||||||
return DataTypeInfo{
|
return DataTypeInfo{
|
||||||
ElementSize: 4,
|
ElementSize: 4,
|
||||||
ElementCount: 4,
|
ElementCount: 4,
|
||||||
ElementType: gl.FLOAT,
|
ElementType: gl.FLOAT,
|
||||||
GLType: gl.FLOAT_VEC4,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logging.WarnLog.Println("Unknown data type passed. DataType:", dt)
|
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
||||||
return DataTypeInfo{}
|
return DataTypeInfo{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
main.go
18
main.go
@ -92,14 +92,7 @@ func main() {
|
|||||||
initImGUI()
|
initImGUI()
|
||||||
|
|
||||||
//Enable vertex attributes
|
//Enable vertex attributes
|
||||||
simpleMat.SetAttribute("vertPosIn", cubeMesh.BufObj, cubeMesh.BufObj.VertPosBuf)
|
simpleMat.SetAttribute(cubeMesh.BufObjV2)
|
||||||
simpleMat.EnableAttribute("vertPosIn")
|
|
||||||
|
|
||||||
simpleMat.SetAttribute("vertColorIn", cubeMesh.BufObj, cubeMesh.BufObj.ColorBuf)
|
|
||||||
simpleMat.EnableAttribute("vertColorIn")
|
|
||||||
|
|
||||||
simpleMat.SetAttribute("vertNormalIn", cubeMesh.BufObj, cubeMesh.BufObj.NormalBuf)
|
|
||||||
simpleMat.EnableAttribute("vertNormalIn")
|
|
||||||
|
|
||||||
//Movement, scale and rotation
|
//Movement, scale and rotation
|
||||||
translationMat := gglm.NewTranslationMat(gglm.NewVec3(0, 0, 0))
|
translationMat := gglm.NewTranslationMat(gglm.NewVec3(0, 0, 0))
|
||||||
@ -358,23 +351,20 @@ 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.BufObj.Bind()
|
cubeMesh.BufObjV2.Bind()
|
||||||
tempModelMat := modelMat.Clone()
|
tempModelMat := modelMat.Clone()
|
||||||
|
gl.BindBuffer(gl.ARRAY_BUFFER, cubeMesh.BufObjV2.BufID)
|
||||||
|
|
||||||
rowSize := 10
|
rowSize := 10
|
||||||
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, int32(cubeMesh.BufObj.IndexBuf.DataLen), gl.UNSIGNED_INT, gl.PtrOffset(0))
|
gl.DrawElements(gl.TRIANGLES, cubeMesh.BufObjV2.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)
|
||||||
}
|
}
|
||||||
|
|
||||||
simpleMat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
simpleMat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
||||||
cubeMesh.BufObj.UnBind()
|
|
||||||
|
|
||||||
drawUI()
|
|
||||||
|
|
||||||
window.SDLWin.GLSwap()
|
window.SDLWin.GLSwap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,16 +25,23 @@ func (m *Material) GetAttribLoc(attribName string) int32 {
|
|||||||
return gl.GetAttribLocation(m.ShaderProg.ID, gl.Str(attribName+"\x00"))
|
return gl.GetAttribLocation(m.ShaderProg.ID, gl.Str(attribName+"\x00"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Material) SetAttribute(attribName string, bufObj *buffers.BufferObject, buf *buffers.Buffer) {
|
func (m *Material) SetAttribute(bufObj buffers.Buffer) {
|
||||||
|
|
||||||
bufObj.Bind()
|
bufObj.Bind()
|
||||||
buf.Activate()
|
|
||||||
|
|
||||||
attribLoc := m.GetAttribLoc(attribName)
|
//NOTE: VBOs are only bound at 'VertexAttribPointer', not BindBUffer, so we need to bind the buffer and vao here
|
||||||
gl.VertexAttribPointer(uint32(attribLoc), buf.ElementCount, buf.ElementType, false, buf.GetSize(), gl.PtrOffset(0))
|
gl.BindBuffer(gl.ARRAY_BUFFER, bufObj.BufID)
|
||||||
|
|
||||||
bufObj.Bind()
|
for i := 0; i < len(bufObj.Layout.Elements); i++ {
|
||||||
buf.Deactivate()
|
|
||||||
|
gl.EnableVertexAttribArray(uint32(i))
|
||||||
|
|
||||||
|
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()
|
||||||
|
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Material) EnableAttribute(attribName string) {
|
func (m *Material) EnableAttribute(attribName string) {
|
||||||
|
|||||||
@ -11,8 +11,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Mesh struct {
|
type Mesh struct {
|
||||||
Name string
|
Name string
|
||||||
BufObj *buffers.BufferObject
|
BufObjV2 buffers.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh, error) {
|
func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh, error) {
|
||||||
@ -27,20 +27,79 @@ func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh,
|
|||||||
return nil, errors.New("No meshes found in file: " + modelPath)
|
return nil, errors.New("No meshes found in file: " + modelPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh := &Mesh{Name: name, BufObj: buffers.NewBufferObject()}
|
mesh := &Mesh{Name: name}
|
||||||
|
|
||||||
sceneMesh := scene.Meshes[0]
|
sceneMesh := scene.Meshes[0]
|
||||||
mesh.BufObj.GenBuffer(flattenVec3(sceneMesh.Normals), buffers.BufUsageStatic, buffers.BufTypeNormal, buffers.DataTypeVec3)
|
dataSize := len(sceneMesh.Vertices)*3 + len(sceneMesh.Normals)*3
|
||||||
mesh.BufObj.GenBuffer(flattenVec3(sceneMesh.Vertices), buffers.BufUsageStatic, buffers.BufTypeVertPos, buffers.DataTypeVec3)
|
|
||||||
mesh.BufObj.GenBufferUint32(flattenFaces(sceneMesh.Faces), buffers.BufUsageStatic, buffers.BufTypeIndex, buffers.DataTypeUint32)
|
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.BufObj.GenBuffer(flattenVec4(sceneMesh.ColorSets[0]), buffers.BufUsageStatic, buffers.BufTypeColor, buffers.DataTypeVec4)
|
mesh.BufObjV2.Layout.Elements = append(mesh.BufObjV2.Layout.Elements, buffers.BufferLayoutElement{DataType: buffers.DataTypeVec4})
|
||||||
|
dataSize += len(sceneMesh.ColorSets) * 4
|
||||||
|
mesh.BufObjV2.CalcValues()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
positions := flattenVec3(sceneMesh.Vertices)
|
||||||
|
normals := flattenVec3(sceneMesh.Normals)
|
||||||
|
colors := []float32{}
|
||||||
|
if len(sceneMesh.ColorSets) > 0 {
|
||||||
|
colors = flattenVec4(sceneMesh.ColorSets[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
var values []float32
|
||||||
|
if len(colors) > 0 {
|
||||||
|
values = interleave(
|
||||||
|
arrInfo{values: positions, valsPerComp: 3},
|
||||||
|
arrInfo{values: normals, valsPerComp: 3},
|
||||||
|
arrInfo{values: colors, valsPerComp: 4},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
values = interleave(
|
||||||
|
arrInfo{values: positions, valsPerComp: 3},
|
||||||
|
arrInfo{values: normals, valsPerComp: 3},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.BufObjV2.SetData(values)
|
||||||
|
mesh.BufObjV2.SetIndexBufData(flattenFaces(sceneMesh.Faces))
|
||||||
return mesh, nil
|
return mesh, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type arrInfo struct {
|
||||||
|
values []float32
|
||||||
|
valsPerComp int
|
||||||
|
}
|
||||||
|
|
||||||
|
func interleave(arrs ...arrInfo) []float32 {
|
||||||
|
|
||||||
|
if len(arrs) == 0 || len(arrs[0].values) == 0 {
|
||||||
|
panic("No input to interleave or arrays are empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
size := 0
|
||||||
|
for i := 0; i < len(arrs); i++ {
|
||||||
|
size += len(arrs[i].values)
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]float32, 0, size)
|
||||||
|
for posInArr := 0; posInArr < len(arrs[0].values)/arrs[0].valsPerComp; posInArr++ {
|
||||||
|
for arrToUse := 0; arrToUse < len(arrs); arrToUse++ {
|
||||||
|
for compToAdd := 0; compToAdd < arrs[arrToUse].valsPerComp; compToAdd++ {
|
||||||
|
|
||||||
|
out = append(out, arrs[arrToUse].values[posInArr*arrs[arrToUse].valsPerComp+compToAdd])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
func flattenVec3(vec3s []gglm.Vec3) []float32 {
|
func flattenVec3(vec3s []gglm.Vec3) []float32 {
|
||||||
|
|
||||||
floats := make([]float32, len(vec3s)*3)
|
floats := make([]float32, len(vec3s)*3)
|
||||||
@ -68,7 +127,7 @@ func flattenVec4(vec4s []gglm.Vec4) []float32 {
|
|||||||
|
|
||||||
func flattenFaces(faces []asig.Face) []uint32 {
|
func flattenFaces(faces []asig.Face) []uint32 {
|
||||||
|
|
||||||
asserts.True(len(faces[0].Indices) == 3, fmt.Sprintf("Face doesn't have 3 indices. Index count: %v\n", len(faces[0].Indices)))
|
asserts.T(len(faces[0].Indices) == 3, fmt.Sprintf("Face doesn't have 3 indices. Index count: %v\n", len(faces[0].Indices)))
|
||||||
|
|
||||||
uints := make([]uint32, len(faces)*3)
|
uints := make([]uint32, len(faces)*3)
|
||||||
for i := 0; i < len(faces); i++ {
|
for i := 0; i < len(faces); i++ {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
#version 410
|
#version 410
|
||||||
|
|
||||||
in vec3 vertPosIn;
|
layout(location=0) in vec3 vertPosIn;
|
||||||
in vec3 vertColorIn;
|
layout(location=1) in vec3 vertNormalIn;
|
||||||
in vec3 vertNormalIn;
|
layout(location=2) in vec3 vertColorIn;
|
||||||
|
|
||||||
out vec3 vertColor;
|
out vec3 vertColor;
|
||||||
out vec3 vertNormal;
|
out vec3 vertNormal;
|
||||||
|
|||||||
Reference in New Issue
Block a user