I am trying to render multiple text labels in a single draw call. To that end I pass the matrices of each label in a uniform array. For each vertex of the text meshes a "labelIndex" attribute is passed to select the correct matrix from the array.
But when I check the VS Input in RenderDoc the labelIndex is 0 for every vertex as if it is uninitialized. What am I missing when setting up the labelIndex vertex attribute?
uint labelIdx = 0;
std::vector<uint> labelIndices;
for (auto& label : Labels)
{
...
for (unsigned int i = 0; i < wcslen(label.Text); i++)
{
...
labelIndices.push_back(labelIdx);
labelIndices.push_back(labelIdx);
labelIndices.push_back(labelIdx);
labelIndices.push_back(labelIdx);
}
labelIdx++;
}
glGenBuffers(1, &LabelIndexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, LabelIndexBufferID);
glBufferData(GL_ARRAY_BUFFER, labelIndices.size() * sizeof(uint), &labelIndices[0], GL_STATIC_DRAW);
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
...
// 2nd attribute buffer : Label indices
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, LabelIndexBufferID);
glVertexAttribIPointer(1, 1, GL_UNSIGNED_INT, 0, (void*)0);
// element buffer
glGenBuffers(1, &ElementBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint), &indices[0], GL_DYNAMIC_DRAW);
glBindVertexArray(0);
Rendering:
glUseProgram(ShaderID);
...
glUniformMatrix4fv(ParentMatrixLocation, 1, GL_FALSE, glm::value_ptr(Renderer::VP));
glUniformMatrix4fv(LabelMatricesLocation, Labels.size(), GL_FALSE, glm::value_ptr(LabelMatrices.get()[0]));
glBindVertexArray(VertexArrayID);
glDrawElements(
GL_TRIANGLES,
CharacterCount * 6,
GL_UNSIGNED_INT,
(void*)0
);
glBindVertexArray(0);
Vertex Shader:
#version 430 core
layout(location = 0) in vec4 PositionUV;
layout(location = 1) in uint LabelIndex;
uniform mat4 ParentMatrix;
uniform mat4 LabelMatrices[200];
out vec2 UV;
void main()
{
gl_Position = ParentMatrix * LabelMatrices[LabelIndex] * vec4(PositionUV.xy, 0, 1);
UV = PositionUV.zw;
}
Edit:
I dont know what is going on here. When I get the buffer after filling it:
uint* data = NULL;
data = new uint[labelIndices.size()];
for (int i = 0; i < labelIndices.size(); i++)
{
data[i] = 0;
}
glGetBufferSubData(GL_ARRAY_BUFFER, 0, labelIndices.size() * sizeof(TextVertex), data);
I look at data
and the LabelIndex is set to the appropriate label.
But when grabbing the frame in RenderDoc the LabelIndex is still 0.
When I initialize LabelIndex with, say, 7 and do not increment it in the loop, LabelIndex will correctly have the value 7 in the VS Input. It's bizarre.