Reputation: 121
I'm trying to draw a cube using indexed draw in OpenGL 3.3. But it does not show up right... Here is what I tried doing.
GLfloat vertices01[] = {
-1.0f,1.0f,0.0f,
-1.0f,-1.0f,0.0f,
1.0f,1.0f,0.0f,
1.0f,-1.0f,0.0f,
-1.0f,1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,1.0f,-1.0f,
1.0f,-1.0f,-1.0f
};
unsigned int indices01[] = {
0, 2, 3, 1,
2, 6, 7, 3,
6, 4, 5, 7,
4, 0, 1, 5,
0, 4, 6, 2,
1, 5, 7, 3
};
Mesh* obj3 = new Mesh();
obj3->CreateMesh(vertices01, indices01, 24, 24);
meshList.push_back(obj3);
meshList[0]->RenderMesh();
//in mesh class indexCount = numOfIndices;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0])*numOfIndices, indices, GL_STATIC_DRAW);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0])*numOfVertices, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindVertexArray(VAO);
//bind ibo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glDrawElements(GL_TRIANGLES,indexCount, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
the output shows a partial cube whose each side had one triangle each and also a triangle going through it's diagonal
Upvotes: 0
Views: 5116
Reputation: 210878
If you use a compatibility profile context, then you can keep your indices an use GL_QUADS
instead of GL_TRIANGLES
. But that's deprecated (Legacy OpenGL ).
Since the primitive type is GL_TRIANGLES
, each side of the cube has to be formed by 2 triangles. See Triangle primitives.
Change the index buffer to solve the issue:
unsigned int indices01[] = {
0, 2, 3, 0, 3, 1,
2, 6, 7, 2, 7, 3,
6, 4, 5, 6, 5, 7,
4, 0, 1, 4, 1, 5,
0, 4, 6, 0, 6, 2,
1, 5, 7, 1, 7, 3,
};
An alternative solution would be to use the primitive type GL_TRIANGLE_STRIP
and a Primitive Restart index.
Enable primitive restart and define a restart index:
e.g.
glEnable( GL_PRIMITIVE_RESTART );
glPrimitiveRestartIndex( 99 );
Define 2 triangle strips, which are separated by the restart index:
unsigned int indices01[] = {
0, 1, 2, 3, 6, 7, 4, 5,
99, // 99 is the restart index
7, 3, 5, 1, 4, 0, 6, 2
};
int indexCOunt = 17;
And draw the elements:
glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0);
Note, the Index buffer binding is stored in the Vertex Array Object.
So it is sufficient to bind the index buffer once, when the VAO is setup:
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
// [...]
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
// [...]
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); <---- delete this
glBindVertexArray(0);
Then it is superfluous to bind the index buffer again, before the draw call:
glBindVertexArray(VAO);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); <---- now this is superfluous
glDrawElements(GL_TRIANGLES,indexCount, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Upvotes: 3