Apparently, when rendering primitives from a vertex buffer object (VBO) using glDrawElements, glDrawRangeElements, or glDrawRangeElementsEXT, an index array must be supplied. As i understand this can be done in two ways (using glDrawRangeElements in the examples):
- The first way may be the most straight-forward.
// Bind vertex data.
glBindBufferARB( GL_ARRAY_BUFFER, VertexBufferID );
glVertexPointer( 3, GL_FLOAT, 0, 0 );
// Create index array.
GLuint indexArray[] = { 0, 1, 2, ..., NumPoints };
// Render all the points. Pass the index array in the glDrawRangeElements call.
glDrawRangeElements( GL_POINTS, 0, NumPoints, NumPoints, GL_UNSIGNED_INT, indexArray );
// Reset.
glDisableClientState( GL_VERTEX_ARRAY );
glBindBufferARB( GL_ARRAY_BUFFER, 0 );
The downside of this is that the index array is sent to the GPU each call.
- To avoid passing the index array to the GPU each call we can store the index array in a buffer too. The call is then:
// Bind vertex and element data.
glBindBufferARB( GL_ARRAY_BUFFER, VertexBufferID );
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, IndexBufferID );
glVertexPointer( 3, GL_FLOAT, 0, 0 );
// Render all the points. The indices are now read from the index buffer instead (pass 0 as last argument).
glDrawRangeElements( GL_POINTS, 0, NumPoints, NumPoints, GL_UNSIGNED_INT, 0 );
// Reset.
glDisableClientState( GL_VERTEX_ARRAY );
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, 0 );
glBindBufferARB( GL_ARRAY_BUFFER, 0 );
Now to my question. For rendering points, it often doesn’t make much sense to have an index array at all. I would like to be able to specify a range of indices to render, rather than having to store/transfer every single index. For large collections of points, the memory required becomes quite substantial (one third of the vertex memory, assuming 3 floats per vertex and an unsigned int per index). One solution is to revert to immediate mode and go:
for( unsigned int i = 0; i < NumPoints; ++i )
{
glVertex3f( VertexData[i].x, VertexData[i].y, VertexData[i].z);
}
Is it possible to use glDrawRangeElements without an index array? I suspect not, but I am hoping to confirm this.
Also, I suspect the call:
glDrawRangeElements( GL_POINTS, 0, NumPoints, NumPoints, GL_UNSIGNED_INT, indexArray );
should be
// "end" is size-1 because of zero-based indexing?
glDrawRangeElements( GL_POINTS, 0, NumPoints-1, NumPoints, GL_UNSIGNED_INT, indexArray );
I hope this is clear enough.
best,
T