📄 chapter06.html
字号:
Define Normal Vectors for Each Vertex of All the Objects</H4>
An object's normals determine its orientation relative to the light sources.
For each vertex, OpenGL uses the assigned normal to determine how much
light that particular vertex receives from each light source. In this example,
the normals for the sphere are defined as part of the <B>auxSolidSphere()</B>
routine. See "Normal Vectors" for more details on how to define normals.
<H4>
Create, Position, and Enable One or More Light Sources</H4>
Example 6-1 uses only one, white light source; its location is specified
by the <B>glLightfv()</B> call. This example uses the default color for
light zero (GL_LIGHT0), which is white; if you had wanted a differently
colored light, you'd use <B>glLight*()</B> to indicate this. You can include
at least eight different light sources in your scene of various colors;
the default color of these other lights is black. (The particular implementation
of OpenGL you're using might allow more than eight.) You can also locate
the lights wherever you desire - you can position them near the scene,
as a desk lamp would be, or an infinite distance away, like the sun. In
addition, you can control whether a light produces a narrow, focused beam
or a wider beam. Remember that each light source adds significantly to
the calculations needed to render the scene, so performance is affected
by the number of lights in the scene. See "Creating Light Sources" for
more information about how to create lights with the desired characteristics.
<P>After you've defined the characteristics of the lights you want, you
have to turn them on with the <B>glEnable()</B> command. You also need
to call this command with GL_LIGHTING as a parameter to prepare OpenGL
to perform lighting calculations. See "Enabling Lighting" for more information
about how to do this.
<H4>
Select a Lighting Model</H4>
As you might expect, the <B>glLightModel*()</B> command describes the parameters
of a lighting model. In Example 6-1 , the only element of the lighting
model that's defined explicitly is the global ambient light. The lighting
model also defines whether the viewer of the scene should be considered
to be an infinite distance away or local to the scene, and whether lighting
calculations should be performed differently for the front and back surfaces
of objects in the scene. Example 6-1 uses the default settings for these
two aspects of the model - an infinite viewer and one-sided lighting. Using
a local viewer adds significantly to the complexity of the calculations
that must be performed because OpenGL must calculate the angle between
the viewpoint and each object. With an infinite viewer, however, the angle
is ignored, and the results are slightly less realistic. Further, since
in this example, the back surface of the sphere is never seen (it's the
inside of the sphere), one-sided lighting is sufficient. The section "Selecting
a Lighting Model" describes the elements of an OpenGL lighting model in
more detail.
<H4>
Define Material Properties for the Objects in the Scene</H4>
An object's material properties determine how it reflects light and therefore
what material it seems to be made of. Because the interaction between an
object's material surface and incident light is complex, specifying material
properties so that an object has a certain desired appearance is an art.
You can specify a material's ambient, diffuse, and specular colors and
how shiny it is. In this example, only these last two material properties
- the specular material color and shininess - are explicitly specified
(with the <B>glMaterialfv()</B> calls). "Defining Material Properties"
describes and gives examples of all the material-property parameters.
<H4>
Some Important Notes</H4>
As you write your own lighting program, remember that you can use the default
values for some lighting parameters; others need to be changed. Also, don't
forget to enable whatever lights you define and to enable lighting calculations.
Finally, remember that you might be able to use display lists to maximize
efficiency as you change lighting conditions; see "Display-List Design
Philosophy."
<P>
<BR>
<HR>
<H2>
Creating Light Sources</H2>
Light sources have a number of properties, such as color, position, and
direction. The following sections explain how to control these properties
and what the resulting light looks like. The command used to specify all
properties of lights is <B>glLight*()</B>; it takes three arguments: to
identify the light whose property is being specified, the property, and
the desired value for that property. void <B>glLight</B>{if}[v](GLenum
<I>light</I>,
GLenum <I>pname</I>, <I>TYPEparam</I>);
<P>Creates the light specified by <I>light</I>, which can be GL_LIGHT0,
GL_LIGHT1, ... , or GL_LIGHT7. The characteristic of the light being set
is defined by <I>pname</I>, which specifies a named parameter (see Table
6-1 ). The <I>param </I>argument indicates the values to which the <I>pname</I>
characteristic is set; it's a pointer to a group of values if the vector
version is used, or the value itself if the nonvector version is used.
The nonvector version can be used to set only single-valued light characteristics.
<TABLE BORDER CELLPADDING=10 >
<CAPTION ALIGN=TOP><B>Table 6-1 : </B>Default Values for pname Parameter
of glLight*()</CAPTION>
<TR ALIGN=LEFT VALIGN=TOP>
<TH>Parameter Name</TH>
<TH>Default Value</TH>
<TH>Meaning</TH>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_AMBIENT</TD>
<TD>(0.0, 0.0, 0.0, 1.0)</TD>
<TD>ambient RGBA intensity of light</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_DIFFUSE</TD>
<TD>(1.0, 1.0, 1.0, 1.0)</TD>
<TD>diffuse RGBA intensity of light</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_SPECULAR</TD>
<TD>(1.0, 1.0, 1.0, 1.0)</TD>
<TD>specular RGBA intensity of light</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_POSITION</TD>
<TD>(0.0, 0.0, 1.0, 0.0)</TD>
<TD>(<I>x, y, z, w</I>) position of light</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_SPOT_DIRECTION</TD>
<TD>(0.0, 0.0, -1.0)</TD>
<TD>(<I>x, y, z</I>) direction of spotlight</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_SPOT_EXPONENT</TD>
<TD>0.0</TD>
<TD>spotlight exponent</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_SPOT_CUTOFF</TD>
<TD>180.0</TD>
<TD>spotlight cutoff angle</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_CONSTANT_ATTENUATION</TD>
<TD>1.0</TD>
<TD>constant attenuation factor</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_LINEAR_ATTENUATION</TD>
<TD>0.0</TD>
<TD>linear attenuation factor</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_QUADRATIC_ATTENUATION</TD>
<TD>0.0</TD>
<TD>quadratic attenuation factor</TD>
</TR>
</TABLE>
<BR>
<P>The default values listed for GL_DIFFUSE and GL_SPECULAR in Table 6-1
apply only to GL_LIGHT0. For other lights, the default value is (0.0, 0.0,
0.0, 1.0) for both GL_DIFFUSE and GL_SPECULAR.
<P>Here's an example of using <B>glLight*()</B>:
<PRE>GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);</PRE>
As you can see, arrays are defined for the parameter values, and <B>glLightfv()</B>
is called repeatedly to set the various parameters. In this example, the
first three calls to <B>glLightfv()</B> are superfluous, since they're
being used to specify the default values for the GL_AMBIENT, GL_DIFFUSE,
and GL_SPECULAR parameters.
<P>Remember to turn on each light with <B>glEnable()</B>; see "Enabling
Lighting" for more information about how to do this.
<P>All the parameters for <B>glLight*()</B> and their possible values are
explained in the following sections. These parameters interact with those
that define the overall lighting model for a particular scene and an object's
material properties. See "Selecting a Lighting Model" and "Defining Material
Properties" for more information about these two topics. "The Mathematics
of Lighting" explains how all these parameters interact mathematically.
<H3>
Color</H3>
OpenGL allows you to associate three different color-related parameters
- GL_AMBIENT, GL_DIFFUSE, and GL_SPECULAR - with any particular light.
The GL_AMBIENT parameter refers to the RGBA intensity of the ambient light
that a particular light source adds to the scene. As you can see in Table
6-1 , by default there is no ambient light since GL_AMBIENT is (0.0, 0.0,
0.0, 1.0). This value was used in Example 6-1 . If this program had specified
blue ambient light
<PRE>GLfloat light_ambient[] = { 0.0, 0.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);</PRE>
the result would have been as shown in the left part of Figure J-14 .
<P>The GL_DIFFUSE parameter probably most closely correlates with what
you naturally think of as "the color of a light." It defines the RGBA color
of the diffuse light that a particular light source adds to a scene. By
default, GL_DIFFUSE is (1.0, 1.0, 1.0, 1.0) for GL_LIGHT0, which produces
a bright, white light as shown in Figure J-14 . The default value for any
other light (GL_LIGHT1, ... , GL_LIGHT7) is (0.0, 0.0, 0.0, 0.0).
<P>The GL_SPECULAR parameter affects the color of the specular highlight
on an object. Typically, a real-world object such as a glass bottle has
a specular highlight that's the color of the light shining on it (which
is often white). Therefore, if you want to create a realistic effect, set
the GL_SPECULAR parameter to the same value as the GL_DIFFUSE parameter.
By default, GL_SPECULAR is (1.0, 1.0, 1.0, 1.0) for GL_LIGHT0 and (0.0,
0.0, 0.0, 0.0) for any other light.
<H3>
Position and Attenuation</H3>
As previously mentioned, you can choose whether to have a light source
that's treated as though it's located infinitely far away from the scene
or one that's nearer to the scene. The first type is referred to as an
<I>directional</I>
light source; the effect of an infinite location is that the rays of light
can be considered parallel by the time they reach an object. An example
of a real-world directional light source is the sun. The second type is
called a <I>positional</I> light source, since its exact position within
the scene determines the effect it has on a scene and, specifically, the
direction from which the light rays come. A desk lamp is an example of
a positional light source. You can see the difference between directional
and positional lights in Figure J-16 .
<P>The light used in Example 6-1 is a directional one:
<PRE>GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);</PRE>
As shown, you supply a vector of four values (<I>x, y, z, w</I>) for the
GL_POSITION parameter. If the last value, <I>w</I>, is zero, the corresponding
light source is a directional one, and the (<I>x, y, z</I>) values describe
its direction. This direction is transformed by the modelview matrix just
as it would be if it described a normal vector. By default, GL_POSITION
is (0, 0, 1, 0), which defines a directional light that points along the
negative <I>z</I>-axis. (Note that nothing prevents you from creating a
directional light with the direction of (0, 0, 0), but such a light won't
help you much.)
<P>If the <I>w</I> value is nonzero, the light is positional, and the (<I>x,
y, z</I>) values specify the location of the light in homogeneous object
coordinates (see Appendix G ). This location is transformed by the modelview
matrix and stored in eye coordinates. See "Controlling a Light's Position
and Direction" for more information about how to control the transformation
of the light's location. Also, by default, a positional light radiates
in all directions, but you can restrict it to producing a cone of illumination
by defining the light as a spotlight. The next section, "Spotlights," explains
how to define a light as a spotlight.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -