|

OpenGL/ FPC - Chapter 16 - by Delax
It was planned to carry on with pointed light but I think you earned yourself a break. So this chapter is about display lists. As you'll see, they are not only shortening your OpenGL code, but speed up performance, save space, make coffee and everything. But what are display lists? Simple said: they are a list of OpenGL calls stored in one variable.
To show you the use of a display list, let's start off with a simple example. Let's create a pillar with 4 sides, with bottom (4 quads), body (4 quads) and a top (4 triangles). Making 12 surfaces or 44 vertices.
glBegin(GL_QUADS);
glColor3f( 0.0, 0.0, 0.5 );
glNormal3f(0.0,0.0,1.0);
glVertex3f( 10.0,-10.0, 0.0);
glVertex3f( 10.0, 10.0, 0.0);
glVertex3f(-10.0, 10.0, 0.0);
glVertex3f(-10.0,-10.0, 0.0);
glEnd();
glTranslatef( 0.0, 0.0, 1.0);
glColor3f( 0.9, 0.0, 0.0 );
glBegin(GL_QUADS);
glNormal3f(1.0, 0.0, 0.0);
glVertex3f( 1.0, 1.0,-1.0);
glVertex3f( 1.0, 1.0, 1.0); // rechts unten
glVertex3f( 1.0,-1.0, 1.0);
glVertex3f( 1.0,-1.0,-1.0);
glNormal3f(-1.0, 0.0, 0.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0,-1.0); // links unten
glVertex3f(-1.0,-1.0,-1.0);
glVertex3f(-1.0,-1.0, 1.0);
glNormal3f(0.0,1.0,0.0);
glVertex3f( 1.0, 1.0, 1.0);
glVertex3f( 1.0, 1.0,-1.0); // hinten unten
glVertex3f(-1.0, 1.0,-1.0);
glVertex3f(-1.0, 1.0, 1.0);
glNormal3f(0.0, -1.0, 0.0);
glVertex3f( 1.0,-1.0,-1.0);
glVertex3f( 1.0,-1.0, 1.0); // vorne unten
glVertex3f(-1.0,-1.0, 1.0);
glVertex3f(-1.0,-1.0,-1.0);
FindNormal(-0.5,0.5,6.0,0.5,0.5,6.0,1.0,1.0,1.0);
glNormal3f(CNormal[1], CNormal[2], CNormal[3]);
glVertex3f(-0.5, 0.5, 6.0);
glVertex3f( 0.5, 0.5, 6.0); // vorne oben
glVertex3f( 1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
FindNormal(0.5,-0.5,6.0,-0.5,-0.5,6.0,-1.0,-1.0,1.0);
glNormal3f(CNormal[1], CNormal[2], CNormal[3]);
glVertex3f( 0.5,-0.5, 6.0);
glVertex3f(-0.5,-0.5, 6.0); // hinten oben
glVertex3f(-1.0,-1.0, 1.0);
glVertex3f( 1.0,-1.0, 1.0);
FindNormal(1.0,1.0,1.0,0.5,0.5,6.0,0.5,-0.5,6.0);
glNormal3f(CNormal[1], CNormal[2], CNormal[3]);
glVertex3f( 1.0, 1.0, 1.0);
glVertex3f( 0.5, 0.5, 6.0); // rechts oben
glVertex3f( 0.5,-0.5, 6.0);
glVertex3f( 1.0,-1.0, 1.0);
FindNormal(-0.5,0.5,6.0,-1.0,1.0,1.0,-1.0,-1.0,1.0);
glNormal3f(CNormal[1], CNormal[2], CNormal[3]);
glVertex3f(-0.5, 0.5, 6.0);
glVertex3f(-1.0, 1.0, 1.0); // links oben
glVertex3f(-1.0,-1.0, 1.0);
glVertex3f(-0.5,-0.5, 6.0);
glEnd();
glBegin(GL_TRIANGLES);
FindNormal(-0.5,0.5,6.0,0.0,0.0,7.0,0.5,0.5,6.0);
glNormal3f(CNormal[1], CNormal[2], CNormal[3]);
glVertex3f(-0.5, 0.5, 6.0);
glVertex3f( 0.0, 0.0, 7.0);
glVertex3f( 0.5, 0.5, 6.0); // vorne oben
FindNormal(0.5,-0.5,6.0,0.0,0.0,7.0,-0.5,-0.5,6.0);
glNormal3f(CNormal[1], CNormal[2], CNormal[3]);
glVertex3f( 0.5,-0.5, 6.0);
glVertex3f( 0.0, 0.0, 7.0);
glVertex3f(-0.5,-0.5, 6.0); // hinten oben
FindNormal(0.5,0.5,6.0,0.0,0.0,7.0,0.5,-0.5,6.0);
glNormal3f(CNormal[1], CNormal[2], CNormal[3]);
glVertex3f( 0.5, 0.5, 6.0); // rechts oben
glVertex3f( 0.0, 0.0, 7.0);
glVertex3f( 0.5,-0.5, 6.0);
FindNormal(-0.5,-0.5,6.0,0.0,0.0,7.0,-0.5,0.5,6.0);
glNormal3f(CNormal[1], CNormal[2], CNormal[3]);
glVertex3f(-0.5,-0.5, 6.0);
glVertex3f( 0.0, 0.0, 7.0);
glVertex3f(-0.5, 0.5, 6.0); // links oben
glEnd;
There you go. Get the example here and look at it.
All right? Seen it? Now do the following: draw 4 pillars on one plane, standing next to each other. Have fun.
You may think "That's insane!". Well, you'd have to calculate the coordinates for another 220 vertices. Not what I call a fun time. But by using display lists, you may re-use the object over and over again.
So a display list stores OpenGL calls like "set vertex" or "do light" and the like. Right now we'll store our pillar in a list. To do this we need an integer variable ad an ID for our list. Then we call Variable := glGenLists() and our ID is now pointing to a list.
After the creation of the list we just have to fill it. First, we need to tell OpenGL which list we want to fill. We do this with glNewList(). The first parameter is the name of the list, the second is how the list should be handled. For now, we'll use GL_COMPILE, meaning we just want to fill it and execute it later.
Now following are simple OpenGL calls. Do what you want. You can even call other procedures (for example to calculate normals etc). If you are done filling the list, close it with glEndList();
After we created the list, we can execute it with glCallList(). So every time we call it, the list gets executed drawing our stuff. In our example, we would draw a pillar, translate and draw the next one.
glColor3f( 0.0, 0.0, 0.5 );
glTranslatef( 0.0, 0.0, 1.0);
glCallList(Ground);
glColor3f( 0.9, 0.0, 0.0 );
glTranslatef( 5.0,5.0,0.0);
glCallList(Pillar);
glColor3f( 0.0, 0.9, 0.0 );
glTranslatef( 0.0,-10.0,0.0);
glCallList(Pillar);
glColor3f( 0.9, 0.9, 0.0 );
glTranslatef(-10.0,0.0,0.0);
glCallList(Pillar);
glColor3f( 0.0, 0.9, 0.9 );
glTranslatef(0.0,10.0,0.0);
glCallList(Pillar);
So the drawing of four pillars is smaller than the drawing of one pillar the direct way. Our OpenGL drawing procedure got a lot more readable. Just grab the example and look for yourself.
As another advantage we don't need to calculate the normals everytime. They are calculated once at the beginning and then just called from the list. Also most of the 3d cards can execute display lists faster than normal OpenGL calls as they cache them.
Now that you got this far, you get a little candy. Compile it and have some fun ;)
Delax/ Sundancer Inc.
[delax@sundancerinc.de]
Back to previous page
|