diff --git a/src/gpu/shader.cpp b/src/gpu/shader.cpp index 555d7582..8f48a93e 100644 --- a/src/gpu/shader.cpp +++ b/src/gpu/shader.cpp @@ -401,6 +401,11 @@ Shader::Shader(char const *vert, char const *frag) #endif } +int Shader::GetAttribCount() const +{ + return data->attrib_locations.Count(); +} + ShaderAttrib Shader::GetAttribLocation(VertexUsage usage, int index) const { ShaderAttrib ret; diff --git a/src/lol/gpu/shader.h b/src/lol/gpu/shader.h index cb93ea00..793b20da 100644 --- a/src/lol/gpu/shader.h +++ b/src/lol/gpu/shader.h @@ -157,6 +157,7 @@ public: static Shader *Create(char const *lolfx); static void Destroy(Shader *shader); + int GetAttribCount() const; ShaderAttrib GetAttribLocation(struct VertexUsage usage, int index) const; ShaderUniform GetUniformLocation(char const *uni) const; diff --git a/src/mesh/mesh.cpp b/src/mesh/mesh.cpp index 14254f0e..7d4fe264 100644 --- a/src/mesh/mesh.cpp +++ b/src/mesh/mesh.cpp @@ -20,6 +20,10 @@ namespace lol { +/* + * Mesh class + */ + Mesh::Mesh() { } @@ -30,21 +34,83 @@ Mesh::~Mesh() void Mesh::Render(mat4 const &model) { - for (int i = 0; i < m_submeshes.Count(); ++i) - m_submeshes[i]->Render(model); + //for (int i = 0; i < m_submeshes.Count(); ++i) + // m_submeshes[i]->Render(model); } -SubMesh::SubMesh() +/* + * SubMesh class + */ + +SubMesh::SubMesh(lol::VertexDeclaration* vdecl) + : m_mesh_prim(MeshPrimitive::Triangles) { + m_vdecl = vdecl; + m_vbos = new VertexBuffer*[vdecl->GetStreamCount()]; + memset(m_vbos, 0, sizeof(VertexBuffer*) * vdecl->GetStreamCount()); + m_vertex_count = -1; } SubMesh::~SubMesh() { + // TODO: cleanup +} + +void SubMesh::SetMeshPrimitive(MeshPrimitive mesh_primitive) +{ + m_mesh_prim = mesh_primitive; +} + +void SubMesh::SetVertexBuffer(int index, VertexBuffer* vbo) +{ + m_vbos[index] = vbo; + if (m_vertex_count < 0) + m_vertex_count = vbo->GetSize() / m_vdecl->GetStream(index).GetSize(); +} + +void SubMesh::AddTexture(const char* name, Texture* texture) +{ + m_textures.Push(String(name), texture); } -void SubMesh::Render(mat4 const &model) +void SubMesh::Render(Shader* shader) { - /* FIXME: TODO */ + ShaderAttrib attribs[12]; + + int c = 0; + for (int i = 0; i < m_vdecl->GetStreamCount(); ++i) + { + ShaderAttrib attribs[12]; + + if (m_vbos[i] == nullptr) + { + Log::Error("trying to render a mesh with a null vbo"); + return; + } + + int indices[VertexUsage::Max]; + memset(indices, 0, sizeof(int) * VertexUsage::Max); + + VertexStreamBase stream = m_vdecl->GetStream(i); + for (int j = 0; j < stream.GetStreamCount(); ++j) + { + VertexUsage usage = stream.GetUsage(j); + attribs[j] = shader->GetAttribLocation(usage, indices[usage]++); + } + + m_vdecl->SetStream(m_vbos[i], attribs); + } + + for (int i = 0; i < m_textures.Count(); ++i) + { + // TODO: might be good to cache this + ShaderUniform uniform = shader->GetUniformLocation(m_textures[i].m1.C()); + shader->SetUniform(uniform, m_textures[i].m2->GetTexture(), i); + } + + m_vdecl->Bind(); + m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, m_vertex_count); + m_vdecl->Unbind(); } } /* namespace lol */ diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h index 8636ec43..4101ee95 100644 --- a/src/mesh/mesh.h +++ b/src/mesh/mesh.h @@ -22,15 +22,22 @@ namespace lol class SubMesh { public: - SubMesh(); + SubMesh(VertexDeclaration* vdecl); ~SubMesh(); - void Render(mat4 const &model); + void SetMeshPrimitive(MeshPrimitive mesh_primitive); + void SetVertexBuffer(int index, VertexBuffer* vbo); + void AddTexture(const char* name, Texture* texture); -private: - Array m_vertices; - Array m_uvs; - Array m_normals; + void Render(Shader* shader); + +protected: + VertexDeclaration* m_vdecl; + MeshPrimitive m_mesh_prim; + VertexBuffer** m_vbos; + int m_vertex_count; + + Array m_textures; }; class Mesh