Search code examples
openglrenderingvertex-buffer

The classic "nothing is getting rendered" OpenGL problem


I know, it's quite frustrating. I can't get anything to show up in my OpenGL application - all I see is an empty viewport.

When I first started writing the application, I was manually drawing the vertices (using GL_QUADS) and everything worked fine. Then I decided to switch to VBOs (Vertex Buffer Objects). Now nothing works.

Here is the structure for vertices:

struct SimpleVertex
{
    GLfloat x, y;
    GLbyte r, g, b, a;
};

As you can see, it is very simple - x and y coords for the vertices and RGBA color data. Here is the code that fills the vertex and index buffer:

const SimpleVertex rect_vertices[] = {
    { -0.8,  0.8, 0, 255, 0, 128 },
    {  0.8,  0.8, 0, 255, 0, 128 },
    {  0.8, -0.8, 0, 255, 0, 128 },
    { -0.8, -0.8, 0, 255, 0, 128 }
};

const GLuint rect_indices[] = {
    0, 1, 2, 3
};

GLuint vertices;
GLuint indices;

glGenBuffers(1, &vertices);
glBindBuffer(GL_ARRAY_BUFFER, vertices);
glBufferData(GL_ARRAY_BUFFER,
             sizeof(rect_vertices),
             rect_vertices,
             GL_STATIC_DRAW);

glGenBuffers(1, &indices);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
             sizeof(rect_indices),
             rect_indices,
             GL_STATIC_DRAW);

And last but certainly not least, here is the code that is supposed to draw the rectangle:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glBindBuffer(GL_ARRAY_BUFFER, vertices);
glVertexPointer(2, GL_FLOAT, 0, NULL);
glColorPointer(4, GL_BYTE, 0,
               (const GLvoid *)(sizeof(GLfloat) * 2));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, NULL);

glDisable(GL_BLEND);

I can't figure out why nothing is being rendered. The vertex and color data is essentially unchanged from the previous version that used glVertex2f().


Solution

  • Simply calling the gl*Pointer functions is not enough; you need to tell OpenGL that it should pull from those particular arrays. For the built-in arrays (glVertexPointer, glColorPointer, etc), you use glEnableClientState(), for the particular array in question.

    For example:

    glBindBuffer(GL_ARRAY_BUFFER, vertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, NULL);
    glEnableClientState(GL_COLOR_ARRAY);
    glColorPointer(4, GL_BYTE, 0, (const GLvoid *)(sizeof(GLfloat) * 2));
    

    That should provide better results.

    You should also use glDisableClientState() on those arrays after you are finished rendering with them.