3D空间:

我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体。

在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D世界中的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();						// 金字塔绘制结束
接下来开始画立方体。他由六个四边形组成。所有的四边形都以逆时针次序绘制。就是说先画右上角,然后左上角、左下角、最后右下角。您也许认为画立方体的背面的时候这个次序看起来好像顺时针,但别忘了我们从立方体的背后看背面的时候,与您现在所想的正好相反。(译者注:您是从立方体的外面来观察立方体的)。
注意到这次我们将立方体移地更远离屏幕了。因为立方体的大小要比金字塔大,同样移入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空间创建对象的方法。必须将OpenGL屏幕想象成一张很大的画纸,后面还带着许多透明的层。差不多就是个由大量的点组成的立方体。这些点从左至右、从上至下、从前到后的布满了这个立方体。如果您能想象的出在屏幕的深度方向,应该在设计新3D对象时没有任何问题。

效果截图:

     

(11)nehe教程5---3D空间的更多相关文章

  1. NeHe OpenGL教程 第五课:3D空间

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  2. Direct3D 11 Tutorial 4: 3D Spaces_Direct3D 11 教程4:3D空间

    概述 在上一个教程中,我们在应用程序窗口的中心成功渲染了一个三角形. 我们没有太注意我们在顶点缓冲区中拾取的顶点位置. 在本教程中,我们将深入研究3D位置和转换的细节. 本教程的结果将是渲染到屏幕的3 ...

  3. iOS 11开发教程(五)iOS11模拟器介绍二

    iOS 11开发教程(五)iOS11模拟器介绍二 3.iOS11模拟器中设置语言 对于不同国家的人来说,使用到的语言是不一样的.一般情况下iOS11模拟器默认使用的English(英语).对于英文不好 ...

  4. 第05课 OpenGL 3D空间

    3D空间: 我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体. 在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D ...

  5. WordPress搬家教程:换空间与换域名

    WordPress搬家教程:换空间与换域名 由于本人博客空间8月份已到期,便新购一个虚拟主机想进行WordPress搬家,于是特意在网上查了些WordPress搬家教程,进行了综合总结,并结合这次实操 ...

  6. 《zw版·Halcon-delphi系列原创教程》 3d汽车模型自动区域分割

    <zw版·Halcon-delphi系列原创教程> 3d汽车模型自动区域分割 目前,图像分析,在3D设计,机器视觉方面拥有很广.这个Halcon脚本是3d汽车模型自动区域分割,很简单才20 ...

  7. iOS 11开发教程(二十二)iOS11应用视图实现按钮的响应(2)

    iOS 11开发教程(二十二)iOS11应用视图实现按钮的响应(2) 此时,当用户轻拍按钮后,一个叫tapButton()的方法就会被触发. 注意:以上这一种方式是动作声明和关联一起进行的,还有一种先 ...

  8. iOS 11开发教程(二十一)iOS11应用视图美化按钮之实现按钮的响应(1)

    iOS 11开发教程(二十一)iOS11应用视图美化按钮之实现按钮的响应(1) 按钮主要是实现用户交互的,即实现响应.按钮实现响应的方式可以根据添加按钮的不同分为两种:一种是编辑界面添加按钮实现的响应 ...

  9. iOS 11开发教程(二十)iOS11应用视图美化按钮之设置按钮的状态

    iOS 11开发教程(二十)iOS11应用视图美化按钮之设置按钮的状态 在示例2-2中,设置按钮的标题和颜色时,需要对按钮的状态进行设置,表示按钮在某一状态下的标题和标题颜色是什么样子.例如,UICo ...

随机推荐

  1. xUtils框架的介绍(一)

    微信账号申请终于通过了,这是我们第一次Android干货分享. 想来是第一次,要对得起“干货”二字. 今天我要为大家推荐的是一个Android基于快速开发的一个框架——xUtils, 它是在aFina ...

  2. html5 shiv

    使用html5标签吧!ie6.ie7.ie8不支持怎么办?它的原理是如此的简单:    1.document.createElement("ele");  // js虚拟创建一个元 ...

  3. Tutorial: Facebook analytics using Power BI Desktop

    In this tutorial you learn how to import and visualize data from Facebook. During the tutorial you'l ...

  4. P1951: [Sdoi2010]古代猪文

    呜啊啊啊啊,选错了题,原以为很简单的优化+剪枝就能过结果牵扯到了一堆数论知识.我的错,贴上我的代码(已经尽量优化了) ; var n,g,i,j,ans:longint; tem:int64; fun ...

  5. Windows python 安装 nNumpy、Scipy、matplotlib模块

    折腾了 很久,总结一些. 首先如果python 是64位,安装32位的numpy ,Scipy,或者matplotlib 模块. 会出现很多问题. 比如当你 在python 导入 Numpy 时,导入 ...

  6. Abstract Class与 Interface 的区别

    表格                                                                                               Abs ...

  7. 20145120 《Java程序设计》第7周学习总结

    20145120 <Java程序设计>第7周学习总结 教材学习内容总结 Lambda表达式 例:Comparator<String> byLength = (name1, na ...

  8. Netsharp快速入门(之14) 销售管理(报表A 热销滞销品统计)

    作者:秋时 杨昶   转载须说明出处 4.5     销售报表 4.5.1  热销滞销品统计 1.建立部件工作区,主部件选择报表.统计表,辅部件选择查询方案 2.设置报表模版.选择主部件,选择工具-报 ...

  9. adb 连接时 device offline

    继上一篇博文,会发现最后图片上 adb连接时候提示device offline 以下三种方法可以试一下~我是试到最后一种才成功 1.重启手机 2.adb kill-server    adb star ...

  10. 浅谈IT

    在没有学计算机应用技术之前我对IT的认知度几乎为零,曾经还天真的认为IT就是白领,只要做上IT行业,以后便可高枕无忧.后来阴差阳错学了这个专业.通过一年的学习,虽然学艺不精但多少对IT行业了解的一知半 ...