I’ve been wondering the same thing too, whether it’s faster to set all the gl***Pointer functions before drawing with each mesh:
gl***Pointer(..., mesh[i].offset + mesh[i].attribute[j].offset); // for each attribute
glDrawRangeElements(..., NULL);
gl***Pointer(..., mesh[i].offset + mesh[i].attribute[j].offset);// for each attribute
glDrawRangeElements(..., NULL);
or whether it’d be better to adjust the indices as meshes are placed into a buffer object, getting rid of the need for gl***Pointer calls:
gl***Pointer(..., 0); // for each attribute
glDrawRangeElements(..., 0);
glDrawRangeElements(..., mesh[i].offset);
If you are prepared to limit to OpenGL 3.2+ (or GL_ARB_draw_elements_base_vertex), then you can provide a base vertex that is added to all the indices:
glDrawElementsBaseVertex(GL_TRIANGLES, 39, GL_UNSIGNED_SHORT, NULL, mesh[i].basevertex); // other ***BaseVertex functions exist
Without GL_ARB_draw_elements_base_vertex, then I think if you were to use unsigned short indices, you would be limited to 65536 vertices per buffer object, which isn’t as bad as it sounds if you have 32 bytes per interleaved vertex, that’s a 2 MB buffer object. But if you aren’t using interleaved vertex data, then you’d might up with several smaller buffer objects, eg. from 128kb to 1MB.
Another few related questions I have, are:
- How much do OpenGL implementations gain from using glDrawRangeElements instead of glDrawElements too? It says that if the range is small enough, it could automatically convert indices to a smaller data type (eg. from GL_UNSIGNED_INT to GL_UNSIGNED_SHORT), but would it do this on every draw call?
- If you have meshes that needs certain data updated every frame, such as vertex position + normals, and you want to group several meshes into a single buffer object, how + when is the best way to update this data without causing slowdown?
- Do vertices or indices gain anything from being aligned to certain values, or if they were in the same buffer object, could they be tightly packed?