I have two separate UBO's for different types of lights (for a light stage in a deferred rendering system).
These are defined as follows:
//Pointlight UBO
m_pointLightBlockIndex = glGetUniformBlockIndex(shader.getShaderHandle(), "PointLights");
glGetActiveUniformBlockiv(shader.getShaderHandle(), m_pointLightBlockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &m_PointLightBlockSize);
glUniformBlockBinding(shader.getShaderHandle(), m_pointLightBlockIndex, 0);
//Spotlight UBO
m_splBlockIndex = glGetUniformBlockIndex(shader.getShaderHandle(), "SpotLights");
glGetActiveUniformBlockiv(shader.getShaderHandle(), m_splBlockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &m_SpotLightBlockSize);
glUniformBlockBinding(shader.getShaderHandle(), m_splBlockIndex, 0);
//create the buffers
glGenBuffers(1, &m_SLBuffer);
glGenBuffers(1, &m_PLBuffer);
glBindBuffer(GL_UNIFORM_BUFFER, m_SLBuffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(SpotLightData)*m_MaxSpots, nullptr, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, m_PLBuffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(LightData)*m_MaxPoints, nullptr, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
To populate the UBO's I use the following:
void LightUniformBuffer::updatePointLights(int numLights, const LightData * data)
{
glBindBuffer(GL_UNIFORM_BUFFER, m_PLBuffer);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightData)*numLights, data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
void LightUniformBuffer::updateSpotLights(int numLights, const SpotLightData * data)
{
glBindBuffer(GL_UNIFORM_BUFFER, m_SLBuffer);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(SpotLightData)*numLights, data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
And finally to bind them:
void LightUniformBuffer::bindPointLights()
{
glBindBufferBase(GL_UNIFORM_BUFFER, m_pointLightBlockIndex, m_PLBuffer);
}
void LightUniformBuffer::bindSpotLights()
{
glBindBufferBase(GL_UNIFORM_BUFFER, m_splBlockIndex, m_SLBuffer);
}
These buffers are represented as arrays of lights in GLSL, like so:
layout (std140) uniform PointLights
{
LightData points[MAX_NUM_POINT_LIGHTS];
};
layout (std140) uniform SpotLights
{
SpotLightData spots[MAX_NUM_POINT_LIGHTS];
};
Now, when I populate the buffers and use the shader, I found, through using Nsight, that both buffers are using the same set of data, i.e. the spotlight buffer is filled with point light data, and so is useless.
Why is this happening, and how can I fix it?