Graphics 版 (精华区)

发信人: JJason (UFO), 信区: Graphics
标  题: Jeff Molofee(NeHe) 的 OPENGL 教程-第05课
发信站: 哈工大紫丁香 (2002年10月31日08:39:20 星期四), 站内信件

标题     向3D进军:Jeff Molofee(NeHe) 的 OPENGL 教程 -第五课    cker(翻译)  
  
关键字     OpenGL CKER 
  
出处     http://nehe.gamedev.net/tutorials/ 
  

Jeff Molofee(NeHe) 的 OPENGL 教程 
 
第五课 
 Translated by 
CKER 
 



在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3
D世界中的2D对象。我们给三角形增加一个左侧面,一个右侧面,一个后侧面来生成一个金
字塔(四棱锥)。给正方形增加左、右、上、下及背面生成一个立方体。 

我们混合金字塔上的颜色,创建一个平滑着色的对象。给立方体的每一面则来个不同的颜
色。  
int DrawGLScene(GLvoid) // 此过程中包括所有的绘制代码 

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存 
glLoadIdentity(); // 重置模型观察矩阵 
glTranslatef(-1.5f,0.0f,-6.0f); // 左移 1.5 单位,并移入屏幕 6.0 

glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转金字塔 

glBegin(GL_TRIANGLES); // 开始绘制金字塔的各个面 
 
有些人可能早已在上节课中的代码上尝试自行创建3D对象了。但经常有人来信问我:"我的
对象怎么不会绕着其自身的轴旋转?看起来总是在满屏乱转。"要让您的对象绕自身的轴旋
转,您必须让对象的中心坐标总是(0.0f,0,0f,0,0f)。 
下面的代码创建一个绕者其中心轴旋转的金字塔。金字塔的上顶点离中心一个单位,底面
离中心也是一个单位。上顶点在底面的投影位于底面的中心。 

注意所有的面-三角形都是逆时针次序绘制的。这点十分重要,在以后的课程中我会作出
解释。现在,您只需明白要么都逆时针,要么都顺时针,但永远不要将两种次序混在一起
,除非您有足够的理由必须这么做。 

我们开始画金字塔的前侧面。因为所有的面都共享上顶点,我们将这点在所有的三角形中
都设置为红色。底边上的两个顶点的颜色则是互斥的。前侧面的左下顶点是绿色的,右下
顶点是蓝色的。这样相邻右侧面的左下顶点是蓝色的,右下顶点是绿色的。这样四边形的
底面上的点的颜色都是间隔排列的。  
glColor3f(1.0f,0.0f,0.0f); // 红色 
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (前侧面) 
glColor3f(0.0f,1.0f,0.0f); // 绿色 
glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的左下顶点 (前侧面) 
glColor3f(0.0f,0.0f,1.0f); // 蓝色 
glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的右下顶点 (前侧面)  
现在绘制右侧面。注意其底边上的两个顶点的X坐标位于中心右侧的一个单位处。顶点则位
于Y轴上的一单位处,且Z坐标正好处于底边的两顶点的Z坐标中心。右侧面从上顶点开始向
外侧倾斜至底边上。 
这次的左下顶点用蓝色绘制,以保持与前侧面的右下顶点的一致。蓝色将从这个角向金字
塔的前侧面和右侧面扩展并与其他颜色混合。 
还应注意到后面的三个侧面和前侧面处于同一个glBegin(GL_TRIANGLES) 和 glEnd()语句
中间。因为我们是通过三角形来构造这个金字塔的。OpenGL知道每三个点构成一个三角形
。当它画完一个三角形之后,如果还有余下的点出现,它就以为新的三角形要开始绘制了
。OpenGL在这里并不会将四点画成一个四边形,而是假定新的三角形开始了。所以千万不
要无意中增加任何多余的点。  
glColor3f(1.0f,0.0f,0.0f); // 红色 
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (右侧面) 
glColor3f(0.0f,0.0f,1.0f); // 蓝色 
glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的左下顶点 (右侧面) 
glColor3f(0.0f,1.0f,0.0f); // 绿色 
glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的右下顶点 (右侧面)  
现在是后侧面。再次切换颜色。左下顶点又回到绿色,因为后侧面与右侧面共享这个角。 
 
glColor3f(1.0f,0.0f,0.0f); // 红色 
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (后侧面) 
glColor3f(0.0f,1.0f,0.0f); // 绿色 
glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的左下顶点 (后侧面) 
glColor3f(0.0f,0.0f,1.0f); // 蓝色 
glVertex3f(-1.0f,-1.0f, -1.0f); // 三角形的右下顶点 (后侧面)  
最后画左侧面。又要切换颜色。左下顶点是蓝色,与后侧面的右下顶点相同。右下顶点是
蓝色,与前侧面的左下顶点相同。 
到这里金字塔就画完了。因为金字塔只绕着Y轴旋转,我们永远都看不见底面,因而没有必
要添加底面。如果您觉得有经验了,尝试增加底面(正方形),并将金字塔绕X轴旋转来看看
您是否作对了。确保底面四个顶点的颜色与侧面的颜色相匹配。  
glColor3f(1.0f,0.0f,0.0f); // 红色 
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (左侧面) 
glColor3f(0.0f,0.0f,1.0f);// 蓝色 
glVertex3f(-1.0f,-1.0f,-1.0f); // 三角形的左下顶点 (左侧面) 
glColor3f(0.0f,1.0f,0.0f); // 绿色 
glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的右下顶点 (左侧面) 
glEnd(); file://金字塔绘制结束  
接下来开始画立方体。他由六个四边形组成。所有的四边形都以逆时针次序绘制。就是说
先画右上角,然后左上角、左下角、最后右下角。您也许认为画立方体的背面的时候这个
次序看起来好像顺时针,但别忘了我们从立方体的背后看背面的时候,与您现在所想的正
好相反。(译者注:您是从立方体的外面来观察立方体的)。 
注意到这次我们将立方体移地更远离屏幕了。因为立方体的大小要比金字塔大,同样移入6
个单位时,立方体看起来要大的多。这是透视的缘故。越远的对象看起来越小 :) 。  
glLoadIdentity(); 
glTranslatef(1.5f,0.0f,-7.0f); // 先右移再移入屏幕 

glRotatef(rquad,1.0f,1.0f,1.0f); // 在XYZ轴上旋转立方体 

glBegin(GL_QUADS); // 开始绘制立方体  
先画立方体的顶面。从中心上移一单位,注意Y坐标始终为一单位,表示这个四边形与Z轴
平行。先画右上顶点,向右一单位,再屏幕向里一单位。然后左上顶点,向左一单位,再
屏幕向里一单位。然后是靠近观察者的左下和右下顶点。就是屏幕往外一单位。  
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色 
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点 (顶面) 
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点 (顶面) 
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点 (顶面) 
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点 (顶面)  
底面的画法和顶面十分类似。只是Y坐标变成了-1。如果我们从立方体的下面来看立方体
的话,您会注意到右上角离观察者最近,因此我们先画离观察者最近的顶点。然后是左上
顶点最后才是屏幕里面的左下和右下顶点。 

如果您真的不在乎绘制多边形的次序(顺时针或者逆时针)的话,您可以直接拷贝顶面的代
码,将Y坐标从1改成 -1,也能够工作。但一旦您进入象纹理映射这样的领域时,忽略绘制
次序会导致十分怪异的结果。  
glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色 
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右上顶点(底面) 
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左上顶点(底面) 
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面) 
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)  
接着画立方体的前面。保持Z坐标为一单位,前面正对着我们。  
glColor3f(1.0f,0.0f,0.0f); // 颜色改成红色 
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面) 
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面) 
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左下顶点(前面) 
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)  
立方体后面的绘制方法与前面类似。只是位于屏幕的里面。注意Z坐标现在保持 -1 不变。
  
glColor3f(1.0f,1.0f,0.0f); // 颜色改成黄色 
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右上顶点(后面) 
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面) 
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左下顶点(后面) 
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)  
还剩两个面就完成了。您会注意到总有一个坐标保持不变。这一次换成了X坐标。因为我们
在画左侧面。  
glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色 
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面) 
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(左面) 
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面) 
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)  
立方体的最后一个面了。X坐标保持为一单位。逆时针绘制。您愿意的话,留着这个面不画
也可以,这样就是一个盒子:) 

或者您要是有兴趣可以改变立方体所有顶点的色彩值,象金字塔那样混合颜色。您会看见
一个非常漂亮的彩色立方体,各种颜色在它的各个表面流淌。  
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色 
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(右面) 
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面) 
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的左下顶点(右面) 
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(右面) 
glEnd(); // 立方体绘制结束 

rtri+=0.2f; // 增加三角形的旋转变量(新增) 
rquad-=0.15f; // 减少四边形的旋转变量(新增) 
return TRUE; // 继续运行 
}  
这一课又结束了。到这里您应该已经较好的掌握了在3D空间创建对象的方法。必须将OpenG
L屏幕想象成一张很大的画纸,后面还带着许多透明的层。差不多就是个由大量的点组成的
立方体。这些点从左至右、从上至下、从前到后的布满了这个立方体。如果您能想象的出
在屏幕的深度方向,应该在设计新3D对象时没有任何问题。 

如果您对3D空间的理解很困难的话,千万不要灰心! 刚开始的时候,领会这些内容会很难
。象立方体这样的对象是您练习的好例子。继续努力吧!如果您有什么意见或建议请给我E
MAIL。如果您认为有什么不对或可以改进,请告诉我。我想做最好的OpenGL教程并对您的
反馈感兴趣。  

{译者:NeHe的文档似乎很简单,似乎很罗嗦。但仔细想来这样的高手您又见过几个?还是
那句话,我不是高手,希望您是,真诚的。} 
下面是源代码下载链接。祝您好运!  
* DOWNLOAD Visual C++ Code For This Lesson. 
* DOWNLOAD Visual Basic Code For This Lesson. ( Conversion by Ross Dawson ) 
* DOWNLOAD GLUT Code For This Lesson. ( Conversion by Andy Restad ) 
* DOWNLOAD Cygwin (FREE Language) Code For This Lesson. ( Conversion by 
Stephan Ferraro ) 
* DOWNLOAD Delphi Code For This Lesson. ( Conversion by Peter De Jaegher ) 
* DOWNLOAD MacOS X/GLUT Code For This Lesson. ( Conversion by Raal Goff ) 
* DOWNLOAD Linux/GLX Code For This Lesson. ( Conversion by Mihael Vrbanec ) 
* DOWNLOAD Code Warrior 5 Code For This Lesson. ( Conversion by Scott Lupton ) 
* DOWNLOAD MASM Code For This Lesson. ( Conversion by Nico (Scalp) ) 
* DOWNLOAD ASM Code For This Lesson. ( Conversion by Foolman ) 
* DOWNLOAD Visual Fortran Code For This Lesson. ( Conversion by Jean-Philippe 
Perois ) 
* DOWNLOAD Linux Code For This Lesson. ( Conversion by Richard Campbell ) 
* DOWNLOAD Irix Code For This Lesson. ( Conversion by Lakmal Gunasekara ) 
* DOWNLOAD Solaris Code For This Lesson. ( Conversion by Lakmal Gunasekara ) 
* DOWNLOAD Mac OS Code For This Lesson. ( Conversion by Anthony Parker ) 
* DOWNLOAD Power Basic Code For This Lesson. ( Conversion by Angus Law ) 
* DOWNLOAD BeOS Code For This Lesson. ( Conversion by Chris Herborth ) 
* DOWNLOAD Java Code For This Lesson. ( Conversion by Darren Hodges ) 
* DOWNLOAD MingW32 & Allegro Code For This Lesson. ( Conversion by Peter Puck 

* DOWNLOAD Borland C++ Builder 4.0 Code For This Lesson. ( Conversion by 
Patrick Salmons ) 
* DOWNLOAD Python Code For This Lesson. ( Conversion by Tony Colston )  
 
 
--

     人生,就是一团欲望:
     欲望没有满足的时候就是痛苦,
     欲望被满足的时候就是无聊;
     人生就是在痛苦与无聊之间徘徊。

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.229.69]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.570毫秒