Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No display from glDrawElements

Tags:

c++

opengl

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.

like image 410
Neros Avatar asked Jun 19 '13 12:06

Neros


2 Answers

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.

like image 137
Christian Rau Avatar answered Oct 14 '22 07:10

Christian Rau


I think this:

unsigned int index[] = {
    1, 2, 3,
};

should be this:

unsigned int index[] = {
    0, 1, 2,
};
like image 4
bwroga Avatar answered Oct 14 '22 06:10

bwroga