First, an OpenGL buffer is created and bound. Once bound, data can be loaded onto the buffer with either glBufferData() or glBufferSubData(). Next, the locations of the attributes and uniforms are obtained by using glGetAttribLocation() and glGetUniformLocation(), respectively. Once the attribute locations are known, the attribute locations are enabled by calling glEnabledVertexAttribArray().

Once the attribute locations are enabled, we can tell OpenGL which data in the bound buffer corresponds to the attributes in the shader. This is done by providing a memory offset to the data in the buffer with glVertexAttribPointer(). And finally, we can start the rendering process by calling glDrawArrays() which will render a screen with data found in the current bound buffer.

How to render with glDrawArrays

How does glDrawArrays() knows what data to render? glDrawArrays() will render an object with data found in the current bound buffer. In listing 1, we bound a buffer after having it created (line 2).

Listing 1 sets up a buffer with data ready to render. Ideally, listing 1 is set up once. whereas the code to render is called continuously.

Listing 2 shows a simple rendering example. Notice that before you call glDrawArrays you have to enable the attribute locations (line 1). After the rendering, these locations should be disabled (line 3).

The first parameter in glDrawArrays simply asks how you want to connect the vertices in the buffer data. The vertices can be connected as lines, triangles or points. The second parameter simply aks for the starting index in the data array. The third parameter asks for the total number of indices to be rendered.

Source Code

How to render with glDrawElements

Rendering with glDrawElements() is more efficient than rendering with glDrawArrays(). With glDrawElements() you provide a set of indices that will guide OpenGL through the primitive assembly stage. These set of indices reduce any redundant vertex connection which may occur if using glDrawArrays().

The process of preparing an object for rendering using glDrawElements() is very similar to glDrawArrays(), except that we create a new buffer and bind it to GL_ELEMENT_ARRAY_BUFFER. For example, lines 7-8 in listing 3 shows the creation and binding of the new buffer called elementBuffer. Line 9 shows the loading of the index data found in the array cubeIndex.

Rendering is done as shown in listing 4. Again, we start the rendering loop by first enabling the attribute locations (line 1). glDrawElements() will use the indices as it constructs the object using data in the currently bound buffer. That is, the current buffer bound to GL_ARRAY_BUFFER. Finally, we disable the attribute location (line 3).