#include <Renderer/Shader/UBOShaderInterface.h>
#include <assert.h>
void UBOShaderInterface::Create(const std::string &uniformBlockName, Shader* shader, std::vector<std::string> &uniformNames)
{
m_pShader = shader;
m_blockIndex = glGetUniformBlockIndex(m_pShader->GetProgID(), uniformBlockName.c_str());
assert(m_blockIndex != GL_INVALID_INDEX);
glGetActiveUniformBlockiv(m_pShader->GetProgID(), m_blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &m_blockSize);
// Get block names
std::vector<char const*> uniformNamesCString;
const unsigned int numNames = uniformNames.size();
for(unsigned int i = 0; i < numNames; i++)
uniformNamesCString.push_back(uniformNames[i].c_str());
unsigned int* indices = new unsigned int[numNames];
glGetUniformIndices(m_pShader->GetProgID(), uniformNames.size(), &uniformNamesCString[0], indices);
// Query offsets and associate names to the offsets
int* offsets = new int[numNames];
glGetActiveUniformsiv(m_pShader->GetProgID(), numNames, indices, GL_UNIFORM_OFFSET, offsets);
delete[] indices;
for(unsigned int i = 0; i < numNames; i++)
m_uniformNameToOffset[uniformNames[i]] = offsets[i];
delete[] offsets;
}
void UBOShaderInterface::SetUpBuffer(VBO &buffer)
{
assert(!buffer.Created());
buffer.Create();
buffer.Bind(GL_UNIFORM_BUFFER);
glBufferData(GL_UNIFORM_BUFFER, m_blockSize, NULL, GL_STREAM_DRAW);
// Allocate VBO using this size
buffer.Unbind();
}
void UBOShaderInterface::SetBindingIndex(unsigned int index)
{
m_bufferBindIndex = index;
glUniformBlockBinding(m_pShader->GetProgID(), m_blockIndex, m_bufferBindIndex);
}
int UBOShaderInterface::GetBlockSize() const
{
return m_blockSize;
}
Shader* UBOShaderInterface::GetShader() const
{
return m_pShader;
}
void UBOShaderInterface::BindBufferToSetIndex(VBO &buffer)
{
glBindBufferBase(GL_UNIFORM_BUFFER, m_bufferBindIndex, buffer.GetID());
}
void UBOShaderInterface::UnbindSetIndex()
{
glBindBufferBase(GL_UNIFORM_BUFFER, m_bufferBindIndex, 0);
}
void UBOShaderInterface::SetUniform(const std::string &name, GLintptr size, GLvoid* param)
{
glBufferSubData(GL_UNIFORM_BUFFER, m_uniformNameToOffset[name], size, param);
}
void UBOShaderInterface::SetUniformf(const std::string &name, float param)
{
glBufferSubData(GL_UNIFORM_BUFFER, m_uniformNameToOffset[name], sizeof(float), ¶m);
}
void UBOShaderInterface::SetUniformv2f(const std::string &name, const Vec2f ¶ms)
{
glBufferSubData(GL_UNIFORM_BUFFER, m_uniformNameToOffset[name], 2 * sizeof(float), ¶ms);
}
void UBOShaderInterface::SetUniformv3f(const std::string &name, const Vec3f ¶ms)
{
glBufferSubData(GL_UNIFORM_BUFFER, m_uniformNameToOffset[name], 3 * sizeof(float), ¶ms);
}
void UBOShaderInterface::SetUniformv3f(const std::string &name, const Color3f ¶ms)
{
glBufferSubData(GL_UNIFORM_BUFFER, m_uniformNameToOffset[name], 3 * sizeof(float), ¶ms);
}
void UBOShaderInterface::SetUniformv4f(const std::string &name, const Vec4f ¶ms)
{
glBufferSubData(GL_UNIFORM_BUFFER, m_uniformNameToOffset[name], 4 * sizeof(float), ¶ms);
}
void UBOShaderInterface::SetUniformv4f(const std::string &name, const Color4f ¶ms)
{
glBufferSubData(GL_UNIFORM_BUFFER, m_uniformNameToOffset[name], 4 * sizeof(float), ¶ms);
}