I am trying to make instanced rendering work with multiple differently-sized 'quads' (two connected triangles). I am setting up a VAO with a vertex data VBO and a transform data VBO, along side an index EBO to stitch these vertices together. For some reason, using the transform VBO makes the glDrawElementsInstanced ignore the actual sizes of the vertex data and just uses one set for all 'quads'. It looks like this.
The quad on the right should be half the size of the left one. It seems like opengl picks the larger size regardless of how I add the vertex data.
Here is my opengl render init:
Renderer::Renderer(Shader* staticShader)
: m_ShaderStatic(staticShader)
{
// Generate all needed buffers
glGenVertexArrays(1, &m_VAO);
glGenBuffers(1, &m_VertVBO);
glGenBuffers(1, &m_TransVBO);
glGenBuffers(1, &m_EBO);
// Bind VAO
glBindVertexArray(m_VAO);
// Bind and set up vertex VBO
glBindBuffer(GL_ARRAY_BUFFER, m_VertVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GL_FLOAT) * 2, NULL, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 2, (void*)0);
glEnableVertexAttribArray(0);
// Bind and set up transform VBO
glBindBuffer(GL_ARRAY_BUFFER, m_TransVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GL_FLOAT) * 2, NULL, GL_DYNAMIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 2, (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribDivisor(1, 1);
// Bind and set up EBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * 6, NULL, GL_DYNAMIC_DRAW);
// Unbind everything
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
Here is the AddStatic function to give the buffers data:
void Renderer::AddStatic(float x, float y, float width, float height, float rotation)
{
// Bind VAO
glBindVertexArray(m_VAO);
// Configure vertex data
for (int i = 0; i < 8; i+=2)
{
m_Vertices.push_back(QuadVertices[i] * width);
m_Vertices.push_back(QuadVertices[i+1] * height);
}
// Set vertex data
glBindBuffer(GL_ARRAY_BUFFER, m_VertVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * m_Vertices.size(), m_Vertices.data(), GL_DYNAMIC_DRAW);
// Configure transform data
m_Transforms.push_back(x);
m_Transforms.push_back(y);
// Set transform data
glBindBuffer(GL_ARRAY_BUFFER, m_TransVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * m_Transforms.size(), m_Transforms.data(), GL_DYNAMIC_DRAW);
// Configure index data
m_Indices.push_back(0 + 4 * m_QuadCount);
m_Indices.push_back(1 + 4 * m_QuadCount);
m_Indices.push_back(3 + 4 * m_QuadCount);
m_Indices.push_back(3 + 4 * m_QuadCount);
m_Indices.push_back(2 + 4 * m_QuadCount);
m_Indices.push_back(0 + 4 * m_QuadCount);
// Set index data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * m_Indices.size(), m_Indices.data(), GL_DYNAMIC_DRAW);
// Unbind all
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Increment the amount of quads loaded
m_QuadCount++;
}
Here is the actual draw call:
void Renderer::Render()
{
// Bind VAO
glBindVertexArray(m_VAO);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
// Bind Shader
m_ShaderStatic->use();
// Draw
glDrawElementsInstanced(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0, m_QuadCount);
}
And finally, here is my vertex shader if that is needed.
#version 330 core
layout (location = 0) in vec2 vertex;
layout (location = 1) in vec2 transform;
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
out vec4 color;
void main()
{
gl_Position = projection * view * vec4(vertex + transform, 0.0, 1.0);
color = vec4(1.0, 1.0, 1.0, 1.0);
}
I dont know why a simple transform would affect the actual size of my quads, all it does is just add a set x/y to them.
Edit: If I set the transform values i put into the vector to 0, it renders the squares at the correct width/height, albeit at the wrong location.
