Introduction

This sample demonstrates how the concept of "Vertex Buffer Objects" or, in short, VBOs.

VBOs provide an efficient and versatile method to store and render geometry in OpenGL programs. Unlike display lists, VBOs can be used for both static and dynamic geometry. 

VBOs were introduced in OpenGL 1.5 and are supported all the way up to OpenGL 4.0.

Controls

Press Esc or click the close button to exit.

Implementation

This sample renders a simple spinning cube. Two parts are of interest here: the LoadVBO() method, which constructs a VBO, and the Draw() method, which renders a VBO.

For each VBO-based object, we typically require two VBOs:
1. an "array buffer" which contains vertices for our geometry, and
2. an optional "element array buffer" which indicates how these vertices are connected to form triangles or other geometric primitives. Using an element array will typically result in higher performance.

To construct a VBO, we need to generate a buffer id (GL.GenBuffers), bind it (GL.BindBuffer) and upload our buffer data (GL.BufferData). GL.BindBuffer defines whether the VBO is an array buffer (BufferTarget.ArrayBuffer) or an element array buffer (BufferTarget.ElementArrayBuffer).

GL.BufferData is a generic function. When creating an element array buffer, we need to pass an array of bytes, shorts or ints that indicate indices into the array buffer. When specifying an array buffer, we need to pass an array of structures that contain our desired vertex attributes (e.g. position, color, texcoords, normals). When using GLSL, we can also define "generic" vertex attributes the usage of which is defined by the GLSL shader (see "OpenGL 3.0" sample for a demonstration of generic attributes).

The LoadVBO() method demonstrates how to create an array buffer that contains "potision" and "color" attributes and an element array buffer that uses short (16-bit) indices.

Once a VBO is constructed, we can render it in four simple steps:
1. Enabled the desired vertex attributes with GL.EnableClientState(EnableCap.[Vertex|Color|Normal|...]Array). This is not necessary when using GLSL.

2. Bind the array and (optional) element array buffers with GL.BindBuffer.

3. Define the layout of the array buffer via GL.[Vertex|Color|Normal|...]Pointer. In this sample, we instruct OpenGL that vertex position is stored as 3 floats at offset 0 and vertex color as 4 bytes at offset 12 (3*sizeof(float)). A more complex sample might also specify vertex texcoords (typically 2 floats) and vertex normals (typically 3 floats). The exact offsets are defined by the layout of your "Vertex" struct (see definition of VertexPositionColor for this sample).

4. Call GL.DrawElements (if an element array buffer is bound) or GL.DrawArrays (if no element array buffer exists).

Note: OpenGL 3.0+ simplifies this process by eliminating steps 1 and 3. See OpenGL 3.0 sample for more information.