Introduction

This is a tutorial on how to get better performance out of your VBOs, please read the Using Vertex Buffer Objects before continuing. For the sake of clarity, all the VBOs below are of FLOAT type and of STATIC_DRAW_ARB nature. Also a FLOAT is considered to be of 4 bytes.

Interleaving a VBO

An interleaved VBO is one that contains most components of a mesh in a single VBO in a specific, predefined order. Such an example is V[xyz]N[xyz]C[rgba]T1[st], where V is a vertex, N is a normal, C is a colour, T1 is the texture coordinate; each with their own components listed besides them for clarity. The most important thing to remember in this step is the order in which your interleaved the VBO and then just send it to the GL.

Rendering the VBO

The clever bit behind interleaving a VBO is the way in which you render them, but first we need to enable a vertex array client states:

GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);

Now we can bind the VBO, heres a reminder:

ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, myVBOId );

Now the special bit, calling the glXXXXPointer methods.

int stride = (3 + 3 + 4 + 2) * 4; // 3 for vertex, 3 for normal, 4 for colour and 2 for texture coordinates. * 4 for bytes
 
// vertices
int offset = 0 * 4; // 0 as its the first in the chunk, i.e. no offset. * 4 to convert to bytes.
GL11.glVertexPointer(3, GL11.GL_FLOAT, stride, offset);
 
// normals
offset = 3 * 4; // 3 components is the initial offset from 0, then convert to bytes
GL11.glNormalPointer(GL11.GL_FLOAT, stride, offset);
 
// colours
offset = (3 + 3) * 4; // (6*4) is the number of byte to skip to get to the colour chunk
GL11.glColorPointer(4, GL11.GL_FLOAT, stride, offset);
 
// texture coordinates
offset = (3 + 3 + 2) * 4;
GL11.glTexCoordPointer(2, GL_FLOAT, stride, offset);

Now you can render your indices, heres a reminder of how to do it the non-VBO way (you can see the VBO way in the first tutorial):

GL12.glDrawRangeElements(GL11.GL_TRIANGLES, 0, maxIndex, myIntDirectBuffer);

GL12.GL_MAX_ELEMENTS_VERTICES

GL12.GL_MAX_ELEMENTS_VERTICES is a magical number in which the number of vertices in your VBO is equal to that number, you'll get speedy VBOs. Warning: Speculation follows. This magical number, I assume, is the size of the FIFO buffers, anything above that will be stored in either vram, or ram causing the slowdowns causing unnecessary fetches, which only stall the pipeline. The magical number on most NVIDIA is 4096. So if your doing some terrain stuff, cut it up into 64×64 pieces. Speedy VBOs.

There is also GL12.GL_MAX_ELEMENTS_INDICES, i'll leave that to you.

Conclusion

There is still the matter of ARBVertexBufferObject.glMapBufferARB that can speed VBO updating (specially on specified regions within the VBO), but i'll leave that up to the reader.

Enjoy your Speedy VBOs

 
lwjgl/tutorials/opengl/speedyvbo.txt · Last modified: 2007/07/07 00:38 (external edit)
 
Recent changes RSS feed Creative Commons License Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki