Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: vertex buffer points and element arrays

  1. #1
    Senior Member Regular Contributor
    Join Date
    Jan 2005
    Location
    Stockholm, Sweden
    Posts
    164

    vertex buffer points and element arrays

    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.
    Code :
    // 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:
    Code :
    // 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:
    Code :
    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:
    Code :
    glDrawRangeElements( GL_POINTS, 0, NumPoints, NumPoints, GL_UNSIGNED_INT, indexArray );
    should be
    Code :
    // "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

  2. #2
    Senior Member OpenGL Guru Relic's Avatar
    Join Date
    Apr 2000
    Posts
    2,450

    Re: vertex buffer points and element arrays

    Rendering GL_POINTS with glDrawElements where the element array is 0 to NumPoints is a waste of time.
    Just use glDrawArrays in that case, which allows to specify a contiguous range by using its first and count parameters.

    glDrawElements would only make sense for non-contiguous sets of points or if the glDrawArrays would be too many (count too small).

    Correct, the start and end parameters in glDrawRangeElements are the actual min and max indices you will access. The NumPoints - 1 is the right end parameter.

  3. #3
    Senior Member Regular Contributor songho's Avatar
    Join Date
    May 2003
    Location
    Canada
    Posts
    242

    Re: vertex buffer points and element arrays

    thinks,
    If you reference all vertices in VBO every frame then, try glDrawArrays(). glDrawArrays() does not need an index array.

    However, note that glDrawArrays() does not reduce memory usage in general cases. Actually, it requires more memory than using index, because of shared vertices.

    Let's say there is a mesh with 100 triangles and 30 shared vertices (70 verts are unique). Now, compare memory usages on both glDrawArrays() and glDrawElements().

    1. glDrawArrays()
    The size of the vertex array is 100x3x4 = 1200 bytes.
    100: # of tris
    3: coords of each vertex (x,y,z)
    4: size of float variable

    2. glDrawElements()
    The size of the vertex array is 70x3x4 = 840 bytes.
    70: # of non-shared vertices
    3: coords of each vertex, (x,y,z)
    4: size of float variable

    The size of the index array with GLubyte is 100x3x1 = 300 btyes.
    100: # of tris
    3: each tri needs 3 indices
    1: size of GLubyte

    So, total memory requirement for glDrawElements() is 840+300 = 1140 bytes. It is 60 bytes less than glDrawArrays(). If you also count colour, normal and uv arrays, then the difference is getting bigger.

  4. #4
    Senior Member Regular Contributor
    Join Date
    Jan 2005
    Location
    Stockholm, Sweden
    Posts
    164

    Re: vertex buffer points and element arrays

    Relic:
    glDrawElements would only make sense for non-contiguous sets of points or if the glDrawArrays would be too many (count too small).
    What do you mean by the glDrawArraysbeing too many?

    songho:
    Your discussion is informed. However, in the case of rendering points there is (per definition) no shared vertices.

    Thanks guys, I suspected there was no use for the indexing since there are no shared vertices. I might implement some LOD functionality. But still, if I order the points in the vertex array correctly I might be able to specify certain ranges without having to use indices. When there are millions of points, indices are a bit of a pain...

  5. #5
    Super Moderator OpenGL Guru imported_dorbie's Avatar
    Join Date
    Jul 2000
    Location
    Bay Area, CA, USA
    Posts
    3,966

    Re: vertex buffer points and element arrays

    Yup, the idea behind index rendering of DrawElements is data compression through vertex reuse. Drawing points implies a 1:1 vertex : primitive ratio where each vertex is sent only once, therefore indexed rendering is not a win and may in fact be slower.

    This assumes that your point data is unique, you should ensure it is.

    With millions of points you could probably do a lot with multiple draw calls, there's no need to stick them all in one call.

    Visibility culling with aggregate patches of points, frustum culling and LOD culling with interleaved arrays should all be possible.

    It sounds like you have some sort of surfel splatting going on.

  6. #6
    Senior Member Regular Contributor
    Join Date
    Jan 2005
    Location
    Stockholm, Sweden
    Posts
    164

    Re: vertex buffer points and element arrays

    Dorbie: I am not doing surfels yet. I am processing LiDAR data (think radar, and then switch radio for laser). Data sets are huge and visualization is a bit of a problem. Just want to try to avoid common pitfalls here, every slip-up matters with that many points.

    Does anyone know of any LOD methods for point clouds that have been tried and tested? My idea would be to scramble the vertex array (randaomize the ordering of the points) and the simple draw larger and larger chunks of the vertex array as the user moves closer. What I don't like about this is the randomness. I think it would be better if the sampling was more controlled.

  7. #7
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,574

    Re: vertex buffer points and element arrays

    As an off-line step, what about octree-like subdivision of world space, with smaller voxels about the size of a screen pixel (ajust according to performance), and only a single point per voxel ?
    Then dump each level of detail to an array for optimal real-time performance.

  8. #8
    Senior Member Regular Contributor
    Join Date
    Jan 2005
    Location
    Stockholm, Sweden
    Posts
    164

    Re: vertex buffer points and element arrays

    Zbuffer: I also think that spatial subdivision is the way to go. I was thinking I might subdivide until the point-count in the leaf nodes drops below some threshold. I am not sure what you mean by have voxels the size of a pixel. I understand that the voxel projected to screen space may occupy one pixel, but seeing as the octree has dimensions in space, the projection will not be constant for all the voxels, right? So there is no one unique size that guarantees that the voxel size in screen space is one pixel?

    I think there might be time to save by allowing several points to "live" in a voxel though. In my experience, clipping of points is very fast, so passing a few points that end up being clipped is not too bad, and it shifts computations from CPU to GPU, which in my case is good.

    Thanks for input!

  9. #9
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,574

    Re: vertex buffer points and element arrays

    I am not sure what you mean by have voxels the size of a pixel.
    ie. voxel size computed according to main interest of viewer (center of view, upto distance Z, targeted/selected point, something like that).

    I was a bit quick on this, but it is only a quideline, not an absolute need, and you are right about balancing CPU/GPU computation. Very fine grained LOD is bad for GPUs.

  10. #10
    Senior Member Regular Contributor
    Join Date
    Jan 2005
    Location
    Stockholm, Sweden
    Posts
    164

    Re: vertex buffer points and element arrays

    Very fine grained LOD is bad for GPUs.
    Why is this? I thought this would be bad for CPU since there would be a lot of tree-traversal involved in deciding what gets passed to GPU.

Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 12
    Last Post: 02-19-2014, 06:13 PM
  2. vertex buffer arrays, one normal per polygon?
    By bensmith87 in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 04-09-2008, 05:21 PM
  3. Trying to use Vertex Arrays and Buffer Objects
    By arnaugm in forum OpenGL: Basic Coding
    Replies: 25
    Last Post: 09-28-2007, 05:13 AM
  4. Vertex buffer arrays and data copy.
    By Obli in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 07-23-2004, 03:08 AM
  5. Element-Arrays?
    By CaseMillennium in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 08-29-2003, 07:41 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean