Can add models with multiple textures

This commit is contained in:
Dane Johnson 2021-01-20 14:54:54 -06:00
parent 667b80b074
commit d655b52aa2
9 changed files with 115 additions and 61 deletions

View File

@ -1,6 +1,8 @@
#include "Ball.h" #include "Ball.h"
Ball::Ball() { Ball::Ball() {
IndexList indices;
VertexList vertices;
// It's a cube really // It's a cube really
// Front // Front
vertices.push_back(Vertex(1.0f, 1.0f, 1.0f, 0.0f, 1.0f)); vertices.push_back(Vertex(1.0f, 1.0f, 1.0f, 0.0f, 1.0f));
@ -31,5 +33,7 @@ Ball::Ball() {
// Right side // Right side
indices.push_back(Index(2, 3, 7)); indices.push_back(Index(2, 3, 7));
indices.push_back(Index(2, 6, 7)); indices.push_back(Index(2, 6, 7));
submeshes.push_back(new SubMesh(vertices, indices));
} }

View File

@ -1,21 +1,15 @@
#include "Mesh.h" #include "Mesh.h"
Mesh::Mesh() { SubMesh::SubMesh() {
material = new Material(); material = new Material();
} }
Mesh::~Mesh() { SubMesh::SubMesh(VertexList vertices, IndexList indices) {
if (material) {
delete material;
}
}
Mesh::Mesh(VertexList vertices, IndexList indices) {
this->vertices = vertices; this->vertices = vertices;
this->indices = indices; this->indices = indices;
} }
void Mesh::SetupMesh() { void SubMesh::SetupSubMesh() {
glGenVertexArrays(1, &VAO); glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO); glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO); glGenBuffers(1, &EBO);
@ -40,6 +34,32 @@ void Mesh::SetupMesh() {
glBindVertexArray(0); 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) { Mesh* Mesh::FromFile(const char *filename) {
// HOCUS: https://assimp-docs.readthedocs.io/en/latest/usage/use_the_lib.html // HOCUS: https://assimp-docs.readthedocs.io/en/latest/usage/use_the_lib.html
Assimp::Importer importer; Assimp::Importer importer;
@ -56,31 +76,34 @@ Mesh* Mesh::FromFile(const char *filename) {
} }
aiNode *root = scene->mRootNode; 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){ SubMesh *Mesh::aiMesh2SubMesh(aiMesh *aimesh){
Mesh *mymesh = new Mesh(); SubMesh *sub = new SubMesh();
for (int i = 0; i < aimesh->mNumVertices; i++) { for (int i = 0; i < aimesh->mNumVertices; i++) {
aiVector3D aiPosition = aimesh->mVertices[i]; aiVector3D aiPosition = aimesh->mVertices[i];
aiVector3D aiUV = aimesh->mTextureCoords[0][i]; // TODO get ALL texture coords aiVector3D aiUV = aimesh->mTextureCoords[0][i]; // TODO get ALL texture coords
Vertex vertex(aiPosition.x, aiPosition.y, aiPosition.z, aiUV.x, aiUV.y); 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++) { for (int i = 0; i < aimesh->mNumFaces; i++) {
// We're importing triangulated meshes, so each face is three indices // We're importing triangulated meshes, so each face is three indices
unsigned int *face = aimesh->mFaces[i].mIndices; unsigned int *face = aimesh->mFaces[i].mIndices;
Index index(face[0], face[1], face[2]); 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(Shader *shader) {
void Mesh::Draw() { for (SubMesh *sub : submeshes) {
glBindVertexArray(VAO); sub->Draw(shader);
glDrawElements(GL_TRIANGLES, indices.size() * 3, GL_UNSIGNED_INT, 0); }
glBindVertexArray(0);
} }

View File

@ -2,8 +2,9 @@
#define MESH_H #define MESH_H
#include <list> #include <list>
#include <vector>
// Thirdpart includes // Thirdparty includes
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
@ -15,21 +16,36 @@
#include "Index.h" #include "Index.h"
#include "Material.h" #include "Material.h"
class Mesh : public Spatial { #include "Shaders/Shader.h"
class SubMesh {
public: public:
SubMesh();
SubMesh(VertexList vertices, IndexList indices);
VertexList vertices; VertexList vertices;
IndexList indices; IndexList indices;
Material *material; Material *material;
Mesh(); void SetupSubMesh();
~Mesh(); void Draw(Shader *shader);
Mesh(VertexList vertices, IndexList indices);
static Mesh *FromFile(const char *filename);
virtual bool IsDrawable() const {return true;}
virtual void Draw();
virtual void SetupMesh();
private: private:
Id VAO, VBO, EBO; Id VAO, VBO, EBO;
static Mesh *aiMesh2Mesh(aiMesh *mesh); };
typedef std::vector<SubMesh*> 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<Mesh*> MeshList; typedef std::list<Mesh*> MeshList;

View File

@ -3,7 +3,3 @@
#include "flat.frag.h" #include "flat.frag.h"
FlatShader::FlatShader() : Shader(flat_vert, flat_frag) {} FlatShader::FlatShader() : Shader(flat_vert, flat_frag) {}
void FlatShader::UpdateColor(Vector3 color) {
glUniform3f(glGetUniformLocation(id, "color"), color.r, color.g, color.b);
}

View File

@ -1,7 +1,12 @@
#ifndef FLATSHADER_H
#define FLATSHADER_H
#include "Shader.h" #include "Shader.h"
class FlatShader : public Shader { class FlatShader : public Shader {
public: public:
FlatShader(); FlatShader();
void UpdateColor(Vector3 color);
}; };
#endif /* FLATSHADER_H */

View File

@ -41,17 +41,7 @@ void render(Node *curr, Shader *shader, Matrix model) {
shader->UpdateModel(model); shader->UpdateModel(model);
} }
Mesh *mesh = dynamic_cast<Mesh*>(curr); Mesh *mesh = dynamic_cast<Mesh*>(curr);
if (mesh->material->usesColor) { mesh->Draw(shader);
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();
} }
for (Node *child : curr->children) { for (Node *child : curr->children) {
render(child, shader, model); render(child, shader, model);
@ -85,9 +75,6 @@ int main() {
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
root = Node::GetRoot(); root = Node::GetRoot();
Input *input = Input::GetInstance(); Input *input = Input::GetInstance();

View File

@ -24,33 +24,47 @@ local RED = couch.Color(1.0, 0.0, 0.0)
local BLUE = couch.Color(0.0, 0.0, 1.0) local BLUE = couch.Color(0.0, 0.0, 1.0)
function init() function init()
local material
camera = couch.Camera() camera = couch.Camera()
camera:MakeCurrent() camera:MakeCurrent()
camera.transform:Translate(0.0, 0.0, 10.0) camera.transform:Translate(0.0, 0.0, 10.0)
ball = couch.Ball() ball = couch.Ball()
ball:SetupMesh() ball:SetupMesh()
ball.material.color = RED material = couch.Material.new()
ball.material.usesColor = true material.color = RED
material.usesColor = true
ball:SetMaterial(0, material)
couch.Node.GetRoot().children:Append(ball) couch.Node.GetRoot().children:Append(ball)
ball1 = couch.Ball() ball1 = couch.Ball()
ball1:SetupMesh() ball1:SetupMesh()
ball1.material.tex = couch.Texture.FromFile("container.png") material = couch.Material.new()
ball1.material.usesTex = true material.tex = couch.Texture.FromFile("container.png")
material.usesTex = true
ball1:SetMaterial(0, material)
couch.Node.GetRoot().children:Append(ball1) couch.Node.GetRoot().children:Append(ball1)
ball1.transform:Translate(0.0, 3.0, 0.0) ball1.transform:Translate(0.0, 3.0, 0.0)
trough = couch.Mesh.FromFile("trough.glb") trough = couch.Mesh.FromFile("trough.glb")
trough:SetupMesh() trough:SetupMesh()
trough.material.tex = couch.Texture.FromFile("wood_lowres.png") material = couch.Material.new()
trough.material.usesTex = true material.tex = couch.Texture.FromFile("wood_lowres.png")
material.usesTex = true
trough:SetMaterial(0, material)
couch.Node.GetRoot().children:Append(trough) couch.Node.GetRoot().children:Append(trough)
trough.transform:Translate(10.0, 0.0, 0.0) trough.transform:Translate(10.0, 0.0, 0.0)
scaffold = couch.Mesh.FromFile("scaffold.glb") scaffold = couch.Mesh.FromFile("scaffold.glb")
scaffold:SetupMesh() scaffold:SetupMesh()
scaffold.material.tex = couch.Texture.FromFile("grate_floor_lowres.png") material = couch.Material.new()
scaffold.material.usesTex = true 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) couch.Node.GetRoot().children:Append(scaffold)
scaffold.transform:Translate(-10.0, 0.0, 0.0) scaffold.transform:Translate(-10.0, 0.0, 0.0)
end end

BIN
demo/railing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -7,12 +7,14 @@
#include "Node.h" #include "Node.h"
#include "Transform.h" #include "Transform.h"
#include "Spatial.h" #include "Spatial.h"
#include "Material.h"
#include "Mesh.h" #include "Mesh.h"
#include "Ball.h" #include "Ball.h"
#include "Material.h"
#include "Camera.h" #include "Camera.h"
%} %}
%rename("%(strip:[script_])s") "";
typedef float cfloat; typedef float cfloat;
%ignore "cfloat"; %ignore "cfloat";
@ -21,6 +23,7 @@ public:
Vector3(); Vector3();
cfloat x, y, z; cfloat x, y, z;
}; };
%extend Vector3 { %extend Vector3 {
Vector3 operator+(const Vector3 &o) const { Vector3 operator+(const Vector3 &o) const {
return *$self + o; return *$self + o;
@ -31,12 +34,18 @@ public:
} }
%ignore "Vector3"; %ignore "Vector3";
%extend Material {
static Material* Material::script_new() {
return new Material();
}
}
%include "types.h" %include "types.h"
%include "Node.h" %include "Node.h"
%include "Spatial.h" %include "Spatial.h"
%include "Transform.h"
%include "Material.h"
%include "Mesh.h" %include "Mesh.h"
%include "Ball.h" %include "Ball.h"
%include "Transform.h"
%include "Material.h"
%include "Camera.h" %include "Camera.h"