When I use glDrawArrays I get a triangle in the middle of my screen, as expected. But when I try to use glDrawElements nothing comes up at all.
I have tried all sorts of things like reordering the gl calls, moving the attribute pointers, and even hard coding verts and index appears to do nothing as shown in my code.
This code runs once:
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
//return -1;
}
glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4); // 4x antialiasing
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); // We want OpenGL 3.3
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE); //We don't want the old OpenGL
// Open a window and create its OpenGL context
if( !glfwOpenWindow( mApplication->getWindowWidth(), mApplication->getWindowHeight(), 0,0,0,0, 32,0, GLFW_WINDOW ) )
{
fprintf( stderr, "Failed to open GLFW window\n" );
glfwTerminate();
//return -1;
}
// Initialize GLEW
glewExperimental=true; // Needed in core profile
if (glewInit() != GLEW_OK)
{
fprintf( stderr, "Failed to initialize GLEW\n");
//return -1;
}
glfwSetWindowTitle( "Hello World" );
glViewport( 0, 0, mApplication->getWindowWidth(), mApplication->getWindowHeight());
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.0f, 0.0f, 0.4f, 0.0f); // colour to use when clearing
This runs every step:
float verts[] = {
-0.5f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f,
};
unsigned int index[] = {
1, 2, 3,
};
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// VAO
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
// VBO
glGenBuffers(1, &VBO );
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts) * sizeof(float), verts, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
// IBO
glGenBuffers(1, &IBO );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index) * sizeof(unsigned int), index, GL_STATIC_DRAW);
glDrawArrays(GL_TRIANGLES, 0, 3); // this works
//glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &index); // this doesnt
glfwSwapBuffers();
This is a very cut down version of what I am trying to achieve but the problem is exactly the same.
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &index); // this doesn't work
Of course it doesn't. You are storing your indices in a buffer object. In the same way the last pointer argument to glVertexAttribPointer
is interpreted as an offset into the currently bound GL_ARRAY_BUFFER
(if one is bound), the last pointer argument to glDrawElements
is interpreted as an offset into the buffer currently bound to GL_ELEMENT_ARRAY_BUFFER
. You already properly store your indices into that, so you have to tell `glDrawElements
that the indices start at offset 0 of this buffer, like you did with glVertexAttribPointer
:
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
EDIT: And like bwroga points out in his answer, you should start your indices with 0
instead of 1
.
EDIT: And you also pass the wrong sizes into glBufferData
. You use sizeof(verts) * sizeof(floats)
(and likewise for index
), but verts
is an array and the sizeof
an array already is the size of the whole thing in bytes and not just the number of elements, so it should rather just be sizeof(verts)
, otherwise the glBufferData
will try to read data beyond the actual array size which is undefined behaviour (and in your case unfortunately seems to work).
EDIT: And of course as Grimmy points out in his comment you shouldn't recreate your VAO and VBO each time you draw, that's initialization stuff. But this is more of a conceptual/optimization error (albeit a severe one) rather than an actual "non-working" error.
I think this:
unsigned int index[] = {
1, 2, 3,
};
should be this:
unsigned int index[] = {
0, 1, 2,
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With