diff --git a/src/inferno/application.cpp b/src/inferno/application.cpp index 7d1e47f..a6ebc69 100644 --- a/src/inferno/application.cpp +++ b/src/inferno/application.cpp @@ -217,7 +217,7 @@ int Application::run() RenderCommand::clearBit(m_screenFramebuffer->clearBit()); Renderer2D::the().setEnableDepthBuffer(false); - Uniformbuffer::the().setFloat("Camera", "u_projectionView", matIdentity); + Uniformbuffer::the().setValue("Camera", "u_projectionView", matIdentity); Renderer2D::the().drawQuad(transformIdentity, vectorOne, m_framebuffer->texture(0)); Renderer2D::the().endScene(); Renderer2D::the().setEnableDepthBuffer(true); diff --git a/src/inferno/render/uniformbuffer.cpp b/src/inferno/render/uniformbuffer.cpp index 1f3b2d3..d6ed865 100644 --- a/src/inferno/render/uniformbuffer.cpp +++ b/src/inferno/render/uniformbuffer.cpp @@ -5,11 +5,13 @@ */ #include // size_t -#include // int32_t, uint8_t +#include // int32_t, uint32_t, uint8_t #include #include "glad/glad.h" -#include "glm/gtc/type_ptr.hpp" // glm::value_ptr +#include "glm/ext/matrix_float2x2.hpp" // glm::mat2 +#include "glm/ext/matrix_float3x3.hpp" // glm::mat3 +#include "glm/gtc/type_ptr.hpp" // glm::value_ptr #include "ruc/meta/assert.h" #include "inferno/render/buffer.h" @@ -44,6 +46,7 @@ void Uniformbuffer::setLayout(std::string_view blockName, uint8_t bindingPoint, } UniformbufferBlock& block = m_blocks[blockName]; + block.bindingPoint = bindingPoint; // Example block layout: // - mat3 @@ -207,18 +210,36 @@ void Uniformbuffer::create(std::string_view blockName) glBindBufferBase(GL_UNIFORM_BUFFER, block.bindingPoint, block.id); } -void Uniformbuffer::setFloat(std::string_view blockName, std::string_view member, glm::mat4 matrix) +void Uniformbuffer::setValue(std::string_view blockName, std::string_view member, bool value) { - VERIFY(exists(blockName), "uniformbuffer block doesnt exist"); + CHECK_SET_CALL(blockName, member); - const UniformbufferBlock& block = m_blocks[blockName]; + glBindBuffer(GL_UNIFORM_BUFFER, block.id); + uint32_t tmp = static_cast(value); + glBufferSubData(GL_UNIFORM_BUFFER, block.uniformLocations.at(member.data()), sizeof(uint32_t), &tmp); + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} - VERIFY(block.uniformLocations.find(member.data()) != block.uniformLocations.end(), - "uniformbuffer block member doesnt exist"); +void Uniformbuffer::setValue(std::string_view blockName, std::string_view member, glm::mat2 value) +{ + CHECK_SET_CALL(blockName, member); - // Note: Uniformbuffers are bound to a binding point for the entire pipeline, - // it remains accessible without needing to rebind it every time - glBufferSubData(GL_UNIFORM_BUFFER, block.uniformLocations.at(member.data()), sizeof(glm::mat4), glm::value_ptr(matrix)); + // Write only the first 2 rows (32 bytes), additional values are padded with 0 + glBindBuffer(GL_UNIFORM_BUFFER, block.id); + glm::mat4 tmp = static_cast(value); + glBufferSubData(GL_UNIFORM_BUFFER, block.uniformLocations.at(member.data()), sizeof(glm::vec4) * 2, glm::value_ptr(tmp)); + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} + +void Uniformbuffer::setValue(std::string_view blockName, std::string_view member, glm::mat3 value) +{ + CHECK_SET_CALL(blockName, member); + + // Write only the first 3 rows (48 bytes), additional values are padded with 0 + glBindBuffer(GL_UNIFORM_BUFFER, block.id); + glm::mat4 tmp = static_cast(value); + glBufferSubData(GL_UNIFORM_BUFFER, block.uniformLocations.at(member.data()), sizeof(glm::vec4) * 3, glm::value_ptr(tmp)); + glBindBuffer(GL_UNIFORM_BUFFER, 0); } } // namespace Inferno diff --git a/src/inferno/render/uniformbuffer.h b/src/inferno/render/uniformbuffer.h index 503bd19..314098e 100644 --- a/src/inferno/render/uniformbuffer.h +++ b/src/inferno/render/uniformbuffer.h @@ -9,11 +9,19 @@ #include #include -#include "glm/ext/matrix_float4x4.hpp" // glm::mat4 +#include "glad/glad.h" +#include "glm/ext/matrix_float2x2.hpp" // glm::mat2 +#include "glm/ext/matrix_float3x3.hpp" // glm::mat3 #include "ruc/singleton.h" #include "inferno/render/buffer.h" +#define CHECK_SET_CALL(blockName, member) \ + VERIFY(exists(blockName), "uniformbuffer block doesnt exist"); \ + const UniformbufferBlock& block = m_blocks[blockName]; \ + VERIFY(block.uniformLocations.find(member.data()) != block.uniformLocations.end(), \ + "uniformbuffer block member doesnt exist"); + namespace Inferno { struct UniformbufferBlock { @@ -31,7 +39,19 @@ public: void setLayout(std::string_view blockName, uint8_t bindingPoint, const BufferLayout& layout); void create(std::string_view blockName); - void setFloat(std::string_view blockName, std::string_view member, glm::mat4 matrix); + template + void setValue(std::string_view blockName, std::string_view member, T value) + { + CHECK_SET_CALL(blockName, member); + + glBindBuffer(GL_UNIFORM_BUFFER, block.id); + glBufferSubData(GL_UNIFORM_BUFFER, block.uniformLocations.at(member.data()), sizeof(T), &value); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + } + // Exceptions: + void setValue(std::string_view blockName, std::string_view member, bool value); + void setValue(std::string_view blockName, std::string_view member, glm::mat2 value); + void setValue(std::string_view blockName, std::string_view member, glm::mat3 value); bool exists(std::string_view blockName) const { return m_blocks.find(blockName) != m_blocks.end(); } diff --git a/src/inferno/scene/scene.cpp b/src/inferno/scene/scene.cpp index 2a637cf..314f10f 100644 --- a/src/inferno/scene/scene.cpp +++ b/src/inferno/scene/scene.cpp @@ -85,7 +85,7 @@ void Scene::update(float deltaTime) void Scene::render() { auto [projection, view] = CameraSystem::the().projectionView(); - Uniformbuffer::the().setFloat("Camera", "u_projectionView", projection * view); + Uniformbuffer::the().setValue("Camera", "u_projectionView", projection * view); RendererCubemap::the().beginScene(projection, view); // camera, lights, environment RenderSystem::the().render();