diff --git a/buffers/buffers.go b/buffers/buffers.go index 21d39f5..4ac8942 100755 --- a/buffers/buffers.go +++ b/buffers/buffers.go @@ -10,9 +10,9 @@ type Buffer struct { //BufID is the ID of the VBO BufID uint32 //IndexBufID is the ID of the index/element buffer - IndexBufID uint32 - IndexBufCount int32 - Stride int32 + IndexBufID uint32 + // 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() diff --git a/main.go b/main.go index e69fceb..d15703a 100755 --- a/main.go +++ b/main.go @@ -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)) diff --git a/meshes/mesh.go b/meshes/mesh.go index 3ec4900..19dbdfc 100755 --- a/meshes/mesh.go +++ b/meshes/mesh.go @@ -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 + 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() - - if len(sceneMesh.TexCoords[0]) == 0 { - sceneMesh.TexCoords[0] = make([]gglm.Vec3, len(sceneMesh.Vertices)) + mesh := &Mesh{ + Name: name, + Buf: buffers.NewBuffer(), + SubMeshes: make([]SubMesh, 0, 1), } - layoutToUse := []buffers.Element{{ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec2}} + // 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) - if len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0 { - layoutToUse = append(layoutToUse, buffers.Element{ElementType: buffers.DataTypeVec4}) - } - mesh.Buf.SetLayout(layoutToUse...) + for i := 0; i < len(scene.Meshes); i++ { - var values []float32 - arrs := []arrToInterleave{{V3s: sceneMesh.Vertices}, {V3s: sceneMesh.Normals}, {V2s: v3sToV2s(sceneMesh.TexCoords[0])}} + sceneMesh := scene.Meshes[i] - if len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0 { - arrs = append(arrs, arrToInterleave{V4s: sceneMesh.ColorSets[0]}) + 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)) + } + } + } + + 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]}) + } + + indices := flattenFaces(sceneMesh.Faces) + mesh.SubMeshes = append(mesh.SubMeshes, SubMesh{ + + // 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...) } - values = interleave(arrs...) - - mesh.Buf.SetData(values) - mesh.Buf.SetIndexBufData(flattenFaces(sceneMesh.Faces)) + // 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 } diff --git a/renderer/rend3dgl/rend3dgl.go b/renderer/rend3dgl/rend3dgl.go index e68c766..a90ad95 100755 --- a/renderer/rend3dgl/rend3dgl.go +++ b/renderer/rend3dgl/rend3dgl.go @@ -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() {