Sign in to follow this  
TimmerCA

OpenGL Display Lists

Recommended Posts

TimmerCA    100
Hi,

I'm building my terrain as a series blocks that get dynamically created as they come into view and destroyed as they go out of view. Each terrain block contains 64x64 = 4096 tiles, and each tile is made up of two triangles. Each block builds an OpenGL display list when it is instantiated. At each frame, I just use glCallList to draw each block. At any given time there are between 9 and maybe 15 terrain blocks visible. So, for each frame I'm calling glCallList between 9 and 15 times.

However, even with everything loaded into display lists and nothing much else going on at each frame, I'm seeing terrible frame rates - in the mid-to-upper teens generally speaking.

If I shrink my block size down to 16x16 tiles, I get up to about 22 or 23 fps. Still not great, but much better.

Is there some limit to the size of display lists? It would appear that drawing one big display list is slower than drawing several smaller ones. Is this understanding correct?

Share this post


Link to post
Share on other sites
mmakrzem    1036
What else is in your scene? Are you triangles textured? What is the size of your cliping boundaries?

I use display lists to render text on the screen. Basically two triangles per letter. I can have 100's of characters on the screen at a time and I don't see any slow downs.

Share this post


Link to post
Share on other sites
cmasupra    145
You don't mention if these are 2D or 3D blocks. Also, do you consider your computer to be good enough to do that kind of drawing? You are drawing 4096x9=36,864 tiles, which is a lot in my opinion.

Share this post


Link to post
Share on other sites
TimmerCA    100
[quote name='mmakrzem' timestamp='1311534244' post='4839686']
What else is in your scene? Are you triangles textured? What is the size of your cliping boundaries?

I use display lists to render text on the screen. Basically two triangles per letter. I can have 100's of characters on the screen at a time and I don't see any slow downs.
[/quote]

In addition to the terrain, I have a handful (less than 50) trees that I've drawn by hand. Each uses maybe 100 triangles.

Currently, there are no textures.

I have alpha blending enabled, as well as depth buffering and lighting.

By clipping boundaries, do you mean what frustum am I using? I'm using gluPerspective to build that:

[code]GLU.gluPerspective(
80.0f,
16.0f / 9.0f,
0.1f,
500.0f
); [/code]

Share this post


Link to post
Share on other sites
TimmerCA    100
[quote name='cmasupra' timestamp='1311536716' post='4839707']
You don't mention if these are 2D or 3D blocks. Also, do you consider your computer to be good enough to do that kind of drawing? You are drawing 4096x9=36,864 tiles, which is a lot in my opinion.
[/quote]

Sorry, it's 3D.

This is a Dell laptop with a Core i7 8-core processor, 8GB system memory, and an nVidia GeForce GT 555M discreet graphics card with 3GB of RAM. I regularly play games (WOW, LFD2, Civ5, etc) at high resolution and "full" graphics settings and achieve frame rates in the 45's - 60's.

Share this post


Link to post
Share on other sites
TimmerCA    100
[quote name='TimmerCA' timestamp='1311524570' post='4839639']
If I shrink my block size down to 16x16 tiles, I get up to about 22 or 23 fps. Still not great, but much better.
[/quote]

I should also have mentioned than when I do shrink down the individual block size, I simultaneously increase the number of blocks by an amount that causes the system to draw approximately the same number of vertices on the screen. The only real difference is that there are more call lists each with a smaller (about 1/4) number of polygons.

Share this post


Link to post
Share on other sites
mhagain    13430
First thing is to find out where exactly your performance problems are coming from; drawing (or use of display lists) may not be the root cause (it may well be your dynamic generation and destruction, for example). So comment out your drawing commands (specifically your glCallLists calls) and measure performance. That'll give you a good indication of how much performance impact your drawing has on your overall program. Work back from there to identify the point at which performance goes back up again, and you've found your bottleneck.

Share this post


Link to post
Share on other sites
TimmerCA    100
[quote name='mhagain' timestamp='1311538390' post='4839716']
First thing is to find out where exactly your performance problems are coming from; drawing (or use of display lists) may not be the root cause (it may well be your dynamic generation and destruction, for example). So comment out your drawing commands (specifically your glCallLists calls) and measure performance. That'll give you a good indication of how much performance impact your drawing has on your overall program. Work back from there to identify the point at which performance goes back up again, and you've found your bottleneck.
[/quote]

I'm fairly certain it's not during the block computation. When I first start the game up, block computation takes a few hundred milliseconds, but then once that's done it doesn't happen again until I move to another block. If I just start the game, and don't move at all, my frame rate is still in the upper teens even though no computation is taking place.

I'll try profiling the process and see if that can give me any insight into what's going on.

Share this post


Link to post
Share on other sites
frob    44904
[quote name='TimmerCA' timestamp='1311524570' post='4839639']
I'm building my terrain as a series blocks that get dynamically created as they come into view and destroyed as they go out of view. Each terrain block contains 64x64 = 4096 tiles, and each tile is made up of two triangles. Each block builds an OpenGL display list when it is instantiated. [/quote]
I'm surprised nobody mentioned this part already.


Don't do that. That was how things were done in the mid 90's. There were all kinds of fancy routines for continuous level of detail and other fancy stuff.

Then someone came along with a programable pipeline. The GeForce 3 video card programmable vertex shaders transformed the world of terrain rendering.

Vertex shaders and geometry clipmaps can render many thousand square miles of detailed terrain with practically zero effort. It will automatically be at the best LOD. About the only significant issue is that it doesn't morph between LOD levels, but that is a very tiny price to pay since you can include so much higher details at every level.

[url="http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter02.html"]Here is the classic GPU Gems article (with source) on how to do it[/url], though newer and fancier algorithms exist. You get better visual results for far less memory, plus it frees up the cpu and the bus for more important tasks.



[font="arial, verdana, tahoma, sans-serif"][size="2"][quote name='TimmerCA' timestamp='1311524570' post='4839639']
Each terrain block contains 8192 triangles. At any given time there are between 9 and maybe 15 terrain blocks visible. So, for each frame I'm calling glCallList between 9 and 15 times.[/quote][/size][/font][font="arial, verdana, tahoma, sans-serif"][size="2"]Those are tiny. The video card can process those without effort.[/size][/font]
[font="arial, verdana, tahoma, sans-serif"] [/font][font="arial, verdana, tahoma, sans-serif"][size="2"][quote]However, even with everything loaded into display lists and nothing much else going on at each frame, I'm seeing terrible frame rates - in the mid-to-upper teens generally speaking. Is there some limit to the size of display lists? It would appear that drawing one big display list is slower than drawing several smaller ones. Is this understanding correct? [/quote][/size][/font][font="arial, verdana, tahoma, sans-serif"][size="2"]The problem is not with display lists. Display lists are just batches of instructions.[/size][/font][size="2"]The problem is that you are saturating the communications with your card on trivialities. You are flooding the bus between your CPU and GPU by [/size]re-transmitting[size="2"] your data in tiny pieces every frame.[/size]
[font="arial, verdana, tahoma, sans-serif"] [/font][font="arial, verdana, tahoma, sans-serif"][size="2"]Dump all of it to the card up front. Let it live on the video card memory. Use a shader on the video card to process it. If you can't dump it all at once, create a really big interleaved array and dump that to the video card every frame. At least then you are using a single transfer rather than a ton of tiny stored commands.[/size][/font]

Share this post


Link to post
Share on other sites
TimmerCA    100
[font="arial, verdana, tahoma, sans-serif"] [/font][quote]The problem is not with display lists. Display lists are just batches of instructions. [size="2"]The problem is that you are saturating the communications with your card on trivialities. You are flooding the bus between your CPU and GPU by [/size]re-transmitting[size="2"] your data in tiny pieces every frame. [/size]Dump all of it to the card up front. Let it live on the video card memory. Use a shader on the video card to process it. If you can't dump it all at once, create a really big interleaved array and dump that to the video card every frame. At least then you are using a single transfer rather than a ton of tiny stored commands.[/quote]

I think I'm either misunderstanding you, or you're misunderstanding me.

When the terrain block is generated, it creates a display list and stores that display list ID in a local variable. At each frame, I'm only calling glCallList(display_list) for each terrain block, which is about 9-15 blocks at any given time. I'm not re-generating the display list at every frame; that would be silly. :)

Share this post


Link to post
Share on other sites
frob    44904
[quote name='TimmerCA' timestamp='1311822693' post='4841419']
[font="arial, verdana, tahoma, sans-serif"] [/font][quote]The problem is not with display lists. Display lists are just batches of instructions. [size="2"]The problem is that you are saturating the communications with your card on trivialities. You are flooding the bus between your CPU and GPU by [/size]re-transmitting[size="2"] your data in tiny pieces every frame. [/size]Dump all of it to the card up front. Let it live on the video card memory. Use a shader on the video card to process it. If you can't dump it all at once, create a really big interleaved array and dump that to the video card every frame. At least then you are using a single transfer rather than a ton of tiny stored commands.[/quote]

I think I'm either misunderstanding you, or you're misunderstanding me.

When the terrain block is generated, it creates a display list and stores that display list ID in a local variable. At each frame, I'm only calling glCallList(display_list) for each terrain block, which is about 9-15 blocks at any given time. I'm not re-generating the display list at every frame; that would be silly. :)
[/quote]

Ah, I think I see the misunderstanding.

Using a display list is not free. It is only specified to probably not be slower than immediate mode.

It is unspecified where display lists are placed. While they *MIGHT* be placed on the card, there is no requirement to do so.

You are correct that there is a tiny performance benefit by making the list up front. The drivers will pre-process them and compress them. But that's all they do.

Neither ATI nor NVidia have publicly stated what they do with lists. So people have monitored bus transfers on drivers from NVidia and ATI in the past and found that they keep them in main memory in an arbitrary format. They generate and compress the command stream, but still must re-transmit it on every use. There is only minimal performance improvement over redrawing everything yourself.

You are using the worst case form of display lists -- a bunch of tiny lists. There is overhead associated with each one, you should prefer one large display list over multiple tiny lists.

Finally display lists are depricated in GL3.0 The replacement is to move it over to the card and do it in the way mentioned above, which has been the preferred way of doing it for over a decade.

Share this post


Link to post
Share on other sites
Dragonion    131
[quote name='TimmerCA' timestamp='1311524570' post='4839639']It would appear that drawing one big display list is slower than drawing several smaller ones. Is this understanding correct?[/quote]
Display lists have pretty much been replaced with [i]static vertex buffer objects[/i] (VBOs created with GL_STATIC_READ usage), and in general when using these the more data/meshes you put into a single object the better performance. Ideally, all vertices used to generate the scene should be placed in a single object and drawn with a single call so that the graphics card can plow right through them.

BTW (edit): If you think your code is correctly implemented with respect to the OpenGL guidelines and you still get a really poor performance there is a chance you are overlooking something in the WGL documentation (assuming you are developing for Windows). Personally I remember getting a really low frame-rate some time ago because I missed some detail about multi-threaded applications.

Share this post


Link to post
Share on other sites
mhagain    13430
GL_STATIC_DRAW, surely?

Worth noting also that GL makes so guarantees as to the location of VBOs either, and a given implementation may store them in system memory. Highly unlikely of course.

Share this post


Link to post
Share on other sites
Dragonion    131
[quote name='mhagain' timestamp='1311849830' post='4841513']GL makes so guarantees as to the location of VBOs either, and a given implementation may store them in system memory. Highly unlikely of course.[/quote]
But then again, GL doesn't make any guarantee that data in display lists are not stored in system memory, either.

[quote name='mhagain' timestamp='1311849830' post='4841513']Worth noting[/quote]
I got a pretty good frame-rate on a rather old computer (from 2005) with 360,000 textured polygons on the screen using VBOs, so "worth nothing" is perhaps a little harsh judgement.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this