GeeXLab
Current version: 0.45.1
>GeeXLab homepage

FurMark
Current version: 1.30.0
>FurMark homepage

GPU Caps Viewer
Current version: 1.55.0.0
>GPU Caps Viewer homepage

GPU Shark
Current version: 0.26.0.0
>GPU Shark homepage


Blogs
>JeGX's HackLab

Geeks3D's Articles
>GPU Memory Speed Demystified

>Multi-Threading Programming Resources

>GeForce and Radeon OpenCL Overview

>How to Get your Multi-core CPU Busy at 100%

>How To Make a VGA Dummy Plug

>Night Vision Post Processing Filter

PhysX FluidMark
Current version: 1.5.4
>FluidMark homepage

TessMark
Current version: 0.3.0
>TessMark homepage

ShaderToyMark
Current version: 0.3.0
>ShaderToyMark homepage
>ShaderToyMark Scores

Demoniak3D
Current Version: 1.23.0
>Demoniak3D
>Download
>Libraries and Plugins
>Demos
>Online Help - Reference Guide
>Codes Samples
 
OpenGL Vertex Buffer Objects

By Christophe [Groove] Riccio - www.g-truc.net
And
Jerome [JeGX] Guinot - jegx[NO-SPAM-THANKS]@ozone3d.net

Initial draft: May 1, 2006

Last Update: January 7, 2007


[ Index ]

Intro | Page 1 | Page 2 | Page 3

�Next Page



1 - Description

1.1 - OpenGL Legacy

OpenGL beginners like its simplicity through the immediate mode that comes with OpenGL 1.0. This mode looks like this:

glBegin(GL_QUADS);
	glColor3f(1.0f, 0.5f, 0.0f);
	glVertex2f(0.0f, 0.0f);
	glVertex2f(1.0f, 0.0f);
	glVertex2f(1.0f, 1.0f);
	glVertex2f(0.0f, 1.0f);
glEnd();

This code is quiet easy to understand but it could become very slow whether the goal is to describe complex geometric primitive composed by thousand of vertices just because of the high number of function calls.

OpenGL 1.1 includes vertex arrays that allow rendering a large amount of data with few function calls. This mode looks like this:

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

float ColorArray[] = {…};
float VertexArray[] = {…};

glColorPointer(3, GL_FLOAT, 0, ColorArray);
glVertexPointer(3, GL_FLOAT, 0, VertexArray);

glDrawArrays(GL_TRIANGLES, 0, sizeof(VertexArray) / sizeof(float));

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

Vertex buffer objects are similar in their principles but they provide a lot of improvements.

1.2 - VBOs Interests

VBO provides three data transfer modes instead of one for vertex arrays.

The first one, called GL_STREAM_DRAW provides the same behaviours than vertex arrays witch means that data are sent for each call to glDrawArrays, glDrawElements, glDrawRangeElements (EXT_draw_range_elements, OpenGL 1.2) glMultiDrawArrays or glMultiDrawElements (EXT_multi_draw_array, OpenGL 1.4). This mode is particularly efficient for CPU animated objects such as characters for example.

A second mode, called GL_STATIC_DRAW, inherits of features from the EXT_compiled_vertex_array extension. It allows sending vertices information only once to the graphics card because these data are saved in the graphic controller memory. This mode is suitable for non deformable objects that are to say for all geometries which remains unchanged during several frames. This mode is the one which could provide the highest performances as the memory is reserved and the graphic controller's bandwidth is much larger thant the one of the CPU.

The last mode is GL_DYNAMIC_DRAW. With this mode, the graphics drivers will choose the data location. This mode is recommended for animated object that are rendered several times per frame, for example in case of multi passes rendering.

To summarize, use these modes:

  • GL_STREAM_DRAW when vertices data could be updated between each rendering.
  • GL_DYNAMIC_DRAW when vertices data could be updated between each frames.
  • GL_STATIC_DRAW when vertices data are never or almost never updated.

Notice that these three modes are more and more considered by the graphics drivers as a recommendation. Therefore, sometimes they may not pay attention to your advice and choose on their own. Consequently, it could happen that you don’t observe any frame rate variation when you are toggling modes.

The second improvement that characterise VBOs is called Vertex mapping. It represents the ability of not using a temporary array to store vertices data. Instead, an array, which is allocated by OpenGL, is directly used for storing this data. Notice that VBOs are also available with OpenGL ES 2.0 but this feature is optional. This feature appeared with ATI_map_buffer_object extension which is available since the first ATI Radeon. nVidia has also provided an extension for this feature which is called NV_vertex_array_range. However, the memory allocation is manually done using the OpenGL context… With VBOs this allocation is transparent.

Finally, VBOs provide an excellent alternative to interleaved arrays. As a recall, interleaved arrays allow sending vertices data to the graphics card by using a single array described by the glInterleavedArrays function. With vertex arrays, we had to use predefined data structures with a precise order for each element of that structure. With the GPU programming arising, the customized programmer attributes are not handled anymore. VBOs solve this issue and allow to update only a part of the data.

1.3. Partial support

VBOs provide a robust API that matches all needs of current and future graphics cards. Thus, they provide six other transfer modes called GL_STREAM_READ, GL_STREAM_COPY, GL_DYNAMIC_READ, GL_DYNAMIC_COPY, GL_STATIC_READ and GL_STATIC_COPY.

Unfortunately, it seems to me that none of the current graphics card is supporting these features for the moment. The ATI Render to Vertex Buffer (R2VB) technology featured by Radeon X1*00 nearly matches the functionnalities provided by this six modes. However, ATI did not communicate any information regarding the OpenGL aspect of this topic, but it looks pretty much like Pixel Buffer Object (ARB_pixel_buffer_object) so it doesn’t bring anything new for OpenGL.

Modes finishing with GL_*_READ allow reading any data handled by OpenGL. Rules on GL_STREAM_*, GL_DYNAMIC_* and GL_STATIC_* terms are the same but they now refer to the number of data reading performed by the program. Modes using the term GL_*_COPY allow to display a geometry from a source managed by OpenGL.

In concrete terms, what are these modes used for? For the upcoming graphics card generations, known as the G80 for nVidia and R600 for ATI, new features will be available. They are brought into disrepute under DirectX names like Shader Model 4.


DirectX 10 Graphics Pipeline
Picture from DirectX 10 documentation that represents the graphic pipeline

Geometry shaders, called primitive shaders in OpenGL, will allow vertices instancing from the GPU. As the previous figure shows, the graphic pipeline will change by allowing data transfer, here refered as the “stream output stage”. This stream of data requires an API, and the VBOs' GL_*_COPY and GL_*_READ modes are specially designed to answer this need. GL_*_COPY modes seems suitable for handling recursive processing on vertices, which could dramatically increase resources required by the vertex pipelines. The marketing action by ATI with R2VB is based on an analogy with this new “stream output stage” using pixels as stream output. However there is no way for pixel creation with Radeon X1*00.





[ Index ]

Intro | Page 1 | Page 2 | Page 3

�Next Page





GeeXLab demos


GLSL - Mesh exploder


PhysX 3 cloth demo


Normal visualizer with GS


Compute Shaders test on Radeon


Raymarching in GLSL



Misc
>Texture DataPack #1
>Asus Silent Knight CPU Cooler
Page generated in 0.0017678737640381 seconds.