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

📄 chapter11.html

📁 OpenGl红宝书
💻 HTML
📖 第 1 页 / 共 4 页
字号:
    glBegin(GL_LINES); 
        for (j = nv1; j <= nv2; j++) 
            glEvalCoord2(u1 + i*(u2-u1)/nu, v1+j*(v2-v1)/nv); 
    glEnd(); 
} 
for (j = nv1; j <= nv2; j++) { 
    glBegin(GL_LINES); 
    for (i = nu1; i <= nu2; i++)  
        glEvalCoord2(u1 + i*(u2-u1)/nu, v1+j*(v2-v1)/nv); 
    glEnd(); 
}</PRE>
or
<PRE>for (i = nu1; i &lt; nu2; i++) {&nbsp;&nbsp;&nbsp;&nbsp; /* mode == GL_FILL */&nbsp;
&nbsp;&nbsp;&nbsp; glBegin(GL_QUAD_STRIP);
&nbsp;&nbsp;&nbsp; for (j = nv1; j &lt;= nv2; j++) {&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; glEvalCoord2(u1 + i*(u2-u1)/nu, v1+j*(v2-v1)/nv);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; glEvalCoord2(u1 + (i+1)*(u2-u1)/nu, v1+j*(v2-v1)/nv);
&nbsp;&nbsp;&nbsp; glEnd();&nbsp;
}</PRE>
Example 11-3 shows the differences necessary to draw the same B閦ier surface
as Example 11-2 , but using <B>glMapGrid2()</B> and <B>glEvalMesh2()</B>
to subdivide the square domain into a uniform 8x8 grid. This program also
adds lighting and shading, as shown in Figure 11-3 .
<P><IMG SRC="figures/bezmesh.gif" ALT="[IMAGE]" NOSAVE >
<P><B>Figure 11-3 : </B>A Lit, Shaded B閦ier Surface Drawn Using a Mesh
<BR>&nbsp;
<BR>&nbsp;
<P><B>Example 11-3 : </B>Drawing a Lit, Shaded B閦ier Surface Using a Mesh:
bezmesh.c
<PRE>void initlights(void)
{
&nbsp;&nbsp;&nbsp; GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 };
&nbsp;&nbsp;&nbsp; GLfloat position[] = { 0.0, 0.0, 2.0, 1.0 };
&nbsp;&nbsp;&nbsp; GLfloat mat_diffuse[] = { 0.6, 0.6, 0.6, 1.0 };
&nbsp;&nbsp;&nbsp; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
&nbsp;&nbsp;&nbsp; GLfloat mat_shininess[] = { 50.0 };

&nbsp;&nbsp;&nbsp; glEnable(GL_LIGHTING);
&nbsp;&nbsp;&nbsp; glEnable(GL_LIGHT0);

&nbsp;&nbsp;&nbsp; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
&nbsp;&nbsp;&nbsp; glLightfv(GL_LIGHT0, GL_POSITION, position);
&nbsp;&nbsp;&nbsp; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
&nbsp;&nbsp;&nbsp; glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
&nbsp;&nbsp;&nbsp; glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS, mat_shininess);
}

void display(void)
{
&nbsp;&nbsp;&nbsp; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
&nbsp;&nbsp;&nbsp; glPushMatrix();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; glRotatef(85.0, 1.0, 1.0, 1.0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; glEvalMesh2(GL_FILL, 0, 8, 0, 8);
&nbsp;&nbsp;&nbsp; glPopMatrix();
&nbsp;&nbsp;&nbsp; glFlush();
}

void myinit(void)
{
&nbsp;&nbsp;&nbsp; glClearColor (0.0, 0.0, 0.0, 1.0);
&nbsp;&nbsp;&nbsp; glEnable(GL_DEPTH_TEST);
&nbsp;&nbsp;&nbsp; glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, 1, 12, 4, &amp;ctrlpoints[0][0][0]);
&nbsp;&nbsp;&nbsp; glEnable(GL_MAP2_VERTEX_3);
&nbsp;&nbsp;&nbsp; glEnable(GL_AUTO_NORMAL);
&nbsp;&nbsp;&nbsp; glMapGrid2f(8, 0.0, 1.0, 8, 0.0, 1.0);
&nbsp;&nbsp;&nbsp; initlights();
}</PRE>

<HR>
<H3>
Example: Using Evaluators for Textures</H3>
Example 11-4 enables two evaluators at the same time: The first generates
three-dimensional points on the same B閦ier surface as Example 11-3 , and
the second generates texture coordinates. In this case, the texture coordinates
are the same as the <I>u</I> and <I>v</I> coordinates of the surface, but
a special flat B閦ier patch must be created to do this.
<P>The flat patch is defined over a square with corners at (0, 0), (0,
1), (1, 0), and (1, 1); it generates (0, 0) at corner (0, 0), (0, 1) at
corner (0, 1), and so on. Since it's of order 2 (linear degree plus one),
evaluating this texture at the point (<I>u, v</I>) generates texture coordinates
(<I>s, t</I>). It's enabled at the same time as the vertex evaluator, so
both take effect when the surface is drawn. See Figure J-26 . If you want
the texture to repeat three times in each direction, change every 1.0 in
the array <B>texpts[][][]</B> to 3.0. Since the texture wraps in this example,
the surface is rendered with nine copies of the texture map.
<P><B>Example 11-4 : </B>Using Evaluators for Textures: texturesurf.c
<PRE>#include &lt;GL/gl.h>
#include &lt;GL/glu.h>
#include "aux.h"
#include &lt;math.h>

GLfloat ctrlpoints[4][4][3] = {
&nbsp;&nbsp;&nbsp; {{ -1.5, -1.5, 4.0}, { -0.5, -1.5, 2.0},&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}},&nbsp;
&nbsp;&nbsp;&nbsp; {{ -1.5, -0.5, 1.0}, { -0.5, -0.5, 3.0},&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}},&nbsp;
&nbsp;&nbsp;&nbsp; {{ -1.5, 0.5, 4.0}, { -0.5, 0.5, 0.0},&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}},&nbsp;
&nbsp;&nbsp;&nbsp; {{ -1.5, 1.5, -2.0}, { -0.5, 1.5, -2.0},&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}}
};

GLfloat texpts[2][2][2] = {{{0.0, 0.0}, {0.0, 1.0}},&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {{1.0, 0.0}, {1.0, 1.0}}};

void display(void)
{
&nbsp;&nbsp;&nbsp; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
&nbsp;&nbsp;&nbsp; glColor3f(1.0, 1.0, 1.0);
&nbsp;&nbsp;&nbsp; glEvalMesh2(GL_FILL, 0, 20, 0, 20);
&nbsp;&nbsp;&nbsp; glFlush();
}

#define&nbsp;&nbsp; imageWidth 64
#define&nbsp;&nbsp; imageHeight 64
GLubyte&nbsp;&nbsp; image[3*imageWidth*imageHeight];

void loadImage(void)
{
&nbsp;&nbsp;&nbsp; int i, j;
&nbsp;&nbsp;&nbsp; float ti, tj;

&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; imageWidth; i++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ti = 2.0*3.14159265*i/imageWidth;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (j = 0; j &lt; imageHeight; j++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tj = 2.0*3.14159265*j/imageHeight;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image[3*(imageHeight*i+j)] =&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (GLubyte) 127*(1.0+sin(ti));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image[3*(imageHeight*i+j)+1] =&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (GLubyte) 127*(1.0+cos(2*tj));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image[3*(imageHeight*i+j)+2] =&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (GLubyte) 127*(1.0+cos(ti+tj));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; }
}

void myinit(void)
{
&nbsp;&nbsp;&nbsp; glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, 1, 12, 4, &amp;ctrlpoints[0][0][0]);
&nbsp;&nbsp;&nbsp; glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, 1, 4, 2, &amp;texpts[0][0][0]);
&nbsp;&nbsp;&nbsp; glEnable(GL_MAP2_TEXTURE_COORD_2);
&nbsp;&nbsp;&nbsp; glEnable(GL_MAP2_VERTEX_3);
&nbsp;&nbsp;&nbsp; glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
&nbsp;&nbsp;&nbsp; loadImage();
&nbsp;&nbsp;&nbsp; glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
&nbsp;&nbsp;&nbsp; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GL_REPEAT);
&nbsp;&nbsp;&nbsp; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GL_REPEAT);
&nbsp;&nbsp;&nbsp; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GL_NEAREST);
&nbsp;&nbsp;&nbsp; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GL_NEAREST);
&nbsp;&nbsp;&nbsp; glTexImage2D(GL_TEXTURE_2D, 0, 3, imageWidth, imageHeight,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, GL_RGB, GL_UNSIGNED_BYTE, image);
&nbsp;&nbsp;&nbsp; glEnable(GL_TEXTURE_2D);
&nbsp;&nbsp;&nbsp; glEnable(GL_DEPTH_TEST);
&nbsp;&nbsp;&nbsp; glEnable(GL_NORMALIZE);
&nbsp;&nbsp;&nbsp; glShadeModel (GL_FLAT);
}

void myReshape(GLsizei w, GLsizei h)
{
&nbsp;&nbsp;&nbsp; glViewport(0, 0, w, h);
&nbsp;&nbsp;&nbsp; glMatrixMode(GL_PROJECTION);
&nbsp;&nbsp;&nbsp; glLoadIdentity();
&nbsp;&nbsp;&nbsp; if (w &lt;= h)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; glOrtho(-4.0, 4.0, -4.0*(GLfloat)h/(GLfloat)w,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.0*(GLfloat)h/(GLfloat)w, -4.0, 4.0);
&nbsp;&nbsp;&nbsp; else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; glOrtho(-4.0*(GLfloat)w/(GLfloat)h,&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.0*(GLfloat)w/(GLfloat)h, -4.0, 4.0, -4.0, 4.0);

&nbsp;&nbsp;&nbsp; glMatrixMode(GL_MODELVIEW);
&nbsp;&nbsp;&nbsp; glLoadIdentity();
&nbsp;&nbsp;&nbsp; glRotatef(85.0, 1.0, 1.0, 1.0);
}


int main(int argc, char** argv)
{
&nbsp;&nbsp;&nbsp; auxInitDisplayMode (AUX_SINGLE | AUX_RGBA | AUX_DEPTH);
&nbsp;&nbsp;&nbsp; auxInitPosition (0, 0, 300, 300);
&nbsp;&nbsp;&nbsp; auxInitWindow (argv[0]);
&nbsp;&nbsp;&nbsp; myinit();
&nbsp;&nbsp;&nbsp; auxReshapeFunc (myReshape);
&nbsp;&nbsp;&nbsp; auxMainLoop(display);
}</PRE>

<HR>
<H2>
The GLU NURBS Interface</H2>
Although evaluators are the only OpenGL primitive available to directly
draw curves and surfaces, and even though they can be implemented very
efficiently in hardware, they're often accessed by applications through
higher-level libraries. The GLU provides a NURBS (Non-Uniform Rational
B-Spline) interface built on top of the OpenGL evaluator commands.
<P>
<HR>
<H3>
A Simple NURBS Example</H3>
If you understand NURBS, writing OpenGL code to manipulate NURBS curves
and surfaces is relatively easy, even with lighting and texture mapping.
Follow these steps to draw NURBS curves or untrimmed NURBS surfaces. (Trimmed
surfaces are discussed in "Trimming." )
<OL>If you intend to use lighting with a NURBS surface, call <B>glEnable()</B>
with GL_AUTO_NORMAL to automatically generate surface normals. (Or you
can calculate your own.)
<BR>&nbsp;
<P>Use <B>gluNewNurbsRenderer()</B> to create a pointer to a NURBS object,
which is referred to when creating your NURBS curve or surface.
<BR>&nbsp;
<P>If desired, call <B>gluNurbsProperty()</B> to choose rendering values,
such as the maximum size of lines or polygons that are used to render your
NURBS object.
<BR>&nbsp;
<P>Call <B>gluNurbsCallback()</B> if you want to be notified when an error
is encountered. (Error checking may slightly degrade performance.)
<BR>&nbsp;
<P>Start your curve or surface by calling <B>gluBeginCurve()</B> or <B>gluBeginSurface()</B>.
<BR>&nbsp;
<P>Generate and render your curve or surface. Call <B>gluNurbsCurve()</B>
or <B>gluNurbsSurface()</B> at least once with the control points (rational
or nonrational), knot sequence, and order of the polynomial basis function
for your NURBS object. You might call these functions additional times
to specify surface normals and/or texture coordinates.
<BR>&nbsp;
<P>Call <B>gluEndCurve()</B> or <B>gluEndSurface() </B>to complete the
curve or surface.</OL>
Example 11-5 renders a NURBS surface in the shape of a symmetrical hill
with control points ranging from -3.0 to 3.0. The basis function is a cubic
B-spline, but the knot sequence is nonuniform, with a multiplicity of 4
at each endpoint, causing the basis function to behave like a B閦ier curve
in each direction. The surface is lighted, with a dark gray diffuse reflection
and white specular highlights. Figure 11-4 shows the surface as a wireframe
and lighted.
<P><IMG SRC="figures/surface.both.gif" ALT="[IMAGE]" NOSAVE >
<P><B>Figure 11-4 : </B>A NURBS Surface
<BR>&nbsp;
<BR>&nbsp;
<P><B>Example 11-5 : </B>Drawing a NURBS Surface: surface.c
<PRE>#include &lt;GL/gl.h>
#include &lt;GL/glu.h>
#include "aux.h"

GLfloat ctlpoints[4][4][3];
GLUnurbsObj *theNurb;

void init_surface(void)
{
&nbsp;&nbsp;&nbsp; int u, v;
&nbsp;&nbsp;&nbsp; for (u = 0; u &lt; 4; u++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (v = 0; v &lt; 4; v++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( (u == 1 || u == 2) &amp;&amp; (v == 1 || v == 2))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctlpoints[u][v][2] = 3.0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctlpoints[u][v][2] = -3.0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; }&nbsp;
}

void myinit(void)
{
&nbsp;&nbsp;&nbsp; GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
&nbsp;&nbsp;&nbsp; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
&nbsp;&nbsp;&nbsp; GLfloat mat_shininess[] = { 100.0 };

&nbsp;&nbsp;&nbsp; glClearColor (0.0, 0.0, 0.0, 1.0);

⌨️ 快捷键说明

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