SOLVED
I've been reading through the OpenGL instancing tutorial on learnopengl.com, and I'm trying to implement it using glDrawElementsInstanced, since I have Assimp doing my mesh loading. My problem is that the "floor" (see the wood-textured model in the attached pic) is drawing perfectly fine, but the positional offsets for instancing that I'm passing to OpenGL have no effect. What could be the problem? Thanks in advance!
floorVS.glsl:
#version 430
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoords;
layout (location = 3) in vec3 offset; // For 3D instancing
layout (std140, binding = 0) uniform Matrices {
mat4 projection;
mat4 view;
};
uniform mat4 model;
out vec2 TexCoords;
out vec3 FragPos;
out vec3 Normal;
void main() {
gl_Position = projection * view * model * vec4(position + offset, 1.0); // Add provided offset
FragPos = vec3(model * vec4(position, 1.0f));
Normal = mat3(transpose(inverse(model))) * normal;
TexCoords = texCoords;
}
I have a Model class that contains numerous Mesh classes (since a complete model may contain several objects), so I need to make sure each mesh gets the offset data:
This function is run per mesh to separately add instancing data:
void Mesh::SetInstancing(const std::vector<glm::vec3>& instanceOffsets) {
m_instanceOffsets = instanceOffsets;
glGenBuffers(1, &m_instanceVBO);
glBindBuffer(GL_ARRAY_BUFFER, m_instanceVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * m_instanceOffsets.size(), &m_instanceOffsets.at(0), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Vertex Instance offset
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, m_instanceVBO);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribDivisor(3, 1); // Tell OpenGL this is an instanced vertex attribute.
glBindVertexArray(0);
}
Now to draw the mesh. The bindTexures function is irrelevant to my question (it just loops through a vector of Textures and binds them):
void Mesh::DrawInstanced(const Shader& shader) {
bindTextures(shader);
// Draw instanced mesh
glBindVertexArray(m_vao);
glDrawElementsInstanced(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, 0, m_instanceOffsets.size());
glBindVertexArray(0);
}
Picture:
There should be 2 floor object being rendered here (and the displayed floor should not be at the origin):
[attachment=33104:help.png]
Please let me know of any more clarification is needed!