Browse Source

Render: Allow arbitrary data in uniformbuffer objects

master
Riyyi 3 months ago
parent
commit
b8e4d9ef3f
  1. 2
      src/inferno/asset/model.cpp
  2. 4
      src/inferno/asset/texture.cpp
  3. 37
      src/inferno/render/uniformbuffer.cpp
  4. 8
      src/inferno/render/uniformbuffer.h

2
src/inferno/asset/model.cpp

@ -40,7 +40,7 @@ std::shared_ptr<Model> Model::create(std::string_view path)
void Model::processScene(std::shared_ptr<Model> model, const aiScene* scene)
{
VERIFY(scene->HasMeshes(), "malformed model");
VERIFY(scene->mNumTextures < 2, "unsupported model type");
VERIFY(scene->mNumTextures < 2, "unsupported model type: {}/1", scene->mNumTextures);
if (scene->mNumTextures == 1) {
aiTexture* texture = scene->mTextures[0];

4
src/inferno/asset/texture.cpp

@ -330,8 +330,8 @@ void TextureFramebuffer::createImpl()
m_dataType, // Texture source datatype
NULL); // Image data
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Unbind texture object
glBindTexture(GL_TEXTURE_2D, 0);

37
src/inferno/render/uniformbuffer.cpp

@ -37,9 +37,21 @@ Uniformbuffer::~Uniformbuffer()
// -----------------------------------------
void Uniformbuffer::setLayout(std::string_view blockName, const UniformbufferBlock& block)
{
VERIFY(block.size && block.bindingPoint && block.uniformLocations.size(),
"invalid uniformbuffer block definition: {}", blockName);
VERIFY(block.bindingPoint < m_maxBindingPoints,
"uniformbuffer exceeded binding points: {}/{}", block.bindingPoint, m_maxBindingPoints);
m_blocks[blockName] = block;
}
void Uniformbuffer::setLayout(std::string_view blockName, uint8_t bindingPoint, const BufferLayout& layout)
{
VERIFY(bindingPoint < m_maxBindingPoints, "{} < {}", bindingPoint, m_maxBindingPoints);
VERIFY(bindingPoint < m_maxBindingPoints,
"uniformbuffer exceeded binding points: {}/{}", bindingPoint, m_maxBindingPoints);
if (!exists(blockName)) {
m_blocks[blockName] = {};
@ -212,34 +224,17 @@ void Uniformbuffer::create(std::string_view blockName)
void Uniformbuffer::setValue(std::string_view blockName, std::string_view member, bool value)
{
CHECK_SET_CALL(blockName, member);
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);
setValue(blockName, member, static_cast<uint32_t>(value), sizeof(uint32_t));
}
void Uniformbuffer::setValue(std::string_view blockName, std::string_view member, glm::mat2 value)
{
CHECK_SET_CALL(blockName, member);
// 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);
setValue(blockName, member, static_cast<glm::mat4>(value), sizeof(glm::vec4) * 2);
}
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);
setValue(blockName, member, static_cast<glm::mat4>(value), sizeof(glm::vec4) * 3);
}
} // namespace Inferno

8
src/inferno/render/uniformbuffer.h

@ -4,6 +4,7 @@
* SPDX-License-Identifier: MIT
*/
#include <cstddef> // size_t
#include <cstdint> // uint8_t, uint32_t
#include <string>
#include <string_view>
@ -36,16 +37,17 @@ public:
Uniformbuffer(s);
~Uniformbuffer();
void setLayout(std::string_view blockName, const UniformbufferBlock& block);
void setLayout(std::string_view blockName, uint8_t bindingPoint, const BufferLayout& layout);
void create(std::string_view blockName);
template<typename T>
void setValue(std::string_view blockName, std::string_view member, T value)
template<typename T> // Capture value by reference, instead of decaying to pointer
void setValue(std::string_view blockName, std::string_view member, T&& value, size_t size = 0)
{
CHECK_SET_CALL(blockName, member);
glBindBuffer(GL_UNIFORM_BUFFER, block.id);
glBufferSubData(GL_UNIFORM_BUFFER, block.uniformLocations.at(member.data()), sizeof(T), &value);
glBufferSubData(GL_UNIFORM_BUFFER, block.uniformLocations.at(member.data()), (size) ? size : sizeof(T), &value);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
// Exceptions:

Loading…
Cancel
Save