diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 42719b05..c790951b 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -138,6 +138,7 @@ add_library(XCEngine STATIC include/XCEngine/RHI/OpenGL/OpenGLSampler.h include/XCEngine/RHI/OpenGL/OpenGLRenderTargetView.h include/XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h + include/XCEngine/RHI/OpenGL/OpenGLMesh.h src/RHI/OpenGL/OpenGLDevice.cpp src/RHI/OpenGL/OpenGLShader.cpp src/RHI/OpenGL/OpenGLBuffer.cpp @@ -150,6 +151,7 @@ add_library(XCEngine STATIC src/RHI/OpenGL/OpenGLSampler.cpp src/RHI/OpenGL/OpenGLRenderTargetView.cpp src/RHI/OpenGL/OpenGLDepthStencilView.cpp + src/RHI/OpenGL/OpenGLMesh.cpp ) target_include_directories(XCEngine PUBLIC diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLMesh.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLMesh.h new file mode 100644 index 00000000..4af69f32 --- /dev/null +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLMesh.h @@ -0,0 +1,44 @@ +#pragma once + +#include "XCEngine/RHI/OpenGL/OpenGLBuffer.h" +#include "XCEngine/RHI/OpenGL/OpenGLVertexArray.h" +#include +#include + +namespace XCEngine { +namespace RHI { + +struct MeshVertex { + float Position[3]; + float Normal[3]; + float TexCoords[2]; +}; + +struct MeshTexture { + unsigned int id; + std::string type; + std::string path; +}; + +class OpenGLMesh { +public: + OpenGLMesh(); + ~OpenGLMesh(); + + bool Initialize(const void* vertices, size_t vertexCount, const void* indices, size_t indexCount); + void Shutdown(); + + void Draw(unsigned int shaderProgram, const std::vector& textures); + + unsigned int GetVAO() const { return m_vertexArray.GetID(); } + unsigned int GetIndexCount() const { return m_vertexArray.GetIndexCount(); } + +private: + OpenGLBuffer m_vertexBuffer; + OpenGLBuffer m_indexBuffer; + OpenGLVertexArray m_vertexArray; + std::vector m_textures; +}; + +} // namespace RHI +} // namespace XCEngine diff --git a/engine/src/RHI/OpenGL/OpenGLMesh.cpp b/engine/src/RHI/OpenGL/OpenGLMesh.cpp new file mode 100644 index 00000000..4d855231 --- /dev/null +++ b/engine/src/RHI/OpenGL/OpenGLMesh.cpp @@ -0,0 +1,84 @@ +#define GLFW_INCLUDE_NONE +#include "XCEngine/RHI/OpenGL/OpenGLMesh.h" +#include +#include + +namespace XCEngine { +namespace RHI { + +OpenGLMesh::OpenGLMesh() { +} + +OpenGLMesh::~OpenGLMesh() { + Shutdown(); +} + +bool OpenGLMesh::Initialize(const void* vertices, size_t vertexCount, const void* indices, size_t indexCount) { + m_vertexBuffer.InitializeVertexBuffer(vertices, vertexCount * sizeof(MeshVertex)); + m_indexBuffer.InitializeIndexBuffer(indices, indexCount * sizeof(unsigned int)); + + m_vertexArray.Initialize(); + + VertexAttribute attr0; + attr0.index = 0; + attr0.count = 3; + attr0.type = GL_FLOAT; + attr0.normalized = GL_FALSE; + attr0.stride = sizeof(MeshVertex); + attr0.offset = 0; + m_vertexArray.AddVertexBuffer(m_vertexBuffer.GetID(), attr0); + + VertexAttribute attr1; + attr1.index = 1; + attr1.count = 3; + attr1.type = GL_FLOAT; + attr1.normalized = GL_FALSE; + attr1.stride = sizeof(MeshVertex); + attr1.offset = sizeof(float) * 3; + m_vertexArray.AddVertexBuffer(m_vertexBuffer.GetID(), attr1); + + VertexAttribute attr2; + attr2.index = 2; + attr2.count = 2; + attr2.type = GL_FLOAT; + attr2.normalized = GL_FALSE; + attr2.stride = sizeof(MeshVertex); + attr2.offset = sizeof(float) * 6; + m_vertexArray.AddVertexBuffer(m_vertexBuffer.GetID(), attr2); + + m_vertexArray.SetIndexBuffer(m_indexBuffer.GetID(), GL_UNSIGNED_INT); + + return true; +} + +void OpenGLMesh::Shutdown() { + m_vertexArray.Shutdown(); + m_vertexBuffer.Shutdown(); + m_indexBuffer.Shutdown(); +} + +void OpenGLMesh::Draw(unsigned int shaderProgram, const std::vector& textures) { + unsigned int diffuseNr = 1; + unsigned int specularNr = 1; + + for (unsigned int i = 0; i < textures.size(); i++) + { + glActiveTexture(GL_TEXTURE0 + i); + std::string number; + std::string name = textures[i].type; + if (name == "texture_diffuse") + number = std::to_string(diffuseNr++); + else if (name == "texture_specular") + number = std::to_string(specularNr++); + + glUniform1i(glGetUniformLocation(shaderProgram, ("material." + name + number).c_str()), i); + glBindTexture(GL_TEXTURE_2D, textures[i].id); + } + + m_vertexArray.Bind(); + glDrawElements(GL_TRIANGLES, m_vertexArray.GetIndexCount(), GL_UNSIGNED_INT, 0); + glActiveTexture(GL_TEXTURE0); +} + +} // namespace RHI +} // namespace XCEngine