Search code examples
iosopengl-es-2.0opengl-3

why can't I get glDrawElements to draw with VBOs in OpenGLES 2.0?


I'm trying to do a simple test in iOS with OpenGL (ES 2.0 but should be the same if it were regular GL 3.5 with core profile or basically any implementation without fixed pipeline):

I have everything setup correctly (context, shaders, mvl matrix, etc) and successfully render a triangle via glDrawArrays, with VBO like so:

- (void)loadActors
{           
            GLfloat triangle1[] = {
                -1.0, -2.0, 0.0,
                3.0, 0.0, 0.0,
                0.0, 1.5, 0.0
            };

            GLuint VBO;
            glGenBuffers(1, &VBO);

            glBindBuffer(GL_ARRAY_BUFFER, VBO);
            glBufferData(GL_ARRAY_BUFFER, sizeof(triangle1), triangle1, GL_STATIC_DRAW);
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*3, 0);
            glEnableVertexAttribArray(0);
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(1., 0., 0., 1.);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(_program);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

    glDrawArrays(GL_TRIANGLES, 0, 3);
}

Now, I'm trying to enable indices. So I create another (global) array which merely holds 0,1,2 and try to use that to index into the VBO. Like so:

- (void)loadActors
{ 
            GLfloat triangle1[] = {
                -1.0, -2.0, 0.0,
                3.0, 0.0, 0.0,
                0.0, 1.5, 0.0
            };

            indicesG = malloc(sizeof(GLuint)*3);
            indicesG[0] = 0;
            indicesG[1] = 1;
            indicesG[2] = 2;

            GLuint VBO[2];
            glGenBuffers(2, VBO);

            glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
            glBufferData(GL_ARRAY_BUFFER, sizeof(triangle1), triangle1, GL_STATIC_DRAW);
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*3, 0);
            glEnableVertexAttribArray(0);

            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[1]);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicesG), indicesG, GL_STATIC_DRAW);
}


- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(1., 0., 0., 1.);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    glUseProgram(_program);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
}

I'd expect that the index array merely calls vertices 0,1 and 2 of the VBO, resulting in the same triangle I get if I was not using GL_ELEMENT_ARRAY_BUFFER. But instead, nothing appears to be drawn.

What am I missing?


Solution

  • The problem was actually my computing of the indicesG array size. I was doing sizeof(indicesG) and should have done sizeof(GLuint)*3

    It works with glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*3, indicesG, GL_STATIC_DRAW);