Basic submeshe support

This commit is contained in:
bloeys
2022-10-07 05:50:48 +04:00
parent 1b858bd4ac
commit 3071b52c85
4 changed files with 78 additions and 31 deletions

View File

@ -11,7 +11,7 @@ type Buffer struct {
BufID uint32
//IndexBufID is the ID of the index/element buffer
IndexBufID uint32
IndexBufCount int32
// IndexBufCount int32
Stride int32
layout []Element
@ -59,7 +59,7 @@ func (b *Buffer) SetDataWithUsage(values []float32, usage BufUsage) {
func (b *Buffer) SetIndexBufData(values []uint32) {
b.IndexBufCount = int32(len(values))
// b.IndexBufCount = int32(len(values))
gl.BindVertexArray(b.VAOID)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, b.IndexBufID)
@ -101,7 +101,7 @@ func (b *Buffer) SetLayout(layout ...Element) {
for i := 0; i < len(layout); i++ {
gl.EnableVertexAttribArray(uint32(i))
gl.VertexAttribPointer(uint32(i), layout[i].ElementType.CompCount(), layout[i].ElementType.GLType(), false, b.Stride, gl.PtrOffset(layout[i].Offset))
gl.VertexAttribPointerWithOffset(uint32(i), layout[i].ElementType.CompCount(), layout[i].ElementType.GLType(), false, b.Stride, uintptr(layout[i].Offset))
}
b.UnBind()

View File

@ -3,7 +3,6 @@ package main
import (
"fmt"
"github.com/bloeys/assimp-go/asig"
"github.com/bloeys/gglm/gglm"
"github.com/bloeys/nmage/assets"
"github.com/bloeys/nmage/camera"
@ -153,7 +152,8 @@ func (g *OurGame) Init() {
//Load meshes
var err error
cubeMesh, err = meshes.NewMesh("Cube", "./res/models/tex-cube.fbx", asig.PostProcess(0))
// cubeMesh, err = meshes.NewMesh("Cube", "./res/models/Wolf.fbx", 0)
cubeMesh, err = meshes.NewMesh("Cube", "./res/models/tex-cube.fbx", 0)
if err != nil {
logging.ErrLog.Fatalln("Failed to load cube mesh. Err: ", err)
}
@ -181,7 +181,7 @@ func (g *OurGame) Init() {
gglm.NewVec3(0, 0, 10),
gglm.NewVec3(0, 0, -1),
gglm.NewVec3(0, 1, 0),
0.1, 20,
0.1, 200,
45*gglm.Deg2Rad,
float32(winWidth)/float32(winHeight),
)
@ -292,8 +292,9 @@ func (g *OurGame) updateCameraPos() {
func (g *OurGame) Render() {
tempModelMat := cubeModelMat.Clone()
// window.Rend.Draw(cubeMesh, tempModelMat, simpleMat)
rowSize := 100
rowSize := 10
for y := 0; y < rowSize; y++ {
for x := 0; x < rowSize; x++ {
tempModelMat.Translate(gglm.NewVec3(-1, 0, 0))

View File

@ -10,9 +10,16 @@ import (
"github.com/bloeys/nmage/buffers"
)
type SubMesh struct {
BaseVertex int32
BaseIndex uint32
IndexCount int32
}
type Mesh struct {
Name string
Buf buffers.Buffer
SubMeshes []SubMesh
}
func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh, error) {
@ -27,32 +34,68 @@ func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh,
return nil, errors.New("No meshes found in file: " + modelPath)
}
mesh := &Mesh{Name: name}
sceneMesh := scene.Meshes[0]
mesh.Buf = buffers.NewBuffer()
mesh := &Mesh{
Name: name,
Buf: buffers.NewBuffer(),
SubMeshes: make([]SubMesh, 0, 1),
}
// Initial sizes assuming one submesh that has vertex pos+normals+texCoords, and 3 indices per face
var vertexBufData []float32 = make([]float32, 0, len(scene.Meshes[0].Vertices)*3*3*2)
var indexBufData []uint32 = make([]uint32, 0, len(scene.Meshes[0].Faces)*3)
for i := 0; i < len(scene.Meshes); i++ {
sceneMesh := scene.Meshes[i]
if len(sceneMesh.TexCoords[0]) == 0 {
sceneMesh.TexCoords[0] = make([]gglm.Vec3, len(sceneMesh.Vertices))
println("Zeroing tex coords for submesh", i)
}
layoutToUse := []buffers.Element{{ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec2}}
if len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0 {
layoutToUse = append(layoutToUse, buffers.Element{ElementType: buffers.DataTypeVec4})
}
if i == 0 {
mesh.Buf.SetLayout(layoutToUse...)
} else {
// @NOTE: Require that all submeshes have the same vertex buffer layout
firstSubmeshLayout := mesh.Buf.GetLayout()
assert.T(len(firstSubmeshLayout) == len(layoutToUse), fmt.Sprintf("Vertex layout of submesh %d does not equal vertex layout of the first submesh. Original layout: %v; This layout: %v", i, firstSubmeshLayout, layoutToUse))
for i := 0; i < len(firstSubmeshLayout); i++ {
if firstSubmeshLayout[i].ElementType != layoutToUse[i].ElementType {
panic(fmt.Sprintf("Vertex layout of submesh %d does not equal vertex layout of the first submesh. Original layout: %v; This layout: %v", i, firstSubmeshLayout, layoutToUse))
}
}
}
var values []float32
arrs := []arrToInterleave{{V3s: sceneMesh.Vertices}, {V3s: sceneMesh.Normals}, {V2s: v3sToV2s(sceneMesh.TexCoords[0])}}
if len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0 {
arrs = append(arrs, arrToInterleave{V4s: sceneMesh.ColorSets[0]})
}
values = interleave(arrs...)
indices := flattenFaces(sceneMesh.Faces)
mesh.SubMeshes = append(mesh.SubMeshes, SubMesh{
mesh.Buf.SetData(values)
mesh.Buf.SetIndexBufData(flattenFaces(sceneMesh.Faces))
// Index of the vertex to start from (e.g. if index buffer says use vertex 5, and BaseVertex=3, the vertex used will be vertex 8)
BaseVertex: int32(len(vertexBufData)*4) / mesh.Buf.Stride,
// Which index (in the index buffer) to start from
BaseIndex: uint32(len(indexBufData)),
// How many indices in this submesh
IndexCount: int32(len(indices)),
})
vertexBufData = append(vertexBufData, interleave(arrs...)...)
indexBufData = append(indexBufData, indices...)
}
// fmt.Printf("!!! Vertex count: %d; Submeshes: %+v\n", len(vertexBufData)*4/int(mesh.Buf.Stride), mesh.SubMeshes)
mesh.Buf.SetData(vertexBufData)
mesh.Buf.SetIndexBufData(indexBufData)
return mesh, nil
}

View File

@ -28,7 +28,10 @@ func (r3d *Rend3DGL) Draw(mesh *meshes.Mesh, trMat *gglm.TrMat, mat *materials.M
}
mat.SetUnifMat4("modelMat", &trMat.Mat4)
gl.DrawElements(gl.TRIANGLES, mesh.Buf.IndexBufCount, gl.UNSIGNED_INT, gl.PtrOffset(0))
for i := 0; i < len(mesh.SubMeshes); i++ {
gl.DrawElementsBaseVertexWithOffset(gl.TRIANGLES, mesh.SubMeshes[i].IndexCount, gl.UNSIGNED_INT, uintptr(mesh.SubMeshes[i].BaseIndex), mesh.SubMeshes[i].BaseVertex)
}
}
func (r3d *Rend3DGL) FrameEnd() {