OpenGL Programming

Buffer objects

Vertex Array Objects (VAO)

Contain attribute pointer information for a number of VBO and a single EBO.

When a VAO is bound, all vertex attribute calls will be stored in it, which means that we can quickly restore vertex attributes parameters to configure VBO and EBO. With this, we can quickly swich different vertex data and attributes by just binding a different VAO.

Vertex Buffer Objects (VBO)

Contain information that will be passed to the vertex shader. Normally we would like to send vertex positions, as well as color information or UV coordinates to be used for a given vertex.

The VBO is just a buffer of raw memory, to interpret the contents in the buffer, we need the vertex attributes glVertexAttribPointer. Vertex attributes contain information about the size of the elements in the buffer, the number of elements per vertex, the type and the stride of those elements. OpenGL guarantees that per shader we can have at least 16 4-dimensional vertex attributes (16 * 4 * sizeof(float)). Some hardware might allow for more, and if so you can query this with: glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &n_vertex_attribs);

Element Buffer Objects (EBO)

Using EBO, we can index vertices in a VBO to remove redundant vertices and extra overhead.

Projection matrices

A point or vertex goes through several transformation before ending up in the screen. First the model and projection matrices move the point to clip space. Clipping occurs on the on the unit cube, leaving a certain “guard band”. When clipping, new triangles may be generated to keep the overall geometry of the mesh. The resulting points after clipping will be moved to screen coordinates, where rasterization will happen.

No perspective (Model coordinates in NDC).

Mat4 model = vm_identity();
Mat4 view = vm_identity();
Mat4 projection = vm_identity();

Orthographic projection.

Mat4 model = vm_scale(vm_identity(), (Vec3){100.0f, 100.0f, 1.00f});
Mat4 view = vm_translate(vm_identity(), (Vec3){50.0f, 50.0f, 0.0f});
Mat4 projection = vm_ortho(0.0f, 400.0f, 0.0f, 400.0f, 0.0f, 1.0f);

Perspective projection.

//            Y
//            |
//            |
//            |---------- X
//           /
//          /
//         Z
Mat4 model = vm_rotate(vm_identity(), (float)glfwGetTime() * 50.0f, (Vec3){0.5f, 1.0f, 0.0f});
Mat4 view = vm_translate(vm_identity(), (Vec3){0.0f, 0.0f, -3.0f});
Mat4 projection = vm_perspective(45.0f, 800.0f/600.0f, 0.1f, 100.0f);

OpenGL command buffers

To provide a cohesive abstraction layer for graphics between different APIs, we need to be able to map lower level concepts to higher level APIs. Unfortunately OpenGL doesn’t have access to command buffers, but emulation should be possible.