dennlinger
dennlinger

Reputation: 11420

OpenGL Fog does not appear

I wanted to create a coordinate system with some lines in it, and wanted to display one window with depth-fog.

My "fog-code" looks like this:

glEnable(GL_FOG);
float fogColor[4] = {0.8, 0.8, 0.8, 1};
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogfv(GL_FOG_COLOR, fogColor); 
glFogf(GL_FOG_DENSITY,0.8); 
glHint(GL_FOG_HINT, GL_NICEST);
glFogf(GL_FOG_START,0.1); 
glFogf(GL_FOG_END,200);

and is placed in my main function (don't know yet if this could cause any problems, but just to be sure), right after the init()-call and before my display-function-call.

Update:

The problem was actually really simple: My problem was, that I worked solely on the GL_MODELVIEW-matrix, thinking there was no real difference to the GL_PROJECTION-matrix. According to this article and the post from Reto Koradi, there is a pretty significant difference. I hugely recommend reading the full article to better understand the system behind OpenGL (definitely helped me a lot).

The corrected code (for my init()-call) would then be:

void init2()
{
    glClearColor (1.0, 1.0, 1.0, 0.0); // set background color to white
    glMatrixMode(GL_PROJECTION); // switch to projection mode
    glLoadIdentity(); // initialize a projection matrix
    glOrtho(-300, 300, -300, 300, -800, 800); // map coordinates to the viewport 
    gluLookAt(2,2,10, 0,0,-0.5, 0,1,0);
    glMatrixMode(GL_MODELVIEW); // now switch to modelview mode
}

Upvotes: 1

Views: 1965

Answers (2)

Reto Koradi
Reto Koradi

Reputation: 54592

The fog equation is evaluated based on the value of (quote from OpenGL 2.1 spec):

Otherwise, if the fog source is FRAGMENT DEPTH, then c is the eye-coordinate distance from the eye, (0,0,0,1) in eye coordinates, to the fragment center.

FRAGMENT_DEPTH is the default, so this applies in your case. Eye coordinate refers to the coordinates after the model-view transformation has been applied. So it's the distance from the origin after applying the model-view transform. The spec also allows implementations to use the absolute value of the z-coordinate instead of the distance from the origin.

One small observation on your code: GL_FOG_DENSITY does not matter if the mode is GL_LINEAR. It is only used for the exponential modes.

For GL_LINEAR mode, the behavior is pretty much as you would expect. The original fragment color is linearly blended with the fog color within the range GL_FOG_START to GL_FOG_END. So everything smaller than GL_FOG_START has the original fragment color, everything after GL_FOG_END has the fog color, and the values in between are linear interpolations between the two, with gradually more fog color and less original fragment color.

To get good results, you'll have to play with the GL_FOG_START and GL_FOG_END values. If you don't get as much for as desired, you can start by reducing the value of GL_FOG_END.

I peeked at the linked code, and noticed one problem: You're specifying the projection matrix while you're in GL_MODELVIEW matrix mode. You need to be careful that you specify the matrices in the correct matrix mode, which is GL_PROJECTION for the projection matrix.

Mixing up the matrix modes does not have an adverse effect on the resulting vertex coordinates, since both the model-view and projection matrices are applied to the vertices. So for very simple use, you can sometimes get away with using the wrong mode. But once lighting comes into play, it is critical to use the correct matrix mode, since lighting calculations are done after the model-view transformation has been applied, but before the projection transformation.

And yes, as others already pointed out, a lot of this actually gets simpler if you write your own shaders. The fact that I quoted the OpenGL 2.1 spec is probably a hint that this functionality is old and obsolete.

Upvotes: 2

datenwolf
datenwolf

Reputation: 162164

Like to many things that OpenGL-1.1 did, fog is calculated on a per vertex level. So if you have a long line, with only two points, fog is calculated only for the end points and then the color interpolated linear inbetween. Depending on how your line is aligned and which shading mode you use, this may result in no apparent fogging.

Two solutions:

  • Subdivide the lines into a couple of dozen line segments, so to sample the fog at more than two points.

or

  • Use a fragment shader instead and calculate the fog term therein. This is what I suggest doing.

Upvotes: 1

Related Questions