⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter13.html

📁 OpenGl红宝书
💻 HTML
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-2">
   <META NAME="GENERATOR" CONTENT="Mozilla/4.07 [en] (Win98; I) [Netscape]">
   <META NAME="Author" CONTENT="Goran UnreaL Krajnovic">
   <TITLE>Chapter 13 - OpenGL Programming Guide (Addison-Wesley Publishing Company)</TITLE>
</HEAD>
<BODY BGCOLOR="#EFEFEF" LINK="#0000FF" VLINK="#551A8B" ALINK="#FF0000">

<DIV ALIGN=right><IMG SRC="figures/SGI_ID.gif" ALT="Silicon Graphics" NOSAVE HEIGHT=43 WIDTH=151 ALIGN=TEXTTOP></DIV>

<HR>
<H1>
Chapter 13<BR>
Now That You Know</H1>
<B>Chapter Objectives</B>
<P>This chapter doesn't have objectives in the same way that previous chapters
do. It's simply a collection of topics that describe ideas you might find
useful for your application.
<P>OpenGL is kind of a bag of low-level tools; now that you know about
those tools, you can use them to implement higher-level functions. This
chapter presents several examples of such higher-level capabilities.
<P>This chapter discusses a variety of techniques based on OpenGL commands
that illustrate some of the not-so-obvious uses to which you can put these
commands. The examples are in no particular order and aren't related to
each other. The idea is to read the section headings and skip to the examples
that you find interesting. For your convenience, the headings are listed
and explained briefly here.
<P>Most of the examples in the rest of this guide are complete and can
be compiled and run as is. In this chapter, however, there are no complete
programs, and you have to do a bit of work on your own to make them run.
<UL>"Cheesy Translucency" explains how to use polygon stippling to achieve
translucency; this is particularly useful when you don't have blending
hardware available.
<BR>&nbsp;
<P>"An Easy Fade Effect" shows how to use polygon stippling to create the
effect of a fade into the background.
<BR>&nbsp;
<P>"Object Selection Using the Back Buffer" describes how to use the back
buffer in a double-buffered system to handle simple object picking.
<BR>&nbsp;
<P>"Cheap Image Transformation" discusses how to draw a distorted version
of a bitmapped image by drawing each pixel as a quadrilateral.
<BR>&nbsp;
<P>"Displaying Layers" explains how to display multiple different layers
of materials and indicate where the materials overlap.
<BR>&nbsp;
<P>"Antialiased Characters" describes how to draw smoother fonts.
<BR>&nbsp;
<P>"Drawing Round Points" describes how to draw near-round points.
<BR>&nbsp;
<P>"Interpolating Images" shows how to smoothly blend from one image to
the another.
<BR>&nbsp;
<P>"Making Decals" explains how to draw two images, where one is a sort
of decal that should always appear on top of the other.
<BR>&nbsp;
<P>"Drawing Filled, Concave Polygons Using the Stencil Buffer" tells you
how to draw concave polygons, nonsimple polygons, and polygons with holes
by using the stencil buffer.
<BR>&nbsp;
<P>"Finding Interference Regions" describes how to determine where three-dimensional
pieces overlap.
<BR>&nbsp;
<P>"Shadows" describes how to draw shadows of lit objects.
<BR>&nbsp;
<P>"Hidden-Line Removal" discusses how to draw a wireframe object with
hidden lines removed by using the stencil buffer.
<BR>&nbsp;
<P>"Texture-Mapping Applications" describes several clever uses for texture
mapping, such as rotating and warping images.
<BR>&nbsp;
<P>"Drawing Depth-Buffered Images" tells you how to combine images in a
depth-buffered environment.
<BR>&nbsp;
<P>"Dirichlet Domains" explains how to find the Dirichlet domain of a set
of points using the depth buffer.
<BR>&nbsp;
<P>"Life in the Stencil Buffer" explains how to implement the Game of Life
using the stencil buffer.
<BR>&nbsp;
<P>"Alternative Uses for glDrawPixels() and glCopyPixels()" describes how
to use these two commands for such effects as fake video, airbrushing,
and transposed images.</UL>

<HR>
<H2>
<A NAME="X"></A>Cheesy Translucency</H2>
You can use polygon stippling to simulate a translucent material. This
is an especially good solution for systems that don't have blending hardware.
Since polygon stipple patterns are 32x32 bits, or 1024 bits, you can go
from opaque to transparent in 1023 steps. For example, if you want a surface
that lets through 29 percent of the light, simply make up a stipple pattern
where 29 percent (roughly 297) of the pixels in the mask are 0 and the
rest are 1. Even if your surfaces have the same translucency, don't use
the same stipple pattern for each one, as they cover exactly the same bits
on the screen. Make up a different pattern for each by randomly selecting
the appropriate number of pixels to be 0. See "Displaying Points, Lines,
and Polygons" for more information about polygon stippling.
<P>If you don't like the effect with random pixels turned on, you can use
regular patterns, but they don't work as well when transparent surfaces
are stacked. This is often not a problem because most scenes have relatively
few translucent regions that overlap. In a picture of an automobile with
translucent windows, your line of sight can go through at most two windows,
and usually it's only one.
<P>
<HR>
<H2>
An Easy Fade Effect</H2>
Suppose you have an image that you want to fade gradually to some background
color. Define a series of polygon stipple patterns, each of which has more
bits turned on so that they represent denser and denser patterns. Then
use these patterns repeatedly with a polygon large enough to cover the
region over which you want to fade. For example, suppose you want to fade
to black in sixteen steps. First define sixteen different pattern arrays:
<PRE>GLubyte stips[16][4*32];</PRE>
Then load them in such a way that each has one-sixteenth of the pixels
in a 32x32 stipple pattern turned on. After that, the following code does
the trick:
<PRE>draw_the_picture();&nbsp;
glColor3f(0.0, 0.0, 0.0);&nbsp;&nbsp;&nbsp; /* set color to black */&nbsp;
for (i = 0; i &lt; 16; i++) {&nbsp;
&nbsp;&nbsp;&nbsp; glPolygonStipple(&amp;stips[i][0]);&nbsp;
&nbsp;&nbsp;&nbsp; draw_a_polygon_large_enough_to_cover_the_whole_region();&nbsp;
}</PRE>
In some OpenGL implementations, you might get better performance by first
compiling the stipple patterns into display lists. During your initialization,
do something like this:
<PRE>#define STIP_OFFSET 100&nbsp;
for (i = 0; i &lt; 16; i++) {&nbsp;
&nbsp;&nbsp;&nbsp; glNewList(i+STIP_OFFSET, GL_COMPILE);&nbsp;
&nbsp;&nbsp;&nbsp; glPolygonStipple(&amp;stips[i][0]);&nbsp;
&nbsp;&nbsp;&nbsp; glEndList();&nbsp;
}</PRE>
Then, replace this line in the first code fragment
<PRE>glPolygonStipple(&amp;stips[i][0]);</PRE>
with
<PRE>glCallList(i);</PRE>
By compiling the command to set the stipple into a display list, OpenGL
might be able to rearrange the data in the stips[ ][ ] array into the hardware-specific
form required for maximum stipple-setting speed.
<P>Another application for this technique is if you're drawing a changing
picture, and you want to leave some blur behind that gradually fades out
to give some indication of past motion. For example, suppose you're simulating
a planetary system, and you want to leave trails on the planets to show
a recent portion of their path. Again, assuming you want to fade in sixteen
steps, set up the stipple patterns as before (using the display-list version,
say), and have the main simulation loop look something like this:
<PRE>current_stipple = 0;&nbsp;
while (1) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* loop forever */&nbsp;
&nbsp;&nbsp;&nbsp; draw_the_next_frame();&nbsp;
&nbsp;&nbsp;&nbsp; glCallList(current_stipple++);&nbsp;
&nbsp;&nbsp;&nbsp; if (current_stipple == 16) current_stipple = 0;&nbsp;
&nbsp;&nbsp;&nbsp; glColor3f(0.0, 0.0, 0.0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* set color to black */&nbsp;
&nbsp;&nbsp;&nbsp; draw_a_polygon_large_enough_to_cover_the_whole_region();&nbsp;
}</PRE>
Each time through the loop, you clear one-sixteenth of the pixels. Any
pixel that hasn't had a planet on it for sixteen frames is certain to be
cleared to black. Of course, if your system supports blending in hardware,
it's easier to blend in a certain amount of background color with each
frame.
<P>See "Displaying Points, Lines, and Polygons" for polygon stippling details,
Chapter 4, "Display Lists," for more information about display lists, and
"Blending" for information about blending.
<P>
<HR>
<H2>
Object Selection Using the Back Buffer</H2>
Although OpenGL's selection mechanism (see "Selection" ) is powerful and
flexible, it can be cumbersome to use. Often, the situation is simple:
Your application draws a scene composed of a substantial number of objects;
the user points to an object with the mouse, and the application needs
to find the item under the tip of the cursor.
<P>One way to do this requires your application to be running in double-buffer
mode. When the user picks an object, the application redraws the entire
scene in the back buffer, but instead of using the normal colors for objects,
it encodes some kind of object identifier for each object's color. The
application then simply reads back the pixel under the cursor, and the
value of that pixel encodes the number of the picked object.
<P>Note that this scheme has an advantage over standard selection in that
it picks the object that's in front, if multiple objects appear at the
same pixel, one behind the other. Since the image with false colors is
drawn in the back buffer, the user never sees it; you can redraw the back
buffer (or copy it from the front buffer) before swapping the buffers.
In color-index mode, the encoding is simple - send the object identifier
as the index. In RGBA mode, encode the bits of the identifier into the
R, G, and B components.
<P>Be aware that you can run out of identifiers if there are too many objects
in the scene. For example, suppose you're running in color-index mode on
a system that has 4-bit buffers for color-index information (sixteen possible
different indices) in each of the color buffers, but the scene has thousands
of pickable items. To address this issue, the picking can be done in a
few passes. For definiteness, assume there are fewer than 4096 items, so
all the object identifiers can be encoded in 12 bits. In the first pass,
draw the scene using indices composed of the 4 high-order bits, then use
the second and third passes to draw the middle 4 bits and the 4 low-order
bits. After each pass, read the pixel under the cursor, extract the bits,
and pack them together at the end to get the object identifier.
<P>With this method, the picking takes three times as long, but that's
often acceptable. Note that after you have the high-order 4 bits, you eliminate
fifteen of the sixteen possible objects, so you really only need to draw
one-sixteenth of them for the second pass. Similarly, after the second
pass, 255 of the 256 possible items have been eliminated. The first pass
thus takes about as long as drawing a single frame does, but the second
and third passes can be up to 16 and 256 times as fast.
<P>If you're trying to write portable code that works on different systems,
break up your object identifiers into chunks that fit on the lowest common
denominator of those systems. Also, keep in mind that your system might
perform automatic dithering in RGB mode. If this is the case, turn off
dithering.
<P>
<HR>
<H2>
Cheap Image Transformation</H2>
Suppose you want to draw a distorted version of a bitmapped image (perhaps
simply stretched or rotated, or perhaps drastically modified by some mathematical
function). In many cases, you can achieve good results by drawing the image
of each pixel as a quadrilateral. Although this scheme doesn't produce
images as nice as those you would get by applying a sophisticated filtering
algorithm (and it might not be sufficient for sophisticated users), it's
a lot quicker.
<P>To make the problem more concrete, assume that the original image is
<B>m</B> pixels by <B>n</B> pixels, with coordinates chosen from [0,<B>
m</B>-1] 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -