diff --git a/core/Ball.cpp b/core/Ball.cpp index 05ce039..abf78c0 100644 --- a/core/Ball.cpp +++ b/core/Ball.cpp @@ -1,6 +1,8 @@ #include "Ball.h" Ball::Ball() { + IndexList indices; + VertexList vertices; // It's a cube really // Front vertices.push_back(Vertex(1.0f, 1.0f, 1.0f, 0.0f, 1.0f)); @@ -31,5 +33,7 @@ Ball::Ball() { // Right side indices.push_back(Index(2, 3, 7)); indices.push_back(Index(2, 6, 7)); + + submeshes.push_back(new SubMesh(vertices, indices)); } diff --git a/core/Mesh.cpp b/core/Mesh.cpp index 8891d01..4dcb830 100644 --- a/core/Mesh.cpp +++ b/core/Mesh.cpp @@ -1,21 +1,15 @@ #include "Mesh.h" -Mesh::Mesh() { +SubMesh::SubMesh() { material = new Material(); } -Mesh::~Mesh() { - if (material) { - delete material; - } -} - -Mesh::Mesh(VertexList vertices, IndexList indices) { +SubMesh::SubMesh(VertexList vertices, IndexList indices) { this->vertices = vertices; this->indices = indices; } -void Mesh::SetupMesh() { +void SubMesh::SetupSubMesh() { glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); @@ -40,6 +34,32 @@ void Mesh::SetupMesh() { glBindVertexArray(0); } +void SubMesh::Draw(Shader *shader) { + shader->UpdateColor(material->usesColor, material->color); + shader->UpdateTex(material->usesTex, material->tex); + glBindVertexArray(VAO); + glDrawElements(GL_TRIANGLES, indices.size() * 3, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); +} + +Mesh::Mesh() {} + +Mesh::~Mesh() { + for (SubMesh *sub : submeshes) { + delete sub; + } +} + +void Mesh::SetupMesh() { + for (SubMesh *sub : submeshes) { + sub->SetupSubMesh(); + } +} + +void Mesh::SetMaterial(int submesh, Material *material) { + submeshes[submesh]->material = material; +} + Mesh* Mesh::FromFile(const char *filename) { // HOCUS: https://assimp-docs.readthedocs.io/en/latest/usage/use_the_lib.html Assimp::Importer importer; @@ -56,31 +76,34 @@ Mesh* Mesh::FromFile(const char *filename) { } aiNode *root = scene->mRootNode; - aiMesh *mesh_to_import = scene->mMeshes[root->mMeshes[0]]; + Mesh *my_mesh = new Mesh(); + for (int i = 0; i < root->mNumMeshes; i++) { + aiMesh *mesh_to_import = scene->mMeshes[root->mMeshes[i]]; + my_mesh->submeshes.push_back(aiMesh2SubMesh(mesh_to_import)); + } - return aiMesh2Mesh(mesh_to_import); + return my_mesh; } -Mesh *Mesh::aiMesh2Mesh(aiMesh *aimesh){ - Mesh *mymesh = new Mesh(); +SubMesh *Mesh::aiMesh2SubMesh(aiMesh *aimesh){ + SubMesh *sub = new SubMesh(); for (int i = 0; i < aimesh->mNumVertices; i++) { aiVector3D aiPosition = aimesh->mVertices[i]; aiVector3D aiUV = aimesh->mTextureCoords[0][i]; // TODO get ALL texture coords Vertex vertex(aiPosition.x, aiPosition.y, aiPosition.z, aiUV.x, aiUV.y); - mymesh->vertices.push_back(vertex); + sub->vertices.push_back(vertex); } for (int i = 0; i < aimesh->mNumFaces; i++) { // We're importing triangulated meshes, so each face is three indices unsigned int *face = aimesh->mFaces[i].mIndices; Index index(face[0], face[1], face[2]); - mymesh->indices.push_back(index); + sub->indices.push_back(index); } - return mymesh; + return sub; } - -void Mesh::Draw() { - glBindVertexArray(VAO); - glDrawElements(GL_TRIANGLES, indices.size() * 3, GL_UNSIGNED_INT, 0); - glBindVertexArray(0); +void Mesh::Draw(Shader *shader) { + for (SubMesh *sub : submeshes) { + sub->Draw(shader); + } } diff --git a/core/Mesh.h b/core/Mesh.h index 4353926..f045f55 100644 --- a/core/Mesh.h +++ b/core/Mesh.h @@ -2,8 +2,9 @@ #define MESH_H #include +#include -// Thirdpart includes +// Thirdparty includes #include #include #include @@ -15,21 +16,36 @@ #include "Index.h" #include "Material.h" -class Mesh : public Spatial { +#include "Shaders/Shader.h" + +class SubMesh { public: + SubMesh(); + SubMesh(VertexList vertices, IndexList indices); VertexList vertices; IndexList indices; Material *material; - Mesh(); - ~Mesh(); - Mesh(VertexList vertices, IndexList indices); - static Mesh *FromFile(const char *filename); - virtual bool IsDrawable() const {return true;} - virtual void Draw(); - virtual void SetupMesh(); + void SetupSubMesh(); + void Draw(Shader *shader); private: Id VAO, VBO, EBO; - static Mesh *aiMesh2Mesh(aiMesh *mesh); +}; + +typedef std::vector SubMeshList; + +class Mesh : public Spatial { +public: + Mesh(); + ~Mesh(); + void SetMaterial(int submesh, Material *material); + static Mesh *FromFile(const char *filename); + virtual bool IsDrawable() const {return true;} + virtual void Draw(Shader *shader); + virtual void SetupMesh(); +protected: + SubMeshList submeshes; +private: + static SubMesh *aiMesh2SubMesh(aiMesh *mesh); }; typedef std::list MeshList; diff --git a/core/Shaders/FlatShader.cpp b/core/Shaders/FlatShader.cpp index 70e4f57..1030b87 100644 --- a/core/Shaders/FlatShader.cpp +++ b/core/Shaders/FlatShader.cpp @@ -3,7 +3,3 @@ #include "flat.frag.h" FlatShader::FlatShader() : Shader(flat_vert, flat_frag) {} - -void FlatShader::UpdateColor(Vector3 color) { - glUniform3f(glGetUniformLocation(id, "color"), color.r, color.g, color.b); -} diff --git a/core/Shaders/FlatShader.h b/core/Shaders/FlatShader.h index 165b58f..dd0e90b 100644 --- a/core/Shaders/FlatShader.h +++ b/core/Shaders/FlatShader.h @@ -1,7 +1,12 @@ +#ifndef FLATSHADER_H +#define FLATSHADER_H + #include "Shader.h" class FlatShader : public Shader { public: FlatShader(); - void UpdateColor(Vector3 color); }; + +#endif /* FLATSHADER_H */ + diff --git a/core/couch.cpp b/core/couch.cpp index 0a8d12d..990610c 100644 --- a/core/couch.cpp +++ b/core/couch.cpp @@ -41,17 +41,7 @@ void render(Node *curr, Shader *shader, Matrix model) { shader->UpdateModel(model); } Mesh *mesh = dynamic_cast(curr); - if (mesh->material->usesColor) { - shader->UpdateColor(true, mesh->material->color); - } else { - shader->UpdateColor(false); - } - if (mesh->material->usesTex) { - shader->UpdateTex(true, mesh->material->tex); - } else { - shader->UpdateTex(false); - } - mesh->Draw(); + mesh->Draw(shader); } for (Node *child : curr->children) { render(child, shader, model); @@ -85,9 +75,6 @@ int main() { glViewport(0, 0, width, height); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - root = Node::GetRoot(); Input *input = Input::GetInstance(); diff --git a/demo/main.lua b/demo/main.lua index 44aa2b8..8a7fc26 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -24,33 +24,47 @@ local RED = couch.Color(1.0, 0.0, 0.0) local BLUE = couch.Color(0.0, 0.0, 1.0) function init() + local material + camera = couch.Camera() camera:MakeCurrent() camera.transform:Translate(0.0, 0.0, 10.0) ball = couch.Ball() ball:SetupMesh() - ball.material.color = RED - ball.material.usesColor = true + material = couch.Material.new() + material.color = RED + material.usesColor = true + ball:SetMaterial(0, material) couch.Node.GetRoot().children:Append(ball) ball1 = couch.Ball() ball1:SetupMesh() - ball1.material.tex = couch.Texture.FromFile("container.png") - ball1.material.usesTex = true + material = couch.Material.new() + material.tex = couch.Texture.FromFile("container.png") + material.usesTex = true + ball1:SetMaterial(0, material) couch.Node.GetRoot().children:Append(ball1) ball1.transform:Translate(0.0, 3.0, 0.0) trough = couch.Mesh.FromFile("trough.glb") trough:SetupMesh() - trough.material.tex = couch.Texture.FromFile("wood_lowres.png") - trough.material.usesTex = true + material = couch.Material.new() + material.tex = couch.Texture.FromFile("wood_lowres.png") + material.usesTex = true + trough:SetMaterial(0, material) couch.Node.GetRoot().children:Append(trough) trough.transform:Translate(10.0, 0.0, 0.0) scaffold = couch.Mesh.FromFile("scaffold.glb") scaffold:SetupMesh() - scaffold.material.tex = couch.Texture.FromFile("grate_floor_lowres.png") - scaffold.material.usesTex = true + material = couch.Material.new() + material.tex = couch.Texture.FromFile("grate_floor_lowres.png") + material.usesTex = true + scaffold:SetMaterial(0, material) + material = couch.Material.new() + material.tex = couch.Texture.FromFile("railing.png") + material.usesTex = true + scaffold:SetMaterial(1, material) couch.Node.GetRoot().children:Append(scaffold) scaffold.transform:Translate(-10.0, 0.0, 0.0) end diff --git a/demo/railing.png b/demo/railing.png new file mode 100644 index 0000000..f7aaa57 Binary files /dev/null and b/demo/railing.png differ diff --git a/scripting/couch.i b/scripting/couch.i index ee14760..07691a4 100644 --- a/scripting/couch.i +++ b/scripting/couch.i @@ -7,12 +7,14 @@ #include "Node.h" #include "Transform.h" #include "Spatial.h" -#include "Material.h" #include "Mesh.h" #include "Ball.h" +#include "Material.h" #include "Camera.h" %} +%rename("%(strip:[script_])s") ""; + typedef float cfloat; %ignore "cfloat"; @@ -21,6 +23,7 @@ public: Vector3(); cfloat x, y, z; }; + %extend Vector3 { Vector3 operator+(const Vector3 &o) const { return *$self + o; @@ -31,12 +34,18 @@ public: } %ignore "Vector3"; +%extend Material { + static Material* Material::script_new() { + return new Material(); + } +} + %include "types.h" %include "Node.h" %include "Spatial.h" -%include "Transform.h" -%include "Material.h" %include "Mesh.h" %include "Ball.h" +%include "Transform.h" +%include "Material.h" %include "Camera.h"