JavaScript EditorFree JavaScript Editor     Ajax Editor 

Main Page
  Previous Section Next Section

Display Lists

Painting primitives using immediate mode is simple to code, but results in poor performance. We use lots of calls to deliver the geometry, thus fragmenting the bus usage. Luckily, OpenGL has better ways of handling geometry. Generally speaking, two global methods exist (each with some variants): display lists and vertex arrays. In this section we will explore display lists. In the next section we will cover vertex arrays.

Immediate mode commands are sent to the graphics hardware individually. They have to cross the bus, which is by no means a wide, empty road. In fact, it is better to imagine it as a very narrow road with lots of traffic. But graphics hardware has its own readily accessible memory pool. That's where the framer buffer and Z-buffer live, and where textures are held. Luckily, that's where display lists are stored too. A display list is a sequence of OpenGL commands that have been transferred to the server side (the graphics card), so they can be executed locally. Notice that display lists are not just geometry blocks. They really store OpenGL command sequences, much the same way in which many desktop applications allow you to create macros.

Display lists have the obvious advantage of being extremely efficient. No bus overhead is introduced, and thus rendering speed is maximal. But there is a downside to all this: Declaring a display list and placing it in the video card is a time-consuming process, so data cannot be dynamically refreshed. Display lists are great to hold static geometry that does not change during the game's life cycle, but they yield poor performance on dynamic data. As you will soon see, some types of vertex arrays can help with dynamic geometry.

Another caveat of display lists is that they are placed in the graphics card memory if there's memory available. Because there is a limited amount of video memory, the memory display lists use is also limited. If we didn't limit their memory, we would lose their speed because they would have to be stored in system memory.

Working with display lists involves a three-step process:

  1. You need to create an identifier for the list. Identifiers are strictly positive integers, created with the call:

    int glGenLists(int range)

    This call allocates a number of previously unallocated display lists, as specified with the range parameter. The integer returned is the index that marks the beginning of a contiguous block of empty display list identifiers. For example, the call:

    int k=glGenLists(3);



    This means we have three lists allocated with the identifiers 5, 6, and 7. If the requested number of lists is not available, the call returns 0.

  2. Once we have a newly created display list, it is time to fill it with OpenGL commands. This can easily be achieved with the command pair:

    glNewList(int listid, GLenum type);

    The first call opens the display list. All OpenGL commands beyond this point (until reaching the glEndList call) are stored to the list identified by the first parameter. Notice that the list must be created with a previous call to glGenLists, or we might overwrite other lists. The second parameter specifies whether the commands to be packed to the list must only be stored as a display list or be executed as well. The possible values are

    • GL_COMPILE Compiles commands to display list, but does not execute them

    • GL_COMPILE_AND_EXECUTE Compiles commands to display list and executes them

    This allows display list creation to be performed at boot time or in the middle of a rendering loop. But GL_COMPILE is the most common option.

  3. Our display list is ready after the call to glEndList. From that moment, we can execute the code contained in the list with a single OpenGL call, which is

    glCallList(int listid)

    This call runs the list we pass as a parameter.

      Previous Section Next Section

    JavaScript EditorAjax Editor     JavaScript Editor