Welcome to the new Friends-of-FPC!

Here you can find all kinds of information about the FreePascal Compiler. We have many tutorials and howtos as well as a selection of tools to help you with your programming. We also have some example codes for you. And if you want to contribute some information/ sources/ tools yourself you can do so.
Also we have finally relaunched the FoFPC forum. It's your chance for some Q&A about everything FreePascal.

Friends-of-FPC

Tutorials: Learn how to code with FreePascal.

Source Codes: A collection of examples, miscellaneous source codes and open source stuff.

Tools and Help Files: Intro- duction of some tools that might help you with FPC.

Community

Forum: Ask or answer questions about the FreePascal Compiler, programming or just babble about coding.

Contribute! Contribute your own Tutorial, Source Codes or Tools and send them to us!

Website

About: Information about Friends-of-FPC.org.

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

Useful Links









Link to us