Browse Source

Render: Add more value setter types for uniformbuffer objects

master
Riyyi 4 months ago
parent
commit
b2ed951b1e
  1. 2
      src/inferno/application.cpp
  2. 41
      src/inferno/render/uniformbuffer.cpp
  3. 24
      src/inferno/render/uniformbuffer.h
  4. 2
      src/inferno/scene/scene.cpp

2
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);

41
src/inferno/render/uniformbuffer.cpp

@ -5,11 +5,13 @@
*/
#include <cstddef> // size_t
#include <cstdint> // int32_t, uint8_t
#include <cstdint> // int32_t, uint32_t, uint8_t
#include <string_view>
#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<uint32_t>(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<glm::mat4>(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<glm::mat4>(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

24
src/inferno/render/uniformbuffer.h

@ -9,11 +9,19 @@
#include <string_view>
#include <unordered_map>
#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<typename T>
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(); }

2
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();

Loading…
Cancel
Save