Display lists or VBO?

I can’t seem to get a definite answer on exactly when to use display list, when to use vertex arrays/VBOs. First off, can a VBO do everything a vertex array can do only faster? Second, if I have static geometry will a display list give similar results to the fastest alternative? From my reading the display list effectively removes all method call overhead, does all calculations ahead of time, and stores the results directly on the video card. This sounds pretty good.

Thanks,

Keith

You should use display lists for static data, while vertex arrays/VBOs for dynamic data.

Yes, I think that is true.

I read and did my own measurements about display lists and can verify that sometimes they are the fastest method.

VAs are for dynamic data
VBOs are for static data
Displaylists are for static data

Using VBOs can save you a lot of vRAM, as you can use indexed data, which is impossible in Displaylists.
The down-side of VBOs is that the amount of calls per object can grow rapidly (vertices, texcoords, normals, indices). With Displaylists you can easily group a few hundred and use only 1 call.

int[] lists = new int[objCount * 2];
lists[0] ---> translate to obj[0].xyz
lists[1] ---> render obj[0]
lists[2] ---> translate to obj[1].xyz (relative to obj[0], so no push/pop required)
lists[3] ---> render obj[1]
// etc etc

glPushMatrix();
glCallLists(IntBuffer);
glPopMatrix();

You can also nest Displaylists:


world list
  - object list
     - sublist: push
     - sublist: translate + rotate
     - sublist: render object
     - sublist: pop
  - object list
     - sublist: push
     - sublist: translate + rotate
     - sublist: render object
     - sublist: pop

When you have to translate+rotate any object in the scene, you only have to change 1 sublist, then call the world-list which will traverse the entire tree.

Another option is to have 1 displaylist contain a rotation for your billboards:


world list
  - object list
     - sublist: push, translate
     - global rotation list
     - sublist: render object, pop
  - object list
     - sublist: push, translate
     - global rotation list
     - sublist: render object, pop

So if you really know what you are doing, displaylists are definitly the way to go (if you can spare some vRAM).

HTH

I don’t think this advice is correct. VBOs can be used for dynamic data as well; that’s why there’s a usage hint in glBufferDataARB. I personally haven’t been able to get really good performance out of dynamic VBOs (compare the VertexArrayRange and VertexBufferObject demos in the jogl-demos workspace), but they’re definitely the way of the future when it comes to rendering either static or dynamic geometry.

I have made some profiling of static data handling in my engine with vertex arrays / VBO / display list. My card is a GeForce 2 GTS.
It gave me this ;
Vertex arrays are always slower. VBO and display list gave the same speed as long as I use a single VBO for all the datas, and as long as the display list only contains the vertice submissions (no state changes).

I choosed to stick to VBO because ;

  • the data model I use easily lets you optimize the way data are submitted,

  • the specification of VBO lets you use them for dynamic datas,

  • I perform heavy state caching to avoid state changes and batch primitives, therefore I would not have included state changes in display list,

  • VBO are more in line with the way DirectX and OpenGL evolves and I think they are more “future proof” (I may be completely wrong).

              Vincent

Hm, you could be right, but for me using the dynamic features of VBOs (yes, I had noticed them) were just as fast as VAs (or even slightly slowly). Not surprising because you’re basicly doing the same as what you would do with VAs: constantly uploading the same data to vRAM.

I could be wrong, it’s been months since I tried to get dynamic VBOs fast.

I have experimented quite a lot with VBOs and VAs in the virtual globe http://globe.sintef.no/ and when I (at last) found out the ups and downs of VBOs they where significantly faster for my semi-dynamic data. With the current code it runs with 30-40 FPS with VBOs but only 10-15 with VAs (when rendering highly complex terrain on a dual 1.7GHz workstation, RADEON 9800, 4xAA, 8xAF). The ratio between VA/VBO speed is consistent with results on other computers.

Here I have double buffered terrain geometry, one thread is generating geometry arrays independently of the render (opengl/AWT) thread. Every few frames (when a new batch of geometry is completed (updating dependent on the movements of the viewpoint)) the update thread and the render thread synchronizes and new geometry is either copied into VBOs or into the render threads VAs. This means that the VBOs are used for a few dozen frames before being updated with new data.

In the first VBO version I tried a very dynamic method, where parts of the VBOs where updated during the rendering, but found that slower than VAs. My conclusion is to stay away from the buffer mapping and buffer sub data calls, it is usually most efficient to replace the whole geometry chunk with a buffer data call.

I have tried all of the usage parameters; STATIC, DYANMIC and STREAM. I found no significant speed difference between them. According to the documentation STREAM shoud be used for data that are updated every frame, but it also works well for data that is used for a few frames. However I got crashes on some systems when the geometry update thread sometimes was late, and the GPU had to use the same STREAM VBO for several seconds. I have now changed to DYNAMIC and have no more problems with that. STATIC also worked, by the way…

Rune

with VBOs you can upload only the parts of the data that has changed (glBufferSubDataARB) thus saving you some bus transfers (really useful for animation)

DP