Introduction

This sample demonstrates how to modify the data in an existing VBO.

Controls

Press Esc or click the close button to exit.

Implementation

This sample builds on the concepts of the "VBO Static" sample, so please refer to that for instructions on how to load and render a VBO.

OpenGL defines nine different BufferUsageHints for VBO that can improve rendering performance when used correctly. Each hint consists of two parts:
1. update frequency, which can be one of "static", "dynamic" or "stream", and
2. buffer usage, which can be one of "draw", "read" or "copy".

Update frequency defines how often the buffer will be updated: static means that the buffer is modified infrequently or not at all; dynamic means that parts of it may be modified frequently; stream means that the whole buffer is discarded and recreated frequently.

Buffer usage defines how the buffer will be used: draw means that the buffer will be used to draw geometry; read means that the buffer will be used to read data from OpenGL back into system memory (via GL.GetBufferSubData or GL.MapBuffer); copy means that the buffer will hold intermediate results that will be copied from/to other OpenGL buffers.

When uploading data to a VBO via GL.BufferData, you should specify the BufferUsageHint that most closely resembles the usage pattern for this buffer. For example, if you are planning to use this buffer for rendering unchanging (or mostly unchanging) geometry you should specify BufferUsageHint.StaticDraw. If you are planning to read back results that change every frame, you should use BufferUsageHint.StreamRead.

Note that this is only a hint that might allow the driver to optimize performance. It doesn't prevent you from using the buffer in a way opposed to the hint (for example, reading back data from a StaticDraw buffer). However, doing so might result in a performance penalty.

In this sample, we use a StreamDraw buffer that is recreated every frame (see OnRenderFrame method). Since OpenGL might not have finished drawing from the buffer when we try to update its data, we first call GL.BufferData(..., IntPtr.Zero) to allocate a new buffer and upload the new data to this. Without this optimization, OpenGL would have to block until the old buffer would finish drawing; this optimization allows the drawing and the data upload to go on at the same time.