📄 chapter11.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 11 - 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 11<BR>
Evaluators and NURBS</H1>
<B>Chapter Objectives</B>
<P><B>Advanced</B>
<P>After reading this chapter, you'll be able to do the following:
<UL>Use OpenGL's evaluator commands to draw basic curves and surfaces
<BR>
<P>Use the GLU's higher-level NURBS facility to draw more complex curves
and surfaces</UL>
Note that this chapter presumes a number of prerequisites; they're listed
in "Prerequisites" .
<P>At the lowest level, graphics hardware draws points, line segments,
and polygons, which are usually triangles and quadrilaterals. Smooth curves
and surfaces are drawn by approximating them with large numbers of small
line segments or polygons. However, many useful curves and surfaces can
be described mathematically by a small number of parameters such as a few
<I>control points</I>. Saving the sixteen control points for a surface
requires much less storage than saving 1000 triangles together with the
normal vector information at each vertex. In addition, the 1000 triangles
only approximate the true surface, but the control points can accurately
describe the real surface.
<P>Evaluators provide a way to specify points on a curve or surface (or
part of one) using only the control points. The curve or surface can then
be rendered at any precision. In addition, normal vectors can be calculated
for surfaces automatically. You can use the points generated by an evaluator
in many ways - to draw dots where the surface would be, to draw a wireframe
version of the surface, or to draw a fully lighted and shaded version.
<P>You can use evaluators to describe any polynomial or rational polynomial
splines or surfaces of any degree. These include almost all splines and
spline surfaces in use today, including B-splines, NURBS (Non-Uniform Rational
B-Spline) surfaces, B閦ier curves and surfaces, and Hermite splines. Since
evaluators provide only a low-level description of the points on a curve
or surface, however, they're typically used underneath utility libraries
that provide a higher-level interface to the programmer. The GLU's NURBS
facility is such a higher-level interface - the NURBS routines encapsulate
lots of complicated code, but the final rendering is done with evaluators.
<P>This chapter contains the following major sections:
<UL>"Prerequisites" discusses what knowledge is assumed for this chapter.
It also gives several references where you can obtain this information.
<BR>
<P>"Evaluators" explains how evaluators work and how to control them using
the appropriate OpenGL commands.
<BR>
<P>"The GLU NURBS Interface" describes the GLU routines for creating NURBS
surfaces.</UL>
<HR>
<H2>
<A NAME="X"></A>Prerequisites</H2>
Evaluators make splines and surfaces that are based on a B閦ier (or Bernstein)
basis. The defining formulas for the functions in this basis are given
in this chapter, but the discussion doesn't include derivations or even
lists of all their interesting mathematical properties. If you want to
use evaluators to draw curves and surfaces using other bases, you must
know how to convert your basis to a B閦ier basis. In addition, when you
render a B閦ier surface or part of it using evaluators, you need to determine
the granularity of your subdivision. Your decision needs to take into account
the trade-off between high-quality (highly subdivided) images and high
speed. Determining an appropriate subdivision strategy can be quite complicated,
and it's not discussed here.
<P>Similarly, a complete discussion of NURBS is beyond the scope of this
book. The GLU NURBS interface is documented here, however, and programming
examples are provided for readers who already understand the subject. In
what follows, we assume that you know about NURBS control points, knot
sequences, and trimming curves.
<P>If you lack some of these prerequisites, the following references will
help.
<UL>Burns, Derrick. <I>Dynamic Trimmed Surface Rendering</I>. Ph.D. dissertation,
Stanford University, 1993.
<BR>
<P>de Boor, Carl. <I>A Practical Guide to Splines</I>. New York: Springer-Verlag,
1985.
<BR>
<P>Farin, Gerald. <I>Curves and Surfaces for Computer-Aided Geometric Design</I>.
San Diego, Calif: Academic Press, 1990.
<BR>
<P>Mortenson, Michael. <I>Geometric Modeling</I>. New York: John Wiley
& Sons, 1985.
<BR>
<P>Newman, William and Sproull, Robert. <I>Principles of Interactive Computer
Graphics</I>. New York: McGraw-Hill, 1979.</UL>
Some of the terms used in this chapter might have slightly different meanings
in other books on spline curves and surfaces, since there isn't total agreement
among the practitioners of this art. Generally, the OpenGL meanings are
a bit more restrictive. For example, OpenGL evaluators always use B閦ier
bases; in other contexts, evaluators might refer to the same concept, but
with an arbitrary basis.
<P>
<HR>
<H2>
Evaluators</H2>
A B閦ier curve is a vector-valued function of one variable
<P><B>C</B>(<I>u</I>) = [<B>X</B>(<I>u</I>) <B>Y</B>(<I>u</I>) <B>Z</B>(<I>u</I>)]
<P>where <I>u</I> varies in some domain (say [0,1]). A B閦ier surface patch
is a vector-valued function of two variables
<P><B>S</B>(<I>u,v</I>) = [<B>X</B>(<I>u,v</I>) <B>Y</B>(<I>u,v</I>) <B>Z</B>(<I>u,v</I>)]
<P>where <I>u</I> and <I>v</I> can both vary in some domain. The range
isn't necessarily three-dimensional as shown here. You might want two-dimensional
output for curves on a plane or texture coordinates, or you might want
four-dimensional output to specify RGBA information. Even one-dimensional
output may make sense for gray levels, for example.
<P>For each <I>u</I> (or <I>u</I> and <I>v</I>, in the case of a surface),
the formula for <B>C()</B> (or <B>S()</B>) calculates a point on the curve
(or surface). To use an evaluator, first define the function <B>C()</B>
or <B>S()</B>, enable it, and then use the <B>glEvalCoord1()</B> or <B>glEvalCoord2()</B>
command instead of <B>glVertex()</B>. This way, the curve or surface vertices
can be used like any other vertices - to form points or lines, for example.
In addition, other commands automatically generate series of vertices that
produce a regular mesh uniformly spaced in <I>u</I> (or in <I>u</I> and
<I>v</I>). One- and two-dimensional evaluators are similar, but the description
is somewhat simpler in one dimension, so that case is discussed first.
<P>
<HR>
<H3>
One-Dimensional Evaluators</H3>
This section presents an example of using one-dimensional evaluators to
draw a curve. It then describes the commands and equations that control
evaluators.
<H4>
One-Dimensional Example: A Simple B閦ier Curve</H4>
The program shown in Example 11-1 draws a cubic B閦ier curve using four
control points, as shown in Figure 11-1 .
<P><IMG SRC="figures/bezcurve.gif" ALT="[IMAGE]" NOSAVE >
<P><B>Figure 11-1 : </B>A B閦ier Curve
<BR>
<BR>
<P><B>Example 11-1 : </B>Drawing a B閦ier Curve Using Four Control Points:
bezcurve.c
<PRE>#include <GL/gl.h>
#include <GL/glu.h>
#include "aux.h"
GLfloat ctrlpoints[4][3] = {
{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},
{2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};
void myinit(void)
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4,&ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
glShadeModel(GL_FLAT);
}
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord1f((GLfloat) i/30.0);
glEnd();
/* The following code displays the control points as dots. */
glPointSize(5.0);
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_POINTS);
for (i = 0; i < 4; i++)
glVertex3fv(&ctrlpoints[i][0]);
glEnd();
glFlush();
}
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0*(GLfloat)w/(GLfloat)h,
5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);
auxInitPosition (0, 0, 500, 500);
auxInitWindow (argv[0]);
myinit();
auxReshapeFunc (myReshape);
auxMainLoop(display);
}</PRE>
A cubic B閦ier curve is described by four control points, which appear
in this example in the <B>ctrlpoints[][]</B> array. This array is one of
the arguments to <B>glMap1f()</B>. All the arguments for this command are
as follows:
<DL>
<DT>
GL_MAP1_VERTEX_3</DT>
<DD>
</DD>
<BR>Three-dimensional vertices are produced
<DT>
</DT>
<BR>0
<DD>
</DD>
<BR>Low value of parameter <B>u</B>
<DT>
</DT>
<BR>1
<DD>
</DD>
<BR>High value of parameter <B>u</B>
<DT>
</DT>
<BR>3
<DD>
</DD>
<BR>The number of floating-point values to advance in the data between
one control point and the next
<DT>
</DT>
<BR>4
<DD>
</DD>
<BR>The order of the spline, which is the degree+1; in this case, the degree
is 3 (since the curve is a cubic)
<DT>
</DT>
<BR>&ctrlpoints[0][0]
<DD>
</DD>
<BR>Pointer to the first control point's data</DL>
Note that the second and third arguments control the parameterization of
the curve - as the variable <I>u</I> ranges from 0 to 1, the curve goes
from one end to the other. The call to <B>glEnable()</B> enables the one-dimensional
evaluator for two-dimensional vertices.
<P>The curve is drawn in the routine <B>display() </B>between the <B>glBegin()
</B>and <B>glEnd()</B> calls. Since the evaluator is enabled, the command
<B>glEvalCoord1f()</B> is just like issuing a <B>glVertex()</B> command
with coordinates that are the coordinates of a vertex on the curve corresponding
to the input parameter <I>u</I>.
<H4>
Defining and Evaluating a One-Dimensional Evaluator</H4>
The Bernstein polynomial of degree <B>n</B> (or order <B>n</B>+1) is given
by
<P><IMG SRC="figures/eq1101.gif" ALT="[IMAGE]" NOSAVE >
<P>If Pi represents a set of control points (one-, two-, three-, or even
four- dimensional), then the equation
<P><IMG SRC="figures/eq1102.gif" ALT="[IMAGE]" NOSAVE >
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -