Browse Source

Render: Allow arbitrary data in uniformbuffer objects

master
Riyyi 2 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) void Model::processScene(std::shared_ptr<Model> model, const aiScene* scene)
{ {
VERIFY(scene->HasMeshes(), "malformed model"); 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) { if (scene->mNumTextures == 1) {
aiTexture* texture = scene->mTextures[0]; aiTexture* texture = scene->mTextures[0];

4
src/inferno/asset/texture.cpp

@ -330,8 +330,8 @@ void TextureFramebuffer::createImpl()
m_dataType, // Texture source datatype m_dataType, // Texture source datatype
NULL); // Image data NULL); // Image data
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Unbind texture object // Unbind texture object
glBindTexture(GL_TEXTURE_2D, 0); 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) 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)) { if (!exists(blockName)) {
m_blocks[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) void Uniformbuffer::setValue(std::string_view blockName, std::string_view member, bool value)
{ {
CHECK_SET_CALL(blockName, member); setValue(blockName, member, static_cast<uint32_t>(value), sizeof(uint32_t));
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);
} }
void Uniformbuffer::setValue(std::string_view blockName, std::string_view member, glm::mat2 value) void Uniformbuffer::setValue(std::string_view blockName, std::string_view member, glm::mat2 value)
{ {
CHECK_SET_CALL(blockName, member); setValue(blockName, member, static_cast<glm::mat4>(value), sizeof(glm::vec4) * 2);
// 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) void Uniformbuffer::setValue(std::string_view blockName, std::string_view member, glm::mat3 value)
{ {
CHECK_SET_CALL(blockName, member); setValue(blockName, member, static_cast<glm::mat4>(value), sizeof(glm::vec4) * 3);
// 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 } // namespace Inferno

8
src/inferno/render/uniformbuffer.h

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

Loading…
Cancel
Save