📄 chapter07.html
字号:
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGBA | AUX_DEPTH);
auxInitPosition (0, 0, 200, 200);
auxInitWindow (argv[0]);
auxMouseFunc (AUX_LEFTBUTTON, AUX_MOUSEDOWN, toggleSmooth);
myinit();
auxReshapeFunc (myReshape);
auxMainLoop(display);
}</PRE>
<HR>
<H2>
Fog</H2>
Computer images sometimes seem unrealistically sharp and well-defined.
Antialiasing makes an object appear more realistic by smoothing its edges.
Additionally, you can make an entire image appear more natural by adding
fog, which makes objects fade into the distance. Fog is a general term
that describes similar forms of atmospheric effects; it can be used to
simulate haze, mist, smoke, or pollution. Fog is essential in visual-simulation
applications, where limited visibility needs to be approximated. It's often
incorporated into flight-simulator displays.
<P>When fog is enabled, objects that are farther from the viewpoint begin
to fade into the fog color. You can control the density of the fog, which
determines the rate at which objects fade as the distance increases, as
well as the fog's color. Fog is available in both RGBA and color-index
modes, although the calculations are slightly different in the two modes.
Since fog is applied after matrix transformations, lighting, and texturing
are performed, it affects transformed, lit, and textured objects. Note
that with large simulation programs, fog can improve performance, since
you can choose not to draw objects that are too fogged to be visible.
<H3>
Using Fog</H3>
Using fog is easy. You enable it by passing GL_FOG to <B>glEnable()</B>,
and you choose the color and the equation that controls the density with
<B>glFog*()</B>. If you want, you can supply a value for GL_FOG_HINT with
<B>glHint()</B>, as described on Table 7-2 . Example 7-6 draws five red
teapots, each at a different distance from the viewpoint. Pressing the
left mouse button selects among the three different fog equations, which
are described in the next section.
<P><B>Example 7-6 : </B>Five Fogged Teapots in RGBA Mode: fog.c
<PRE>#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include "aux.h"
GLint fogMode;
void cycleFog (AUX_EVENTREC *event)
{
if (fogMode == GL_EXP) {
fogMode = GL_EXP2;
printf ("Fog mode is GL_EXP2\n");
}
else if (fogMode == GL_EXP2) {
fogMode = GL_LINEAR;
printf ("Fog mode is GL_LINEAR\n");
glFogf (GL_FOG_START, 1.0);
glFogf (GL_FOG_END, 5.0);
}
else if (fogMode == GL_LINEAR) {
fogMode = GL_EXP;
printf ("Fog mode is GL_EXP\n");
}
glFogi (GL_FOG_MODE, fogMode);
}
void myinit(void)
{
GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 };
GLfloat local_view[] = { 0.0 };
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
glFrontFace (GL_CW);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glEnable(GL_FOG);
{
GLfloat density;
GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0};
fogMode = GL_EXP;
glFogi (GL_FOG_MODE, fogMode);
glFogfv (GL_FOG_COLOR, fogColor);
glFogf (GL_FOG_DENSITY, 0.35);
glHint (GL_FOG_HINT, GL_DONT_CARE);
glClearColor(0.5, 0.5, 0.5, 1.0);
}
}
void renderRedTeapot (GLfloat x, GLfloat y, GLfloat z)
{
float mat[3];
glPushMatrix();
glTranslatef (x, y, z);
mat[0] = 0.1745; mat[1] = 0.01175; mat[2] = 0.01175;
glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
mat[0] = 0.61424; mat[1] = 0.04136; mat[2] = 0.04136;
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
mat[0] = 0.727811; mat[1] = 0.626959; mat[2] = 0.626959;
glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
glMaterialf (GL_FRONT, GL_SHININESS, 0.6*128.0);
auxSolidTeapot(1.0);
glPopMatrix();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderRedTeapot (-4.0, -0.5, -1.0);
renderRedTeapot (-2.0, -0.5, -2.0);
renderRedTeapot (0.0, -0.5, -3.0);
renderRedTeapot (2.0, -0.5, -4.0);
renderRedTeapot (4.0, -0.5, -5.0);
glFlush();
}
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= (h*3))
glOrtho (-6.0, 6.0, -2.0*((GLfloat) h*3)/(GLfloat) w,
2.0*((GLfloat) h*3)/(GLfloat) w, 0.0, 10.0);
else
glOrtho (-6.0*(GLfloat) w/((GLfloat) h*3),
6.0*(GLfloat) w/((GLfloat) h*3), -2.0, 2.0, 0.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGBA | AUX_DEPTH);
auxInitPosition (0, 0, 450, 150);
auxInitWindow (argv[0]);
auxMouseFunc (AUX_LEFTBUTTON, AUX_MOUSEDOWN, cycleFog);
myinit();
auxReshapeFunc (myReshape);
auxMainLoop(display);
}</PRE>
<H3>
Fog Equations</H3>
Fog blends a fog color with an incoming fragment's color using a fog blending
factor. This factor, <B>f</B>, is computed with one of these three equations
and then clamped to the range [0,1].
<P><IMG SRC="figures/eq701.gif" ALT="[IMAGE]" >
<P>where <I>z</I> is the eye-coordinate distance between the viewpoint
and the fragment center. The values for <B>density, start</B>, and <B>end</B>
are all specified with <B>glFog*()</B>. The<B> f</B> factor is used differently,
depending on whether you're in RGBA mode or color-index mode, as explained
in the next subsections. void <B>glFog</B>{if}{v}(GLenum <B>pname</B>,
<B>TYPE param</B>);
<P>Sets the parameters and function for calculating fog. If <B>pname</B>
is GL_FOG_MODE, then <B>param</B> is either GL_EXP (the default), GL_EXP2,
or GL_LINEAR to select one of the three fog factors. If <B>pname</B> is
GL_FOG_DENSITY, GL_FOG_START, or GL_FOG_END, then <B>param</B> is (or points
to, with the vector version of the command) a value for <B>density</B>,
<B>start</B>, or <B>end</B> in the equations. (The default values are 1,
0, and 1, respectively.) In RGBA mode, <B>pname</B> can be GL_FOG_COLOR,
in which case <B>param</B> points to four values that specify the fog's
RGBA color values. The corresponding value for <B>pname</B> in color-index
mode is GL_FOG_INDEX, for which <B>param</B> is a single value specifying
the fog's color index.
<P>Figure 7-4 plots the fog-density equations for various values of the
parameters. You can use linear fog to achieve a depth-cuing effect, as
shown in Figure J-2 .
<P><IMG SRC="figures/Fig7-4.gif" ALT="[IMAGE]" >
<P><B>Figure 7-4 : </B>Fog-Density Equations
<BR>
<BR>
<H4>
Fog in RGBA Mode</H4>
In RGBA mode, the fog factor <I>f</I> is used as follows to calculate the
final fogged color:
<P>C = <I>f</I> Ci + (1 - <I>f</I> ) Cf
<P>where Ci represents the incoming fragment's RGBA values and Cf the fog-color
values assigned with GL_FOG_COLOR.
<H4>
Fog in Color-Index Mode</H4>
In color-index mode, the final fogged color index is computed as follows:
<P>I = Ii + (1 - <I>f</I> ) If
<P>where Ii is the incoming fragment's color index and If is the fog's
color index as specified with GL_FOG_INDEX.
<P>To use fog in color-index mode, you have to load appropriate values
in a color ramp. The first color in the ramp is the color of the object
without fog, and the last color in the ramp is the color of the completely
fogged object. You probably want to use <B>glClearIndex()</B> to initialize
the background color index so that it corresponds to the last color in
the ramp; this way, totally fogged objects blend into the background. Similarly,
before objects are drawn, you should call <B>glIndex*()</B> and pass in
the index of the first color in the ramp (the unfogged color). Finally,
to apply fog to different colored objects in the scene, you need to create
several color ramps, and call <B>glIndex*()</B> before each object is drawn
to set the current color index to the start of each color ramp. Example
7-7 illustrates how to initialize appropriate conditions and then apply
fog in color-index mode.
<P><B>Example 7-7 : </B>Using Fog in Color-Index Mode: fogindex.c
<PRE>#include <GL/gl.h>
#include <GL/glu.h>
#include "aux.h"
#define NUMCOLORS 32
#define RAMPSTART 16
void myinit(void)
{
int i;
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
for (i = 0; i < NUMCOLORS; i++) {
GLfloat shade;
shade = (GLfloat) (NUMCOLORS-i)/(GLfloat) NUMCOLORS;
auxSetOneColor (16 + i, shade, shade, shade);
}
glEnable(GL_FOG);
glFogi (GL_FOG_MODE, GL_LINEAR);
glFogi (GL_FOG_INDEX, NUMCOLORS);
glFogf (GL_FOG_START, 0.0);
glFogf (GL_FOG_END, 4.0);
glHint (GL_FOG_HINT, GL_NICEST);
glClearIndex((GLfloat) (NUMCOLORS+RAMPSTART-1));
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
glTranslatef (-1.0, -1.0, -1.0);
glRotatef (-90.0, 1.0, 0.0, 0.0);
glIndexi (RAMPSTART);
auxSolidCone(1.0, 2.0);
glPopMatrix ();
glPushMatrix ();
glTranslatef (0.0, -1.0, -2.25);
glRotatef (-90.0, 1.0, 0.0, 0.0);
glIndexi (RAMPSTART);
auxSolidCone(1.0, 2.0);
glPopMatrix ();
glPushMatrix ();
glTranslatef (1.0, -1.0, -3.5);
glRotatef (-90.0, 1.0, 0.0, 0.0);
glIndexi (RAMPSTART);
auxSolidCone(1.0, 2.0);
glPopMatrix ();
glFlush();
}
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (-2.0, 2.0, -2.0*(GLfloat)h/(GLfloat)w,
2.0*(GLfloat)h/(GLfloat)w, 0.0, 10.0);
else
glOrtho (-2.0*(GLfloat)w/(GLfloat)h,
2.0*(GLfloat)w/(GLfloat)h, -2.0, 2.0, 0.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_INDEX | AUX_DEPTH);
auxInitPosition (0, 0, 200, 200);
auxInitWindow (argv[0]);
myinit();
auxReshapeFunc (myReshape);
auxMainLoop(display);
}</PRE>
<HR><A HREF="chapter06.html">[Previous chapter]</A> <A HREF="chapter08.html">[Next
chapter]
<HR></A>See the <A HREF="about.html">About</A> page for copyright, authoring
and distribution information.
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -