Vertex buffer object

1.0 Introduction

As a starter for graphic design, learners sometimes confuse where they should put objects’ information such as vertex coordinate, texture coordinate, and surface normal coordinate. We learn to use display lists for static graphic designs in order to improve the overall performance. As the graphic program gets bigger, learners might see the need to further improve the program’s performance. Vertex buffer object (VBO) is a good way to store vertex coordinates and vertex attributes on graphic cards. Then, every time an object is redrawn, its coordinates get pulled from the GPU instead of the CPU. 

2.0 Steps to create and use a vertex buffer object

Breaking down the process into small steps, I hope that this could help learners have a better understanding of the purpose of each steps and how to implement it.

2.1: Create the vertex coordinates and vertex attributes

2.2: Create/delete a VBO with three steps [1]

2.2.1 void glGenBuffers(GLsizei n, GLuint* ids) to create a new buffer object. N is the number of buffer objects to create; ids is the address of a GLuint variable.

2.2.2 void glBindBuffer(GLenum target, GLuint id) to bind the buffer object to the corresponding ID. For vertex attributes including vertex coordinates, texture coordinates, surface normal coordinates and color arrays, target is GL_ARRAY_BUFFER. For vertex connection indices, the target is GL_ELEMENT_ARRAY_BUFFER

2.2.3 copying vertex coordinates and vertex attributes into buffer objects.

void glBufferData(GLenum target, GLsizei size, const void* data, GLenum usage)

Size is the amount of bytes of data to be transferred. data is the memory address of the data to be transferred. If data is a NULL pointer, VPO will reserve the memory space for the given data size. Usage flag specify how the VBO is used as following: 




If VBO does not change, we use “Static” . If data frequently changes, we use “dynamic”. If data changes for each frame, we use “stream”. “Draw” specifies data to draw, “read” specifies data to read by the client’s application, and “copy” specifies data to both read and draw. 

void glDeleteBuffers(GLsizei n, const GLuint* ids) is used to delete the VBO when users finish using the buffer object.

2.3 Activate/ deactivate the drawing data

 glEnableClientState(type) is used to activate the drawing data.


To deactivating the client state, using the function glDisableClientState(type)

2.4 Getting each Data Type from Buffer

glVertexPointer( size, type, stride, offset);

glColorPointer( size, type, stride, offset);

glNormalPointer( type, stride, offset);

glTexCoordPointer( size, type, stride, offset);

Size specifies numbers per vertex (2, 3, or 4. Type specifies GL_SHORT, GL_INT, GL_FLOAT, or GL_DOUBLE. Stride is the byte offset between consecutive data. Offset is the byte offset from the beginning of the data array buffer to the first element of the data type. Depending on how data is stored in the array buffer (packed or interleaved arrangement, stride and offset can be set differently. 

2.5 Drawing using glDrawArrays() or glDrawElements()

void glDrawArrays(GLenum mode, GLint first, GLsizei, count)

glDrawArrays() is used if the enabled arrays are arranged in the order of vertices. Mode defines which topology is used, it accepts GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_LINE_STRIP_ADJACENCY, GL_LINES_ADJACENCY, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_TRIANGLE_STRIP_ADJACENCY, GL_TRIANGLES_ADJACENCY, GL_PATCHES.

First is the starting index in the enabled arrays and count is the number of indices to be rendered [2]. 

void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void * indices). 

The glDrawElements() requires four arguments, but it allows the reuse of the same vertices. Mode is similar as in glDrawArrays(). Count specifies the number of elements needed to render. Type specifies the data type (GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT). Indices specify a pointer to the address of the indices array [3]. 

Figure 1: Drawing a cube using glDrawArrays() and glDrawElements()

2.6 Mapping data from buffer object to the client’s address space

void *glMapBuffer(GLenum target, GLenum access);

This function returns a pointer to the stored data; users can directly  read and/or write to the buffer object’s mapped data store. Target could be GL_ARRAY_BUFFER, GL_TEXTURE_BUFFER, etc. Access can be one of the following GL_READ_ONLY, GL_WRITE_ONLY, or GL_READ_WRITE. 

The function GLboolean glUnmapBuffer(GLenum target)is used to cancel the buffer object’s data store from the client’s address space

3.0 Indexed Vertex Buffer Object C++ Class 

Figure 2 shows methods supported by the indexed VBO C++ Class, and an example is shown in Figure 3 to demonstrate how the class is used.

Figure 2 shows methods are supported by the indexed Vertex Buffer Object C++ Class. Source: [5] 
Figure 3: Example of using the VBO class to draw a colored cube.
Source: [5] 

4.0 Conclusion

The Vertex Buffer Object provides a great tool for graphic design’s learners to improve the efficiency of data transferring by storing the vertex coordinates and vertex attributes on the GPU. With VBO, vertex data will be transferred from client memory once instead of for every frame. 


[1]Song Ho Ahn. (2018). OpenGL Vertex Buffer Object(VBO). [Online]. Available: Accessed Oct 31, 2021. 

[2] OpenGL4.5. [Online]. Available: Accessed Oct 31, 2021. 

[3] OpenGL® 4.5 Reference Pages. glDrawElements. [Online]. Available: Accessed Oct 31, 2021. 

[4] Song Ho Ahn. (2018). OpenGL Vertex Array. [Online]. Available: Accessed Oct 31, 2021

[5] Patrick Cozzi and Christophe Riccio.(2012). OpenGL Insights. CRC press. [Online]. Available: Access Oct 31, 2021

Print Friendly, PDF & Email

Leave a comment

Your email address will not be published. Required fields are marked *