Interleaving Arrays in OpenGL
- by Benjamin Danger Johnson
In my pursuit to write code that matches todays OpenGL standards I have found that I am completely clueless about interleaving arrays. I've tried and debugged just about everywhere I can think of but I can't get my model to render using interleaved arrays (It worked when it was configuered to use multiple arrays) Now I know that all the data is properly being parsed from an obj file and information is being copied properly copied into the Vertex object array, but I still can't seem to get anything to render. Below is the code for initializing a model and drawing it (along with the Vertex struct for reference.)
Vertex:
struct Vertex {
glm::vec3 position;
glm::vec3 normal;
glm::vec2 uv;
glm::vec3 tangent;
glm::vec3 bitangent;
};
Model Constructor:
Model::Model(const char* filename) {
bool result = loadObj(filename, vertices, indices);
glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &elementbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short), &indices[0], GL_STATIC_DRAW);
}
Draw Model:
Model::Draw(ICamera camera) {
GLuint matrixID = glGetUniformLocation(programID, "mvp");
GLuint positionID = glGetAttribLocation(programID, "position_modelspace");
GLuint uvID = glGetAttribLocation(programID, "uv");
GLuint normalID = glGetAttribLocation(programID, "normal_modelspace");
GLuint tangentID = glGetAttribLocation(programID, "tangent_modelspace");
GLuint bitangentID = glGetAttribLocation(programID, "bitangent_modelspace");
glm::mat4 projection = camera->GetProjectionMatrix();
glm::mat4 view = camera->GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 mvp = projection * view * model;
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &mvp[0][0]);
glBindVertexArray(vertexArrayID);
glEnableVertexAttribArray(positionID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(positionID, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertices[0].position);
glEnableVertexAttribArray(uvID);
glVertexAttribPointer(uvID, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertices[0].uv);
glEnableVertexAttribArray(normalID);
glVertexAttribPointer(normalID, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertices[0].normal);
glEnableVertexAttribArray(tangentID);
glVertexAttribPointer(tangentID, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertices[0].tangent);
glEnableVertexAttribArray(bitangentID);
glVertexAttribPointer(bitangentID, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertices[0].bitangent);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, (void*)0);
glDisableVertexAttribArray(positionID);
glDisableVertexAttribArray(uvID);
glDisableVertexAttribArray(normalID);
glDisableVertexAttribArray(tangentID);
glDisableVertexAttribArray(bitangentID);
}