diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index d2bb342..4bed262 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -271,8 +271,6 @@ void Engine::RenderFrame() g_render->RenderStats(); - ImGui::ShowDemoWindow(); - // ImGui scope end *** g_ImGuiManager.EndFrame(); diff --git a/src/game/game_object.h b/src/game/game_object.h index df6eef8..c9732e5 100644 --- a/src/game/game_object.h +++ b/src/game/game_object.h @@ -4,6 +4,7 @@ #include "engine/ientity.h" #include "engine/camera.h" +#include "render/model.h" #include "render/modelsystem.h" enum EMovmentDir diff --git a/src/render/model.cpp b/src/render/model.cpp new file mode 100644 index 0000000..46e591c --- /dev/null +++ b/src/render/model.cpp @@ -0,0 +1,316 @@ +#include +#include +#include +#include "ifilesystem.h" +#include "log.h" +#include "render.h" +#include "gpu_buffer.h" +#include "shader.h" +#include "shadersystem.h" +#include "renderdevice.h" +#include "model.h" +#include "modelsystem.h" +#include "texturesmanager.h" + +extern Shader* g_litShader; + +static std::string getFileNameWithoutExtension(const std::string& filename) +{ + size_t lastindex = filename.find_last_of("."); + if (lastindex != std::string::npos) { + return filename.substr(0, lastindex); + } + + return filename; +} + +Model::Model() +{ + m_data.vb = nullptr; + m_data.ib = nullptr; + m_AlbedoTexture = nullptr; + + //m_boundingBox.min = glm::vec3(0.0f); + //m_boundingBox.max = glm::vec3(0.0f); +} + +Model::~Model() +{ + m_AlbedoTexture = nullptr; + + if (m_data.vb) + { + delete m_data.vb; + m_data.vb = nullptr; + } +} + +void Model::LoadObj(const char* filename) +{ + Msg("Loading OBJ file %s...", filename); + + std::vector vertexIndices, uvIndices, normalIndices; + std::vector temp_vertices; + std::vector temp_uvs; + std::vector temp_normals; + + std::vector out_vertices; + std::vector out_uvs; + std::vector out_normals; + + FILE* file = fopen(filename, "r"); + if (file == NULL) { + Msg("Model::LoadObj: Impossible to open the file !"); + return; + } + + while (1) { + + char lineHeader[128]; + // read the first word of the line + int res = fscanf(file, "%s", lineHeader); + if (res == EOF) + break; // EOF = End Of File. Quit the loop. + + // else : parse lineHeader + + if (strcmp(lineHeader, "v") == 0) { + glm::vec3 vertex; + fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z); + temp_vertices.push_back(vertex); + } + else if (strcmp(lineHeader, "vt") == 0) { + glm::vec2 uv; + fscanf(file, "%f %f\n", &uv.x, &uv.y); + uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders. + temp_uvs.push_back(uv); + } + else if (strcmp(lineHeader, "vn") == 0) { + glm::vec3 normal; + fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z); + temp_normals.push_back(normal); + } + else if (strcmp(lineHeader, "f") == 0) { + std::string vertex1, vertex2, vertex3; + unsigned int vertexIndex[3], uvIndex[3], normalIndex[3]; + int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]); + if (matches != 9) { + Msg("Model::LoadObj: File can't be read by our simple parser :-( Try exporting with other options"); + fclose(file); + return; + } + vertexIndices.push_back(vertexIndex[0]); + vertexIndices.push_back(vertexIndex[1]); + vertexIndices.push_back(vertexIndex[2]); + uvIndices.push_back(uvIndex[0]); + uvIndices.push_back(uvIndex[1]); + uvIndices.push_back(uvIndex[2]); + normalIndices.push_back(normalIndex[0]); + normalIndices.push_back(normalIndex[1]); + normalIndices.push_back(normalIndex[2]); + } + else { + // Probably a comment, eat up the rest of the line + char stupidBuffer[1000]; + fgets(stupidBuffer, 1000, file); + } + + } + + // For each vertex of each triangle + for (unsigned int i = 0; i < vertexIndices.size(); i++) { + + // Get the indices of its attributes + unsigned int vertexIndex = vertexIndices[i]; + unsigned int uvIndex = uvIndices[i]; + unsigned int normalIndex = normalIndices[i]; + + // Get the attributes thanks to the index + glm::vec3 vertex = temp_vertices[vertexIndex - 1]; + glm::vec2 uv = temp_uvs[uvIndex - 1]; + glm::vec3 normal = temp_normals[normalIndex - 1]; + + // Put the attributes in buffers + out_vertices.push_back(vertex); + out_uvs.push_back(uv); + out_normals.push_back(normal); + + } + + fclose(file); + + m_boundingBox.m_min = glm::vec3(FLT_MAX); + m_boundingBox.m_max = glm::vec3(FLT_MIN); + + // Combine in to the one array + std::vector vertices; + for (unsigned int i = 0; i < vertexIndices.size(); i++) + { + // Get the indices of its attributes + unsigned int vertexIndex = vertexIndices[i]; + unsigned int uvIndex = uvIndices[i]; + unsigned int normalIndex = normalIndices[i]; + + // Get the attributes thanks to the index + glm::vec3 vertex = temp_vertices[vertexIndex - 1]; + glm::vec2 uv = temp_uvs[uvIndex - 1]; + glm::vec3 normal = temp_normals[normalIndex - 1]; + + StaticMeshVertex vtx = {}; + vtx.position = vertex; + vtx.normal = normal; + vtx.texcoord = uv; + vertices.push_back(vtx); + + m_boundingBox.m_min = glm::min(m_boundingBox.m_min, vertex); + m_boundingBox.m_max = glm::max(m_boundingBox.m_max, vertex); + } + + m_Vertices = vertices; + + m_data.vb = g_renderDevice->CreateVertexBuffer(vertices.data(), (int)sizeof(StaticMeshVertex) * (int)vertices.size()); + m_data.vbcount = vertices.size(); + + std::string mtlfilename = getFileNameWithoutExtension(filename); + mtlfilename += ".mtl"; + LoadMtl(mtlfilename.c_str()); +} + +void Model::LoadMtl(const char* filename) +{ + Msg("Loading MTL file %s...", filename); + + FILE* file = fopen(filename, "r"); + if (file == NULL) { + Msg("Model::LoadObj: Impossible to open the file !"); + return; + } + + while (1) { + + char lineHeader[128]; + // read the first word of the line + int res = fscanf(file, "%s", lineHeader); + if (res == EOF) + break; // EOF = End Of File. Quit the loop. + + if (strcmp(lineHeader, "map_Kd") == 0) { + char stupidBuffer[1000]; + fgets(stupidBuffer, 1000, file); + + const char* textureFilename = stupidBuffer + 1; + m_AlbedoTexture = g_texturesManager->LoadTexture2D(textureFilename, true); + } + + //if (strcmp(lineHeader, "v") == 0) { + // glm::vec3 vertex; + // fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z); + // temp_vertices.push_back(vertex); + //} + //else { + // // Probably a comment, eat up the rest of the line + // char stupidBuffer[1000]; + // fgets(stupidBuffer, 1000, file); + //} + + } + + fclose(file); +} + +void Model::Draw(const glm::mat4& model, bool isTransparent /*= false*/) +{ + SDL_assert(g_litShader); + + glFrontFace(GL_CCW); + glDepthFunc(GL_LESS); + + g_renderDevice->SetCullFace(true); + g_renderDevice->SetDepthTest(true); + g_renderDevice->SetDepthWrite(true); + + if (isTransparent) + { + // Enable blending + g_renderDevice->SetBlending(true); + g_renderDevice->SetBlendingFunction(BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA); + + glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, .5f); + g_shaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color)); + } + else + { + g_renderDevice->SetBlending(false); + + //glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, 1.f); + //g_shaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color)); + } + + g_renderDevice->SetVerticesBuffer(m_data.vb); + + g_shaderSystem->SetShader(g_litShader); + g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MODEL_MATRIX, &model[0]); + + //static float test = 0.0f; + //test += g_systemTimer->GetDelta() * 6.0f; + + //glm::mat4 model = glm::mat4(1.0f); + + //int32_t x = 0, y = 0; + //g_inputSystem->GetMousePosition(&x, &y); + // + //glm::mat4 model = glm::mat4(1.0f); + //model = glm::rotate(model, test, glm::vec3(0.0f, 1.0f, 0.0f)); + // + //float realY = (float)g_renderView.height - (float)y - 1; + // + //glm::vec4 viewport = glm::vec4(0.0f, 0.0f, (float)g_renderView.width, (float)g_renderView.height); + //glm::vec3 pos = glm::unProject( + // glm::vec3((float)x, realY, 0.0f), + // model, + // g_renderView.proj, + // viewport); + // + //pos *= 50.0f; + // + //model = glm::translate(model, pos); + + glm::mat4 mvp = glm::identity(); + mvp = g_render->GetProjectionMatrix() * g_render->GetViewMatrix() * model; + g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]); + + g_texturesManager->SetTexture(0, m_AlbedoTexture); + g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0); + + g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount); + +#if 0 + glm::mat4 mvp = glm::identity(); + mvp = g_renderView.proj * g_renderView.view * model; + g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]); + + g_texturesManager->SetTexture(0, m_AlbedoTexture); + g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0); + + g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount); + + BoundingBox bbox = m_boundingBox; + TransformBoundingBox(bbox, model); + g_debugRender->DrawBoundingBox(bbox, glm::vec3(1.0f)); +#endif +} + +void ReleaseModelData(ModelData_t& data) +{ + if (data.ib) + { + delete data.ib; + data.ib = nullptr; + } + + if (data.vb) + { + delete data.vb; + data.vb = nullptr; + } +} diff --git a/src/render/model.h b/src/render/model.h new file mode 100644 index 0000000..8767d80 --- /dev/null +++ b/src/render/model.h @@ -0,0 +1,48 @@ +#ifndef MODEL_H +#define MODEL_H + +#include + +#include "boundingbox.h" +#include "render_shared.h" + +#include +#include + +class GPUBuffer; +class Texture2D; + +struct ModelData_t +{ + GPUBuffer* vb; + GPUBuffer* ib; + uint32_t vbcount; + uint32_t ibcount; +}; + +void ReleaseModelData(ModelData_t& data); + +class Render; + +class Model +{ + friend class Render; +public: + Model(); + ~Model(); + + void LoadObj(const char* filename); + void LoadMtl(const char* filename); + + void Draw(const glm::mat4& model, bool isTransparent = false); + + const BoundingBox& GetBoundingBox() { return m_boundingBox; } + +private: + std::vector m_Vertices; + ModelData_t m_data; + BoundingBox m_boundingBox; + Texture2D* m_AlbedoTexture; +}; + +#endif // !MODEL_H diff --git a/src/render/modelsystem.cpp b/src/render/modelsystem.cpp index 98237a2..dd67dae 100644 --- a/src/render/modelsystem.cpp +++ b/src/render/modelsystem.cpp @@ -8,6 +8,7 @@ #include "shader.h" #include "shadersystem.h" #include "renderdevice.h" +#include "model.h" #include "modelsystem.h" #include "texturesmanager.h" @@ -27,7 +28,7 @@ static InputLayoutDesc_t g_skinnedVertexLayout[] = { Shader* g_litShader = nullptr; -std::string getFileNameWithoutExtension(const std::string& filename) +static std::string getFileNameWithoutExtension(const std::string& filename) { size_t lastindex = filename.find_last_of("."); if (lastindex != std::string::npos) { @@ -117,294 +118,3 @@ Model* ModelSystem::LoadModel(const char* filename) return model; } - -Model::Model() -{ - m_data.vb = nullptr; - m_data.ib = nullptr; - m_AlbedoTexture = nullptr; - - //m_boundingBox.min = glm::vec3(0.0f); - //m_boundingBox.max = glm::vec3(0.0f); -} - -Model::~Model() -{ - m_AlbedoTexture = nullptr; - - if (m_data.vb) - { - delete m_data.vb; - m_data.vb = nullptr; - } -} - -void Model::LoadObj(const char* filename) -{ - Msg("Loading OBJ file %s...", filename); - - std::vector vertexIndices, uvIndices, normalIndices; - std::vector temp_vertices; - std::vector temp_uvs; - std::vector temp_normals; - - std::vector out_vertices; - std::vector out_uvs; - std::vector out_normals; - - FILE* file = fopen(filename, "r"); - if (file == NULL) { - Msg("Model::LoadObj: Impossible to open the file !"); - return; - } - - while (1) { - - char lineHeader[128]; - // read the first word of the line - int res = fscanf(file, "%s", lineHeader); - if (res == EOF) - break; // EOF = End Of File. Quit the loop. - - // else : parse lineHeader - - if (strcmp(lineHeader, "v") == 0) { - glm::vec3 vertex; - fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z); - temp_vertices.push_back(vertex); - } - else if (strcmp(lineHeader, "vt") == 0) { - glm::vec2 uv; - fscanf(file, "%f %f\n", &uv.x, &uv.y); - uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders. - temp_uvs.push_back(uv); - } - else if (strcmp(lineHeader, "vn") == 0) { - glm::vec3 normal; - fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z); - temp_normals.push_back(normal); - } - else if (strcmp(lineHeader, "f") == 0) { - std::string vertex1, vertex2, vertex3; - unsigned int vertexIndex[3], uvIndex[3], normalIndex[3]; - int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]); - if (matches != 9) { - Msg("Model::LoadObj: File can't be read by our simple parser :-( Try exporting with other options"); - fclose(file); - return; - } - vertexIndices.push_back(vertexIndex[0]); - vertexIndices.push_back(vertexIndex[1]); - vertexIndices.push_back(vertexIndex[2]); - uvIndices.push_back(uvIndex[0]); - uvIndices.push_back(uvIndex[1]); - uvIndices.push_back(uvIndex[2]); - normalIndices.push_back(normalIndex[0]); - normalIndices.push_back(normalIndex[1]); - normalIndices.push_back(normalIndex[2]); - } - else { - // Probably a comment, eat up the rest of the line - char stupidBuffer[1000]; - fgets(stupidBuffer, 1000, file); - } - - } - - // For each vertex of each triangle - for (unsigned int i = 0; i < vertexIndices.size(); i++) { - - // Get the indices of its attributes - unsigned int vertexIndex = vertexIndices[i]; - unsigned int uvIndex = uvIndices[i]; - unsigned int normalIndex = normalIndices[i]; - - // Get the attributes thanks to the index - glm::vec3 vertex = temp_vertices[vertexIndex - 1]; - glm::vec2 uv = temp_uvs[uvIndex - 1]; - glm::vec3 normal = temp_normals[normalIndex - 1]; - - // Put the attributes in buffers - out_vertices.push_back(vertex); - out_uvs.push_back(uv); - out_normals.push_back(normal); - - } - - fclose(file); - - m_boundingBox.m_min = glm::vec3(FLT_MAX); - m_boundingBox.m_max = glm::vec3(FLT_MIN); - - // Combine in to the one array - std::vector vertices; - for (unsigned int i = 0; i < vertexIndices.size(); i++) - { - // Get the indices of its attributes - unsigned int vertexIndex = vertexIndices[i]; - unsigned int uvIndex = uvIndices[i]; - unsigned int normalIndex = normalIndices[i]; - - // Get the attributes thanks to the index - glm::vec3 vertex = temp_vertices[vertexIndex - 1]; - glm::vec2 uv = temp_uvs[uvIndex - 1]; - glm::vec3 normal = temp_normals[normalIndex - 1]; - - StaticMeshVertex vtx = {}; - vtx.position = vertex; - vtx.normal = normal; - vtx.texcoord = uv; - vertices.push_back(vtx); - - m_boundingBox.m_min = glm::min(m_boundingBox.m_min, vertex); - m_boundingBox.m_max = glm::max(m_boundingBox.m_max, vertex); - } - - m_Vertices = vertices; - - m_data.vb = g_renderDevice->CreateVertexBuffer(vertices.data(), (int)sizeof(StaticMeshVertex) * (int)vertices.size()); - m_data.vbcount = vertices.size(); - - std::string mtlfilename = getFileNameWithoutExtension(filename); - mtlfilename += ".mtl"; - LoadMtl(mtlfilename.c_str()); -} - -void Model::LoadMtl(const char* filename) -{ - Msg("Loading MTL file %s...", filename); - - FILE* file = fopen(filename, "r"); - if (file == NULL) { - Msg("Model::LoadObj: Impossible to open the file !"); - return; - } - - while (1) { - - char lineHeader[128]; - // read the first word of the line - int res = fscanf(file, "%s", lineHeader); - if (res == EOF) - break; // EOF = End Of File. Quit the loop. - - if (strcmp(lineHeader, "map_Kd") == 0) { - char stupidBuffer[1000]; - fgets(stupidBuffer, 1000, file); - - const char* textureFilename = stupidBuffer + 1; - m_AlbedoTexture = g_texturesManager->LoadTexture2D(textureFilename, true); - } - - //if (strcmp(lineHeader, "v") == 0) { - // glm::vec3 vertex; - // fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z); - // temp_vertices.push_back(vertex); - //} - //else { - // // Probably a comment, eat up the rest of the line - // char stupidBuffer[1000]; - // fgets(stupidBuffer, 1000, file); - //} - - } - - fclose(file); -} - -void Model::Draw(const glm::mat4& model, bool isTransparent /*= false*/) -{ - SDL_assert(g_litShader); - - glFrontFace(GL_CCW); - glDepthFunc(GL_LESS); - - g_renderDevice->SetCullFace(true); - g_renderDevice->SetDepthTest(true); - g_renderDevice->SetDepthWrite(true); - - if (isTransparent) - { - // Enable blending - g_renderDevice->SetBlending(true); - g_renderDevice->SetBlendingFunction(BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA); - - glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, .5f); - g_shaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color)); - } - else - { - g_renderDevice->SetBlending(false); - - //glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, 1.f); - //g_shaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color)); - } - - g_renderDevice->SetVerticesBuffer(m_data.vb); - - g_shaderSystem->SetShader(g_litShader); - g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MODEL_MATRIX, &model[0]); - - //static float test = 0.0f; - //test += g_systemTimer->GetDelta() * 6.0f; - - //glm::mat4 model = glm::mat4(1.0f); - - //int32_t x = 0, y = 0; - //g_inputSystem->GetMousePosition(&x, &y); - // - //glm::mat4 model = glm::mat4(1.0f); - //model = glm::rotate(model, test, glm::vec3(0.0f, 1.0f, 0.0f)); - // - //float realY = (float)g_renderView.height - (float)y - 1; - // - //glm::vec4 viewport = glm::vec4(0.0f, 0.0f, (float)g_renderView.width, (float)g_renderView.height); - //glm::vec3 pos = glm::unProject( - // glm::vec3((float)x, realY, 0.0f), - // model, - // g_renderView.proj, - // viewport); - // - //pos *= 50.0f; - // - //model = glm::translate(model, pos); - - glm::mat4 mvp = glm::identity(); - mvp = g_render->GetProjectionMatrix() * g_render->GetViewMatrix() * model; - g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]); - - g_texturesManager->SetTexture(0, m_AlbedoTexture); - g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0); - - g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount); - -#if 0 - glm::mat4 mvp = glm::identity(); - mvp = g_renderView.proj * g_renderView.view * model; - g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]); - - g_texturesManager->SetTexture(0, m_AlbedoTexture); - g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0); - - g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount); - - BoundingBox bbox = m_boundingBox; - TransformBoundingBox(bbox, model); - g_debugRender->DrawBoundingBox(bbox, glm::vec3(1.0f)); -#endif -} - -void ReleaseModelData(ModelData_t& data) -{ - if (data.ib) - { - delete data.ib; - data.ib = nullptr; - } - - if (data.vb) - { - delete data.vb; - data.vb = nullptr; - } -} diff --git a/src/render/modelsystem.h b/src/render/modelsystem.h index 9cdc8c7..840f3d9 100644 --- a/src/render/modelsystem.h +++ b/src/render/modelsystem.h @@ -3,47 +3,7 @@ #include -#include "boundingbox.h" -#include "render_shared.h" - -#include -#include - -class GPUBuffer; -class Texture2D; - -struct ModelData_t -{ - GPUBuffer* vb; - GPUBuffer* ib; - uint32_t vbcount; - uint32_t ibcount; -}; - -void ReleaseModelData(ModelData_t& data); - -class Render; - -class Model -{ - friend class Render; -public: - Model(); - ~Model(); - - void LoadObj(const char* filename); - void LoadMtl(const char* filename); - - void Draw(const glm::mat4& model, bool isTransparent = false); - - const BoundingBox& GetBoundingBox() { return m_boundingBox; } - -private: - std::vector m_Vertices; - ModelData_t m_data; - BoundingBox m_boundingBox; - Texture2D* m_AlbedoTexture; -}; +class Model; class ModelSystem {