JPGygax68
1/13/2016 - 10:12 AM

Defining and drawing a rectangle using a VAO (vertex array object) and a vertex buffer.

Defining and drawing a rectangle using a VAO (vertex array object) and a vertex buffer.

/* Example class for rendering a rectangle using OpenGL 4, using a vertex buffer and a
 * vertex array object and the triangle strip primitive.
 * 
 * Note: GL calls are wrapped into a variadic macro of the form GL(func, arg1, arg2,...).
 */
class opengl_rectangle {
  
public:

    void  get_resources()
    {
        // Generate a vertex buffer
        GL(GenBuffers, 1, &vertex_buffer);
    
        // Define a VAO (Vertex Array Object)
        GL(GenVertexArrays, 1, &vao);
        GL(BindVertexArray, vao);
        // Vertex buffer
        GL(BindBuffer, GL_ARRAY_BUFFER, vertex_buffer);
        // Example vertex layout: vec4 vertex coordinates, vec2 texture coordinates
        // Vertex attrib 0: vertex coordinates
        GL(VertexAttribPointer, 0, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_data), (const GLvoid *)0);
        GL(EnableVertexAttribArray, 0);
        // Vertex attrib 1: texture coordinates
        GL(VertexAttribPointer, 1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_data), (const GLvoid *)(4 * sizeof(GLfloat)));
        GL(EnableVertexAttribArray, 1);
        // Done
        GL(BindVertexArray, 0);
    }
    
    void free_resources()
    {
        GL(DeleteVertexArrays, 1, &vao); vao = 0;
        GL(DeleteBuffers, 1, &vertex_buffer); vertex_buffer = 0;
    }

    void set_bounds(GLfloat w, GLfloat h, GLfloat x = -1, GLfloat y = -1)
    {
        vertex_data vertices[4] = {
            // Example vertex layout: vec4 (x,y,z,w) vertex coordinates, 
            //   vec2(u,v) texture coordinates
            { { x    , y    , 0, 1 }, { 0, 0 } },
            { { x + w, y    , 0, 1 }, { 1, 0 } },
            { { x    , y + h, 0, 1 }, { 0, 1 } },
            { { x + w, y + h, 0, 1 }, { 1, 1 } }
        };
        
        GL(BindBuffer, GL_ARRAY_BUFFER, vertex_buffer);
        GL(BufferData, GL_ARRAY_BUFFER, 4 * sizeof(vertex_data), vertices, GL_STATIC_DRAW);
        GL(BindBuffer, GL_ARRAY_BUFFER, 0);
    }
    
    /** glUseProgram() and glBindTexture() must be called before calling draw().
     */
    void draw()
    {
        GL(BindVertexArray, vao);
        GL(DrawArrays, GL_TRIANGLE_STRIP, 0, 4);
        GL(BindVertexArray, 0);
    }
    
private:
    GLuint vao;
    GLuint vertex_buffer;
};