Search code examples
c++copenglopengl-3

Understanding code used to draw quads in OpenGL 3.3+ core using triangles


I'm trying to draw a quad for a background (2D) using OpenGL 3.x+. Quads are deprecated, so the goal is to use two triangles to make a rectangle that fills the screen. It's working, but I'm not 100% clear on everything here.

  1. Setup

    GLuint positionBufferObject;
    GLfloat vertexPositions[] =
    {
        -1.0f, -1.0f, 0.0f, 1.0f,
        -1.0f,  1.0f, 0.0f, 1.0f,
         1.0f,  1.0f, 0.0f, 1.0f,
         1.0f, -1.0f, 0.0f, 1.0f,
        -1.0f, -1.0f, 0.0f, 1.0f,
    };
    glGenBuffers(1, &positionBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
    
    • I understand the vertexPositions, it's an array of vertices.
    • glGenBuffers() is saying, I want 1 buffer and assign id to &positionBufferObject?
    • glBufferData() uploads the vertexPositions to the GPU's memory; but how does it know were to upload it since I didn't give it an ID?
  2. Draw

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 5);
    glDisableVertexAttribArray(0);
    
    • glEnableVertexAttribArray() just says I'm going to be drawing with array 0?
    • glDrawArrays() - what if I want to draw two vertex arrays? How does it know which ones to render? It knows that from the above command?
    • Not sure what glVertexAttribPointer() does?
    • glDrawArrays() is clear.
  3. Clean up, I think this is right?

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDeleteBuffers(1, &positionBufferObject);
    

    I only do the setup/cleanup once.

Bonus points:

  • Is this the most effective way to render this? I read that I'm suppose to be submitting and be rendering in "batches" [?] since 3.x+ doesn't do immediate mode any more. There is also only one array, so batches won't help performance in this case, but if I had say "a very large number" of vertxArrays to draw, would it be the same process?
  • In setup they are storing the array id as positionBufferObject, but have it hardcoded in the rendering loop. Seems like it would get confusing after a dozen or so arrays, why isn't it good practice to use the variable instead of hardcode it?

Solution

  • glGenBuffers(1, &positionBufferObject); says "make a vertex buffer object, and positionBufferObject is its ID."

    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); says "positionBufferObject is now the current GL_ARRAY_BUFFER."

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW); says "upload vertexPositions to the ID currently bound to GL_ARRAY_BUFFER (which is positionBufferObject)."

    glEnableVertexAttribArray(0); says "vertex attribute array 0 is now available for use."

    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); says "vertex attribute array 0 is to be interpreted as consisting of groups of 4 floats."

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 5); says "draw a triangle strip with five indices from every enabled array."

    glDisableVertexAttribArray(0); says "we're done for the time being with vertex attribute array 0."