Correctly render mesh from obj

This commit is contained in:
karl 2020-01-14 12:53:31 +01:00
parent 65f0e3367b
commit 1824b0c38c
7 changed files with 2219 additions and 97 deletions

View File

@ -7,7 +7,7 @@ find_package(OpenGL REQUIRED)
find_package(glfw3 REQUIRED)
find_package(glm REQUIRED)
add_executable(ecsgame Util/glad.c Util/OBJ_Loader.h Rendering/Shader.cpp Rendering/Shader.h main.cpp ECS/Components/Transform.h ECS/Components/Movement.h ECS/Events/InputEvent.h ECS/Events/MouseMoveEvent.h ECS/Systems/GravitySystem.h ECS/Systems/PositionDebugSystem.h ECS/Systems/KeyboardMovementSystem.h ECS/Components/Camera.h ECS/Systems/RenderSystem.h ECS/Components/Mesh.h ECS/Systems/MouseLookSystem.h ECS/Components/MouseLook.h)
add_executable(ecsgame Util/glad.c Util/OBJ_Loader.h Rendering/Shader.cpp Rendering/Shader.h main.cpp ECS/Components/Transform.h ECS/Components/Movement.h ECS/Events/InputEvent.h ECS/Events/MouseMoveEvent.h ECS/Systems/GravitySystem.h ECS/Systems/PositionDebugSystem.h ECS/Systems/KeyboardMovementSystem.h ECS/Components/Camera.h ECS/Systems/RenderSystem.h ECS/Components/Mesh.h ECS/Systems/MouseLookSystem.h ECS/Components/MouseLook.h ECS/Components/ObjMesh.h)
include_directories(${OPENGL_INCLUDE_DIRS})

View File

@ -10,14 +10,18 @@
#include <vector>
struct Mesh {
explicit Mesh(const std::vector<float> &_vertices) : vertex_count(_vertices.size()) {
explicit Mesh(const std::vector<float> &_vertices, const std::vector<unsigned int> &_indices) : vertex_count(_indices.size()) {
// Copy the vertices into a local classic float array. Nothing was displayed without this, maybe
// due to weird hidden type incompatibility or out of scope issues?
float vertices[vertex_count];
float vertices[_vertices.size()];
std::copy(_vertices.begin(), _vertices.end(), vertices);
unsigned int indices[_indices.size()];
std::copy(_indices.begin(), _indices.end(), indices);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray(VAO);
@ -25,21 +29,32 @@ struct Mesh {
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
// Normal attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
}
void render() {
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, vertex_count);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glDrawElements(GL_TRIANGLES, vertex_count, GL_UNSIGNED_INT, 0);
}
private:
unsigned int EBO;
unsigned int VBO;
unsigned int VAO;
unsigned int vertex_count;

106
ECS/Components/ObjMesh.h Normal file
View File

@ -0,0 +1,106 @@
//
// Created by karl on 12.01.20.
//
#ifndef ECSGAME_OBJMESH_H
#define ECSGAME_OBJMESH_H
#include "Mesh.h"
#include "../../Util/OBJ_Loader.h"
struct ObjMesh : public Mesh {
explicit ObjMesh(const std::string &path) : Mesh(getVerticesFromFile(path), getIndicesFromFile(path)) {}
private:
static std::vector<float> getVerticesFromFile(const std::string &path) {
objl::Loader loader;
bool loadout = loader.LoadFile(path);
if (loadout) {
// TODO: Currently only the first mesh is used
objl::Mesh curMesh = loader.LoadedMeshes[0];
std::vector<float> vertexData = std::vector<float>();
// Go through each vertex
for (auto &Vertice : curMesh.Vertices) {
vertexData.emplace_back(Vertice.Position.X);
vertexData.emplace_back(Vertice.Position.Y);
vertexData.emplace_back(Vertice.Position.Z);
vertexData.emplace_back(Vertice.Normal.X);
vertexData.emplace_back(Vertice.Normal.Y);
vertexData.emplace_back(Vertice.Normal.Z);
vertexData.emplace_back(Vertice.TextureCoordinate.X);
vertexData.emplace_back(Vertice.TextureCoordinate.Y);
}
return vertexData;
} else {
// Output Error
std::cout << "Failed to Load File. May have failed to find it or it was not an .obj file.\n";
}
}
static std::vector<unsigned int> getIndicesFromFile(const std::string &path) {
objl::Loader loader;
bool loadout = loader.LoadFile(path);
if (loadout) {
// TODO: Currently only the first mesh is used
objl::Mesh curMesh = loader.LoadedMeshes[0];
std::vector<unsigned int> indices = std::vector<unsigned int>();
// Emplace indices into the float vector
for (int j = 0; j < curMesh.Indices.size(); j++) {
indices.emplace_back(curMesh.Indices[j]);
}
return indices;
} else {
// Output Error
std::cout << "Failed to Load File. May have failed to find it or it was not an .obj file.\n";
}
}
// TODO: Only prints at the moment
static std::vector<float> getMaterialFromFile(const std::string &path) {
objl::Loader loader;
bool loadout = loader.LoadFile(path);
if (loadout) {
// TODO: Currently only the first mesh is used
objl::Mesh curMesh = loader.LoadedMeshes[0];
std::vector<float> vertexData = std::vector<float>();
// Print Material
std::cout << "Material: " << curMesh.MeshMaterial.name << "\n";
std::cout << "Ambient Color: " << curMesh.MeshMaterial.Ka.X << ", " << curMesh.MeshMaterial.Ka.Y << ", "
<< curMesh.MeshMaterial.Ka.Z << "\n";
std::cout << "Diffuse Color: " << curMesh.MeshMaterial.Kd.X << ", " << curMesh.MeshMaterial.Kd.Y << ", "
<< curMesh.MeshMaterial.Kd.Z << "\n";
std::cout << "Specular Color: " << curMesh.MeshMaterial.Ks.X << ", " << curMesh.MeshMaterial.Ks.Y << ", "
<< curMesh.MeshMaterial.Ks.Z << "\n";
std::cout << "Specular Exponent: " << curMesh.MeshMaterial.Ns << "\n";
std::cout << "Optical Density: " << curMesh.MeshMaterial.Ni << "\n";
std::cout << "Dissolve: " << curMesh.MeshMaterial.d << "\n";
std::cout << "Illumination: " << curMesh.MeshMaterial.illum << "\n";
std::cout << "Ambient Texture Map: " << curMesh.MeshMaterial.map_Ka << "\n";
std::cout << "Diffuse Texture Map: " << curMesh.MeshMaterial.map_Kd << "\n";
std::cout << "Specular Texture Map: " << curMesh.MeshMaterial.map_Ks << "\n";
std::cout << "Alpha Texture Map: " << curMesh.MeshMaterial.map_d << "\n";
std::cout << "Bump Map: " << curMesh.MeshMaterial.map_bump << "\n";
return vertexData;
} else {
// Output Error
std::cout << "Failed to Load File. May have failed to find it or it was not an .obj file.\n";
}
}
};
#endif //ECSGAME_OBJMESH_H

View File

@ -10,12 +10,14 @@
#include "../Components/Mesh.h"
#include "../Components/Camera.h"
#include "../../Rendering/Shader.h"
#include "../Components/ObjMesh.h"
using namespace ECS;
class RenderSystem : public EntitySystem {
public:
void render(World *pWorld, Shader shader) {
pWorld->each<Camera, Transform>([&](Entity *ent, ComponentHandle<Camera> camera, ComponentHandle<Transform> cameraTransform) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -30,6 +32,13 @@ public:
mesh->render();
});
// TODO: Duplicate of loop above, but for ObjMesh instead of Mesh. Is it possible to do this implicitly via polymorphism?
pWorld->each<ObjMesh, Transform>([&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform) {
shader.setMat4("model", transform->matrix);
mesh->render();
});
});
}

12
Resources/Monkey.mtl Normal file
View File

@ -0,0 +1,12 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl Material.001
Ns 225.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.157242 0.044599
Ks 0.500000 0.500000 0.500000
Ke 0.0 0.0 0.0
Ni 1.450000
d 0.619318
illum 9

2068
Resources/Monkey.obj Normal file

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@
#include "ECS/Systems/KeyboardMovementSystem.h"
#include "ECS/Systems/RenderSystem.h"
#include "ECS/Systems/MouseLookSystem.h"
#include "ECS/Components/ObjMesh.h"
using namespace ECS;
@ -78,98 +79,9 @@ int main() {
player->assign<Camera>(70.0f, 640, 480, 0.1f, 100.0f);
player->assign<MouseLook>(0.1);
Entity *box = world->create();
box->assign<Transform>();
box->assign<Mesh>(std::vector<float>{
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
});
box->get<Transform>()->translate(glm::vec3(0.0f, 0.0f, -5.0f));
Entity *box2 = world->create();
box2->assign<Transform>();
box2->assign<Mesh>(std::vector<float>{
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
});
box2->assign<ObjMesh>("Resources/Monkey.obj");
box2->get<Transform>()->translate(glm::vec3(5.0f, 0.0f, 0.0f));
Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs");