thinks
07-06-2007, 06:31 AM
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):
1. 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.
2. 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
1. 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.
2. 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