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 8 - by Delax

This time, we'll take a look at the depth functions. To explain what the depth functions do, let's look at an example.

Let's say we are drawing two triangles behind each other and then rotate the matrix. Normally, we would expect to see the two triangles rotate around the Axis. Let's take a look at the reality.

  glClear( GL_COLOR_BUFFER_BIT );
  glLoadIdentity();

  glRotatef( rotation, 0.0, 1.0, 0.0 );                         

  glBegin( GL_TRIANGLES );

    glColor3f(1.0, 0.0, 0.0);  

    glVertex3f(0.0, 1.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.0);
    glVertex3f(1.0, -1.0, 0.0);

    glColor3f(0.0, 1.0, 0.0);  

    glVertex3f(0.0, 1.0, 1.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glVertex3f(1.0, -1.0, 1.0);

  glEnd();

Download the example, compile and run it. Take a close look. Something seems wrong: the green triangle is always in front of the red one, even if it is behind it. Strange, huh?

Just because a primitive is behind another, it does not mean OpenGL is really drawing it behind the primitive. In fact, OpenGL is drawing the surfaces from back to front. The first surface that gets drawn is behind the second one and so on. As we are drawing the red triangle before the green one, it is always covered by it.

Now one has a couple of possibilities to draw everything "correct". The first one is to sort the surfaces in some way so that the farest primitive is drawn before the nearest one. The other is to use the depth functions to do this for you. Every pixel gets a depth value. If a new surface is drawn, this depth value is checked if the surface is behind another surface.

To activate the depth functions, a simple glEnable() is sufficient. Of course you have to give some additional information about how the depth buffer should work etc. Here are the new lines for the OpenGL_Init procedure.

  glClearDepth( 1.0);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

The first line is defining the clearing value for the depth buffer. This is much like the glClearColor() command but for the depth buffer. We activate depth testing by calling glEnable(GL_DEPTH_TEST);.

We choose glDepthFunc(GL_LEQUAL); as our depth function. GL_LEQUAL means "less or equal", so everything that is less or equal the actual value gets drawn. The value for the depth buffer is calculated 1/Z-value. So a Z-value of 2 would be smaller than a Z-value of 1 as 1/1 > 1/2. With GL_LEQUAL the Z-Value of 2 would be drawn as it is in front of the surface with Z = 1.

So now you should be able to understand the glClearDepth() parameter. The valid range is from 0.0 to 1.0. If the value is 1.0 and we work with GL_LEQUAL, every new value is less or equal one. If we would use the clearing value 0.0 and user LEQUAL, nothing would get drawn as nothing could produce a smaller value than 0.0. In this case one would use GL_GREATER, but this would mean that the near surfaces would be behind the far ones.

Whew, this was not easy to explain - especially as this is not my native language. I hope you got the point. If not let's put it this way: with glClearDepth(1.0) and glDepthFunc(GL_LEQUAL);, everything should work as you are "used to it".

And there is one other thing. We set the clearing value, but we have to tell OpenGL that it sould do the actual clearing. We expand our clearing command to glClear(GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT); and everything should work now. Get the complete source code here. As you can see the triangles get drawn in the right order.

Delax/ Sundancer Inc.
[delax@sundancerinc.de]

Back to previous page

Useful Links









Link to us