Optimizing VBO usage

Hello,

I just read ~50 thread about VBO usage, and I ask your opinion about my interpretation.

  • strip the arrays
  • split VBO in multiple VBOs (means one vbo for each mesh, I suppose)
  • use interleaved arrays if possible
  • use 32 byte alignment
  • call glDrawRangeElement instead of all other functions, if possible

And, I have two small questions without answer :

  1. In my engine, I use 4 texture units, so how can I use interleaved arrays ? Is it good to declare separatly an interleaved array T4F_C4F_N3F_V4F for [Vertex/Normal/Color/Texture0] and other linear arrays for [Texture1/Texture2/Texture3] ? What is the best solution in my case ?

  2. In my game, I have to change vertex-positions and vertex-colors every frame. So, should I separate my arrays in vbos like this :

  • One DYNAMIC array with Vertex/Color/Normal, for each mesh
  • One STATIC array with TexCoord 0/1/2/3, for eache mesh

Thanks !

Pacôme.

  • strip the arrays
    Yes, normally a good idea with any geometry.
  • split VBO in multiple VBOs (means one vbo for each mesh, I suppose)
    Not necessarily faster if the individual meshes are very small, you get the overhead from repeatedly setting the gl*Pointer offsets.
  • use interleaved arrays if possible
    Yes, interleave the data, (mind the wording!)
  • use 32 byte alignment
    Not necessarily faster, more data to store and skip gives cache misses.
  • call glDrawRangeElement instead of all other functions, if possible
    Yes, indexed rendering with unsigned shorts is preferrable
  1. You don’t need to use predefined InterleavedArray formats if you want to use interleaved vertex array data, just specify the strides and startoffsets in the pointer calls according to your desired format. For example a Vertex4f, Color4ub, Normal3f format
    would say
    stride = 4 * sizeof(GLfloat) + 4 * sizeof(GLubyte) + 3 * sizeof(GLfloat);
    glVertexPointer(4, GL_FLOAT, stride, 0);
    glColorPointer(4, GL_UNSIGNED_BYTE, stride, 4 * sizeof(GLfloat));
    glNormalPointer(GL_FLOAT, stride, 4 * sizeof(GLfloat) + 4 * sizeof(GLubyte));

Simple as that for any format.

2.) Yes, if the DYNAMIC array is used more than once per frame, otherwise use STREAM.

Thanks Relic, that’s exactly what I wanted to know !

Just a precision in the answer (2) : do you think the use of two separated interleaved buffers (one DYNAMIC for [Vertex/Color/Normal] and another STATIC for [Tex0/1/2/3]) will be more efficient than having a single DYNAMIC buffer where all the data is stored ?

Thanks a lot

Pacôme