diff --git a/Core/Application/Application.cpp b/Core/Application/Application.cpp index 2fb8a12..df9a2c4 100644 --- a/Core/Application/Application.cpp +++ b/Core/Application/Application.cpp @@ -41,6 +41,7 @@ namespace CGL::Core CGL_LOG(CoreApp, Trace, "Running application"); auto startTime = std::chrono::steady_clock::now(); + auto lastFrameTime = startTime; OnInit(); SDL_Event e; @@ -65,7 +66,11 @@ namespace CGL::Core } } - OnUpdate(e); + // Calculate deltatime + auto currentFrameTime = std::chrono::steady_clock::now(); + f32 deltaTime = std::chrono::duration(currentFrameTime - lastFrameTime).count(); + + OnUpdate(e, deltaTime); // Call begin and end frame before calling render itself m_renderer->BeginFrame(); @@ -83,6 +88,8 @@ namespace CGL::Core m_isRunning = false; } } + + lastFrameTime = currentFrameTime; } OnShutdown(); diff --git a/Core/Application/Application.h b/Core/Application/Application.h index fd856e2..65472bf 100644 --- a/Core/Application/Application.h +++ b/Core/Application/Application.h @@ -22,7 +22,7 @@ namespace CGL::Core protected: virtual bool OnInit(); - virtual void OnUpdate(const SDL_Event& e) = 0; + virtual void OnUpdate(const SDL_Event& e, f32 deltaTime) = 0; virtual void OnRender() = 0; virtual void OnShutdown(); virtual void OnResize(u32 width, u32 height); diff --git a/Core/Common.h b/Core/Common.h index 4c814ab..8b9b1f3 100644 --- a/Core/Common.h +++ b/Core/Common.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #endif diff --git a/Core/Graphics/Buffer.h b/Core/Graphics/Buffer.h index 4823538..7b3fb4c 100644 --- a/Core/Graphics/Buffer.h +++ b/Core/Graphics/Buffer.h @@ -40,6 +40,7 @@ namespace CGL::Graphics u32 TypeSize = 0; u32 Count = 0; void* Data = nullptr; + std::type_index VertexType = typeid(void); }; #if defined(CGL_RHI_DX11) diff --git a/Core/Graphics/RHI/OpenGL/OPENGLIndexBuffer.h b/Core/Graphics/RHI/OpenGL/OPENGLIndexBuffer.h index 26d6ee9..a5595eb 100644 --- a/Core/Graphics/RHI/OpenGL/OPENGLIndexBuffer.h +++ b/Core/Graphics/RHI/OpenGL/OPENGLIndexBuffer.h @@ -5,7 +5,8 @@ namespace CGL::Graphics { struct OPENGLIndexBuffer { - u32 Stride; + u32 IndicesCount; + u32 Size; GLuint EBO; }; } // namespace CGL::Graphics \ No newline at end of file diff --git a/Core/Graphics/RHI/OpenGL/OPENGLRenderer.cpp b/Core/Graphics/RHI/OpenGL/OPENGLRenderer.cpp index 0cf0560..038eb69 100644 --- a/Core/Graphics/RHI/OpenGL/OPENGLRenderer.cpp +++ b/Core/Graphics/RHI/OpenGL/OPENGLRenderer.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace CGL::Graphics { @@ -50,7 +51,8 @@ namespace CGL::Graphics void Renderer::BeginFrame_OPENGL() { glClearDepth(1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void Renderer::EndFrame_OPENGL() @@ -59,47 +61,46 @@ namespace CGL::Graphics } void Renderer::Resize_OPENGL(u32 width, u32 height) - { + { glViewport(0, 0, width, height); - } + } - void Renderer::SetPrimitiveTopology_OPENGL(PrimitiveType topology) - { + void Renderer::SetPrimitiveTopology_OPENGL(PrimitiveType topology) + { assert(GetImpl()); GetImpl()->SetPrimitive(Mapping::PrimitiveTopology[size_t(topology)]); - } + } - void Renderer::SetVertexShader_OPENGL([[maybe_unused]] const VertexShader& shader) - { + void Renderer::SetVertexShader_OPENGL([[maybe_unused]] const VertexShader& shader) + { // This function is currently empty because shader creation and compilation are handled // by separate functions. The SetVertexShader function will be implemented to switch to // an active vertex shader for each frame as needed. assert(GetImpl()); - } + } - void Renderer::SetPixelShader_OPENGL( [[maybe_unused]] const PixelShader& shader) - { + void Renderer::SetPixelShader_OPENGL( [[maybe_unused]] const PixelShader& shader) + { // This function is currently empty because shader creation and compilation are handled // by separate functions. The SetPixelShader function will be implemented to switch to // an active pixel shader for each frame as needed. assert(GetImpl() ); - } + } - void Renderer::SetVertexBuffer_OPENGL(const VertexBuffer& buffer) - { + void Renderer::SetVertexBuffer_OPENGL(const VertexBuffer& buffer) + { assert(GetImpl()); glBindVertexArray(buffer.VAO); - } + } - void Renderer::SetIndexBuffer_OPENGL([[maybe_unused]] const IndexBuffer& buffer) - { - // This function is currently empty. The implementation will involve binding the index buffer - // object. As more Samples are implemented this function will be implemented asap. + void Renderer::SetIndexBuffer_OPENGL( const IndexBuffer& buffer) + { assert(GetImpl()); - } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.EBO); + } - ShaderCompileResult Renderer::CompileVertexShader_OPENGL(const ShaderSource& source, VertexShader* outShader) - { + ShaderCompileResult Renderer::CompileVertexShader_OPENGL(const ShaderSource& source, VertexShader* outShader) + { assert(GetImpl() && outShader); CompileConfig cfg{}; @@ -116,10 +117,10 @@ namespace CGL::Graphics } return result; - } + } - ShaderCompileResult Renderer::CompilePixelShader_OPENGL(const ShaderSource& source, PixelShader* outShader) - { + ShaderCompileResult Renderer::CompilePixelShader_OPENGL(const ShaderSource& source, PixelShader* outShader) + { assert(GetImpl() && outShader); CompileConfig cfg{}; @@ -136,10 +137,10 @@ namespace CGL::Graphics } return result; - } + } - void Renderer::LinkShaders_OPENGL(Material* material) - { + void Renderer::LinkShaders_OPENGL(Material* material) + { material->m_id = glCreateProgram(); glAttachShader(material->m_id, material->GetVertexShader()->Shader.VertexShader); glAttachShader(material->m_id, material->GetPixelShader()->Shader.PixelShader); @@ -160,67 +161,91 @@ namespace CGL::Graphics glDeleteShader(material->GetVertexShader()->Shader.VertexShader); glDeleteShader(material->GetPixelShader()->Shader.PixelShader); } - } + } - VertexBuffer Renderer::CreateVertexBuffer_OPENGL(const BufferSource& source) - { + VertexBuffer Renderer::CreateVertexBuffer_OPENGL(const BufferSource& source) + { assert(source.Type == BufferType::Vertex); assert(GetImpl()); VertexBuffer vb; - vb.Stride = source.TypeSize * source.Count; + vb.Size = source.TypeSize * source.Count; glGenVertexArrays(1, &vb.VAO); glGenBuffers(1, &vb.VBO); glBindVertexArray(vb.VAO); glBindBuffer(GL_ARRAY_BUFFER, vb.VBO); - glBufferData(GL_ARRAY_BUFFER, vb.Stride, source.Data, Mapping::BufferUsage[size_t(source.Usage)]); + glBufferData(GL_ARRAY_BUFFER, vb.Size, source.Data, Mapping::BufferUsage[size_t(source.Usage)]); - // Position Attribute - glVertexAttribPointer(0, sizeof(VertexTypes::PositionColor::Position) / sizeof(float), GL_FLOAT, GL_FALSE, source.TypeSize, (void*)offsetof(Graphics::VertexTypes::PositionColor,Graphics::VertexTypes::PositionColor::Position)); - glEnableVertexAttribArray(0); - - // Color Attribute - glVertexAttribPointer(1, sizeof(VertexTypes::PositionColor::Color)/sizeof(float), GL_FLOAT, GL_FALSE, source.TypeSize, (void*)offsetof(Graphics::VertexTypes::PositionColor, Graphics::VertexTypes::PositionColor::Color)); - glEnableVertexAttribArray(1); - - glBindBuffer(GL_ARRAY_BUFFER, 0); + if (source.VertexType == typeid(VertexTypes::Position)) + { + OPENGLEnableVertexAttributes(); + } + else if (source.VertexType == typeid(VertexTypes::PositionColor)) + { + OPENGLEnableVertexAttributes(); + } glBindVertexArray(0); return vb; - } + } - IndexBuffer Renderer::CreateIndexBuffer_OPENGL( [[maybe_unused]] const BufferSource& source) - { + IndexBuffer Renderer::CreateIndexBuffer_OPENGL(const BufferSource& source) + { assert(source.Type == BufferType::Index); assert(GetImpl()); IndexBuffer ib; - ib.Stride = source.TypeSize * source.Count; + ib.Size = source.TypeSize * source.Count; + ib.IndicesCount = source.Count; + glGenBuffers(1, &ib.EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, ib.Stride, source.Data, Mapping::BufferUsage[size_t(source.Usage)]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, ib.Size, source.Data, Mapping::BufferUsage[size_t(source.Usage)]); return ib; - } - - void Renderer::CreateConstantBuffer_OPENGL([[maybe_unused]] const BufferSource& source, [[maybe_unused]] GLuint& buffer){} + } - void Renderer::SetConstantBufferData_OPENGL([[maybe_unused]] GLuint* buffer, [[maybe_unused]] const void* data, [[maybe_unused]] size_t size){} - - void Renderer::SetConstantBuffer_OPENGL([[maybe_unused]] ShaderType type, [[maybe_unused]] u32 startSlot, [[maybe_unused]] const GLuint& buffer){} + void Renderer::CreateConstantBuffer_OPENGL(const BufferSource& source, GLuint& outBuffer) + { + assert(source.Type == BufferType::Constant); + assert(GetImpl()); - void Renderer::Draw_OPENGL(u32 vertexCount, u32 startVertex) - { + glGenBuffers(1, &outBuffer); + + glBindBuffer(GL_UNIFORM_BUFFER, outBuffer); + glBufferData(GL_UNIFORM_BUFFER, source.TypeSize, nullptr, Mapping::BufferUsage[size_t(source.Usage)]); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, outBuffer); + } + + void Renderer::SetConstantBufferData_OPENGL(const GLuint& buffer, const void* data, size_t size) + { + assert(buffer); + glBindBuffer(GL_UNIFORM_BUFFER, buffer); + + glBufferSubData(GL_UNIFORM_BUFFER, 0, size, data); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + } + + void Renderer::SetConstantBuffer_OPENGL([[maybe_unused]] ShaderType type, [[maybe_unused]] u32 startSlot, [[maybe_unused]] const GLuint& buffer) + { + // This function is currently empty because uniform buffer binding is managed directly + // by the shader's 'binding' layout qualifier. If runtime shader switching or dynamic + // buffer management is needed, this function will handle the necessary binding logic. + assert(buffer); + } + + void Renderer::Draw_OPENGL(u32 vertexCount, u32 startVertex) + { assert(GetImpl()); glDrawArrays(GetImpl()->GetPrimitive(), startVertex, vertexCount); - } + } - void Renderer::DrawIndexed_OPENGL([[maybe_unused]] u32 indexCount, [[maybe_unused]] u32 startIndex, [[maybe_unused]] u32 baseVertex) - { + void Renderer::DrawIndexed_OPENGL(u32 indexCount, u32 startIndex, u32 baseVertex) + { assert(GetImpl()); glDrawElementsBaseVertex(GetImpl()->GetPrimitive(), indexCount, GL_UNSIGNED_INT, (void*)(startIndex * sizeof(GLuint)), baseVertex); - } + } #endif // CGL_RHI_OPENGL } \ No newline at end of file diff --git a/Core/Graphics/RHI/OpenGL/OPENGLVertexAttributes.cpp b/Core/Graphics/RHI/OpenGL/OPENGLVertexAttributes.cpp new file mode 100644 index 0000000..03707e3 --- /dev/null +++ b/Core/Graphics/RHI/OpenGL/OPENGLVertexAttributes.cpp @@ -0,0 +1,41 @@ +#include "OPENGLVertexAttributes.h" + +namespace CGL::Graphics +{ + template <> + void OPENGLEnableVertexAttributes() + { + glEnableVertexAttribArray(0); // Position Attribute + glVertexAttribPointer( + 0, + sizeof(Graphics::VertexTypes::Position::Position) / sizeof(float), + GL_FLOAT, + GL_FALSE, + sizeof(Graphics::VertexTypes::Position), + (void*)offsetof(Graphics::VertexTypes::Position, Position) + ); + } + + template <> + void OPENGLEnableVertexAttributes() { + glEnableVertexAttribArray(0); // Position Attribute + glVertexAttribPointer( + 0, + sizeof(Graphics::VertexTypes::PositionColor::Position) / sizeof(float), + GL_FLOAT, + GL_FALSE, + sizeof(Graphics::VertexTypes::PositionColor), + (void*)offsetof(Graphics::VertexTypes::PositionColor, Position) + ); + + glEnableVertexAttribArray(1); // Color Attribute + glVertexAttribPointer( + 1, + sizeof(Graphics::VertexTypes::PositionColor::Color) / sizeof(float), + GL_FLOAT, + GL_FALSE, + sizeof(Graphics::VertexTypes::PositionColor), + (void*)offsetof(Graphics::VertexTypes::PositionColor, Color) + ); + } +} \ No newline at end of file diff --git a/Core/Graphics/RHI/OpenGL/OPENGLVertexAttributes.h b/Core/Graphics/RHI/OpenGL/OPENGLVertexAttributes.h new file mode 100644 index 0000000..c0908ca --- /dev/null +++ b/Core/Graphics/RHI/OpenGL/OPENGLVertexAttributes.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +namespace CGL::Graphics +{ + template + void OPENGLEnableVertexAttributes(); + + template <> + void OPENGLEnableVertexAttributes(); + + template <> + void OPENGLEnableVertexAttributes(); + + template <> + void OPENGLEnableVertexAttributes(); + + template <> + void OPENGLEnableVertexAttributes(); +} \ No newline at end of file diff --git a/Core/Graphics/RHI/OpenGL/OPENGLVertexBuffer.h b/Core/Graphics/RHI/OpenGL/OPENGLVertexBuffer.h index a83f061..c0f120c 100644 --- a/Core/Graphics/RHI/OpenGL/OPENGLVertexBuffer.h +++ b/Core/Graphics/RHI/OpenGL/OPENGLVertexBuffer.h @@ -6,7 +6,7 @@ namespace CGL::Graphics { struct OPENGLVertexBuffer { - u32 Stride; + u32 Size; u32 Offset; GLuint VBO; GLuint VAO; diff --git a/Core/Graphics/Renderer.h b/Core/Graphics/Renderer.h index 2c4ca12..038a8d4 100644 --- a/Core/Graphics/Renderer.h +++ b/Core/Graphics/Renderer.h @@ -97,7 +97,7 @@ namespace CGL::Graphics ShaderCompileResult CompilePixelShader_OPENGL(const ShaderSource& source, PixelShader* outShader); void LinkShaders_OPENGL(Material* material); void CreateConstantBuffer_OPENGL(const BufferSource& source, GLuint& outBuffer); - void SetConstantBufferData_OPENGL(GLuint* buffer, const void* data, size_t size); + void SetConstantBufferData_OPENGL(const GLuint& buffer, const void* data, size_t size); void SetConstantBuffer_OPENGL(ShaderType type, u32 startSlot, const GLuint& buffer); VertexBuffer CreateVertexBuffer_OPENGL(const BufferSource& source); IndexBuffer CreateIndexBuffer_OPENGL(const BufferSource& source); diff --git a/Core/Graphics/Renderer.inl b/Core/Graphics/Renderer.inl index c8f9f2d..e1c9d8f 100644 --- a/Core/Graphics/Renderer.inl +++ b/Core/Graphics/Renderer.inl @@ -18,7 +18,7 @@ namespace CGL::Graphics #if defined(CGL_RHI_DX11) SetConstantBufferData_D3D11(buffer.Buffer.Get(), static_cast(&data), sizeof(T)); #elif defined(CGL_RHI_OPENGL) - SetConstantBufferData_OPENGL(buffer.Buffer.Get(), static_cast(&data), sizeof(T)); + SetConstantBufferData_OPENGL(buffer.Buffer, static_cast(&data), sizeof(T)); #endif } template diff --git a/Samples/BlankApp/BlankApp.cpp b/Samples/BlankApp/BlankApp.cpp index af96aad..659e4a2 100644 --- a/Samples/BlankApp/BlankApp.cpp +++ b/Samples/BlankApp/BlankApp.cpp @@ -25,7 +25,7 @@ namespace CGL return true; } - void BlankApp::OnUpdate([[maybe_unused]] const SDL_Event& e) + void BlankApp::OnUpdate([[maybe_unused]] const SDL_Event& e, [[maybe_unused]] f32 deltaTime) { // Update app here } diff --git a/Samples/BlankApp/BlankApp.h b/Samples/BlankApp/BlankApp.h index d88f046..2ce5551 100644 --- a/Samples/BlankApp/BlankApp.h +++ b/Samples/BlankApp/BlankApp.h @@ -17,7 +17,7 @@ namespace CGL private: bool OnInit() override final; - void OnUpdate(const SDL_Event& e) override final; + void OnUpdate(const SDL_Event& e, f32 deltaTime) override final; void OnRender() override final; void OnResize(u32 width, u32 height) override final; void OnShutdown() override final; diff --git a/Samples/HelloTriangle/Assets/OpenGL/HelloTriangleVS.vert b/Samples/HelloTriangle/Assets/OpenGL/HelloTriangleVS.vert index da17d46..e8e5b17 100644 --- a/Samples/HelloTriangle/Assets/OpenGL/HelloTriangleVS.vert +++ b/Samples/HelloTriangle/Assets/OpenGL/HelloTriangleVS.vert @@ -1,5 +1,5 @@ #version 460 core -layout (location = 0) in vec4 Position; +layout (location = 0) in vec3 Position; layout (location = 1) in vec3 aColor; out vec3 Color; diff --git a/Samples/HelloTriangle/HelloTriangle.cpp b/Samples/HelloTriangle/HelloTriangle.cpp index ee94c67..9086baa 100644 --- a/Samples/HelloTriangle/HelloTriangle.cpp +++ b/Samples/HelloTriangle/HelloTriangle.cpp @@ -89,13 +89,14 @@ namespace CGL vbs.Type = Graphics::BufferType::Vertex; vbs.TypeSize = sizeof(decltype(vertices)::value_type); vbs.Count = u32(vertices.size()); + vbs.VertexType = typeid(decltype(vertices)::value_type); m_vertexBuffer = GetRenderer()->CreateVertexBuffer(vbs); CGL_LOG(HelloTriangle, Info, "Initialized HelloTriangle App"); return true; } - void HelloTriangle::OnUpdate([[maybe_unused]] const SDL_Event& e) + void HelloTriangle::OnUpdate([[maybe_unused]] const SDL_Event& e, [[maybe_unused]] f32 deltaTime) { } diff --git a/Samples/HelloTriangle/HelloTriangle.h b/Samples/HelloTriangle/HelloTriangle.h index 9c70e76..47a1ca0 100644 --- a/Samples/HelloTriangle/HelloTriangle.h +++ b/Samples/HelloTriangle/HelloTriangle.h @@ -17,7 +17,7 @@ namespace CGL private: bool OnInit() override final; - void OnUpdate(const SDL_Event& e) override final; + void OnUpdate(const SDL_Event& e, f32 deltaTime) override final; void OnRender() override final; void OnResize(u32 width, u32 height) override final; void OnShutdown() override final; diff --git a/Samples/SpinningCube/Assets/OpenGL/SpinningCubeVS.vert b/Samples/SpinningCube/Assets/OpenGL/SpinningCubeVS.vert index 5f36660..7f397b5 100644 --- a/Samples/SpinningCube/Assets/OpenGL/SpinningCubeVS.vert +++ b/Samples/SpinningCube/Assets/OpenGL/SpinningCubeVS.vert @@ -1,9 +1,11 @@ #version 460 core -// Uniform buffers -uniform mat4 WorldMatrix; -uniform mat4 ViewMatrix; -uniform mat4 ProjMatrix; +layout(std140, binding = 0) uniform Matrices +{ + mat4 WorldMatrix; + mat4 ViewMatrix; + mat4 ProjMatrix; +}; layout(location = 0) in vec3 inPosition; layout(location = 1) in vec3 inColor; @@ -19,4 +21,4 @@ void main() gl_Position = position; fragColor = inColor; -} +} \ No newline at end of file diff --git a/Samples/SpinningCube/SpinningCube.cpp b/Samples/SpinningCube/SpinningCube.cpp index 0ecbdac..2d92de7 100644 --- a/Samples/SpinningCube/SpinningCube.cpp +++ b/Samples/SpinningCube/SpinningCube.cpp @@ -1,5 +1,14 @@ #include "SpinningCube.h" #include + +#if defined(CGL_RHI_OPENGL) || defined(CGL_RHI_VULKAN) +#define CGL_UPLOAD_MATRIX(mat) mat +#else +#define CGL_UPLOAD_MATRIX(mat) mat.Transpose() +#endif + + + namespace CGL { CGL_DEFINE_LOG_CATEGORY(SpinningCube); @@ -115,10 +124,11 @@ namespace CGL vbs.Type = Graphics::BufferType::Vertex; vbs.TypeSize = sizeof(decltype(vertices)::value_type); vbs.Count = u32(vertices.size()); + vbs.VertexType = typeid(decltype(vertices)::value_type); m_vertexBuffer = GetRenderer()->CreateVertexBuffer(vbs); // Define cube indices - constexpr std::array indices = + constexpr std::array indices = { 3,1,0, 2,1,3, @@ -161,14 +171,14 @@ namespace CGL } f32 time = 0.0f; - void SpinningCube::OnUpdate([[maybe_unused]] const SDL_Event& e) + void SpinningCube::OnUpdate([[maybe_unused]] const SDL_Event& e,[[maybe_unused]] f32 deltaTime) { - time += 0.0001f; + time += deltaTime; FrameData data { - .World = SM::Matrix::CreateRotationY(time), - .View = m_camera.GetViewMatrix().Transpose(), - .Projection = m_camera.GetProjectionMatrix().Transpose() + .World = CGL_UPLOAD_MATRIX(SM::Matrix::CreateRotationY(time).Transpose()), + .View = CGL_UPLOAD_MATRIX(m_camera.GetViewMatrix()), + .Projection = CGL_UPLOAD_MATRIX(m_camera.GetProjectionMatrix()) }; GetRenderer()->SetConstantBufferData(m_constantBuffer, data); diff --git a/Samples/SpinningCube/SpinningCube.h b/Samples/SpinningCube/SpinningCube.h index 2e8c860..ba8f153 100644 --- a/Samples/SpinningCube/SpinningCube.h +++ b/Samples/SpinningCube/SpinningCube.h @@ -25,7 +25,7 @@ namespace CGL private: bool OnInit() override final; - void OnUpdate(const SDL_Event& e) override final; + void OnUpdate(const SDL_Event& e, f32 deltaTime) override final; void OnRender() override final; void OnResize(u32 width, u32 height) override final; void OnShutdown() override final;