NeHe的opengl教程delphi版(5)----3D

原创 2003年08月04日 09:52:00

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

我们混合金字塔上的颜色,创建一个平滑着色的对象。给立方体的每一面则来个不同的颜色。

Procedure glDraw();
Begin
   glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
   glLoadIdentity();                    // 重置当前的模型观察矩阵

   glTranslatef(-1.5, 0.0, -6.0);       // 左移 1.5 单位,并移入屏幕 6.0

   glRotatef(rtri, 0.0, 1.0, 0.0);      // 绕Y轴旋转三角形


   //下面的代码没有变化。在屏幕的左面画了一个彩色渐变三角形,并绕着Y轴从左向右旋转
   glBegin(GL_TRIANGLES);               // 绘制三角

{

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

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

我们开始画金字塔的前侧面。因为所有的面都共享上顶点,我们将这点在所有的三角形中都设置为红色。底边上的两个顶点的颜色则是互斥的。前侧面的左下顶点是绿色的,右下顶点是蓝色的。这样相邻右侧面的左下顶点是蓝色的,右下顶点是绿色的。这样四边形的底面上的点的颜色都是间隔排列的。

}

   glColor3f(1.0, 0.0, 0.0);            // 红色
   glVertex3f(0.0, 1.0, 0.0);           // 三角形的上顶点 (前侧面)
   glColor3f(0.0, 1.0, 0.0);            // 绿色
   glVertex3f(-1.0, -1.0, 1.0);         // 三角形的左下顶点 (前侧面)
   glColor3f(0.0, 0.0, 1.0);            // 蓝色
   glVertex3f(1.0, -1.0, 1.0);          // 三角形的右下顶点 (前侧面)

{

现在绘制右侧面。注意其底边上的两个顶点的X坐标位于中心右侧的一个单位处。顶点则位于Y轴上的一单位处,且Z坐标正好处于底边的两顶点的Z坐标中心。右侧面从上顶点开始向外侧倾斜至底边上。
这次的左下顶点用蓝色绘制,以保持与前侧面的右下顶点的一致。蓝色将从这个角向金字塔的前侧面和右侧面扩展并与其他颜色混合。
还应注意到后面的三个侧面和前侧面处于同一个glBegin(GL_TRIANGLES) 和 glEnd()语句中间。因为我们是通过三角形来构造这个金字塔的。OpenGL知道每三个点构成一个三角形。当它画完一个三角形之后,如果还有余下的点出现,它就以为新的三角形要开始绘制了。OpenGL在这里并不会将四点画成一个四边形,而是假定新的三角形开始了。所以千万不要无意中增加任何多余的点。

}

   glColor3f(1.0, 0.0, 0.0);            // 红色
   glVertex3f(0.0, 1.0, 0.0);           // 三角形的上顶点 (右侧面)
   glColor3f(0.0, 0.0, 1.0);            // 蓝色
   glVertex3f(1.0, -1.0, 1.0);          // 三角形的左下顶点 (右侧面)
   glColor3f(0.0, 1.0, 0.0);            // 绿色
   glVertex3f(1.0, -1.0, -1.0);         // 三角形的右下顶点 (右侧面)

{现在是后侧面。再次切换颜色。左下顶点又回到绿色,因为后侧面与右侧面共享这个角。}  

 glColor3f(1.0, 0.0, 0.0);            // 红色
   glVertex3f(0.0, 1.0, 0.0);           // 三角形的上顶点 (后侧面)
   glColor3f(0.0, 1.0, 0.0);            // 绿色
   glVertex3f(1.0, -1.0, -1.0);         // 三角形的左下顶点 (后侧面)
   glColor3f(0.0, 0.0, 1.0);            // 蓝色
   glVertex3f(-1.0, -1.0, -1.0);        // 三角形的右下顶点 (后侧面)

{最后画左侧面。又要切换颜色。左下顶点是蓝色,与后侧面的右下顶点相同。右下顶点是蓝色,与前侧面的左下顶点相同。
到这里金字塔就画完了}

   glColor3f(1.0, 0.0, 0.0);            // 红色
   glVertex3f(0.0, 1.0, 0.0);           // 三角形的上顶点 (左侧面)
   glColor3f(0.0, 0.0, 1.0);            // 蓝色
   glVertex3f(-1.0, -1.0, -1.0);        // 三角形的左下顶点 (左侧面)
   glColor3f(0.0, 1.0, 0.0);            // 绿色
   glVertex3f(-1.0, -1.0, 1.0);         // 三角形的右下顶点 (左侧面)
   glEnd();                             //金字塔绘制结束

{因为金字塔只绕着Y轴旋转,我们永远都看不见底面,因而没有必要添加底面。您觉得有经验了,尝试增加底面(正方形),并将金字塔绕X轴旋转来看看您是否作对了。确保底面四个顶点的颜色与侧面的颜色相匹配。}

{译者:这是我自己加的底面} 

  glBegin(GL_QUADS);                   // 绘制底面
   glColor3f(0.6, 0.2, 2.0);            //设置当前色为紫色
   glColor3f(0.0, 1.0, 0.0);            // 绿色
   glVertex3f(-1.0, -1.0, 1.0);         // 左上
   glColor3f(0.0, 0.0, 1.0);            // 蓝色
   glVertex3f(1.0, -1.0, 1.0);          // 右上
   glColor3f(0.0, 1.0, 0.0);            // 绿色
   glVertex3f(1.0, -1.0, -1.0);         // 左下
   glColor3f(0.0, 0.0, 1.0);            // 蓝色
   glVertex3f(-1.0, -1.0, -1.0);        // 右下
   glEnd();                             // 正方形绘制结束

   glLoadIdentity();                    // 重置模型观察矩阵
   glTranslatef(1.5, 0.0, -6.0);        // 右移1.5单位,并移入屏幕 6.0
   glRotatef(rquad, 1.0, 1.0, 1.0);     // 绕X轴旋转四边形 ( 新增 )

{

接下来开始画立方体。他由六个四边形组成。所有的四边形都以逆时针次序绘制。就是说先画右上角,然后左上角、左下角、最后右下角。您也许认为画立方体的背面的时候这个次序看起来好像顺时针,但别忘了我们从立方体的背后看背面的时候,与您现在所想的正好相反。(译者注:您是从立方体的外面来观察立方体的)。
注意到这次我们将立方体移地更远离屏幕了。因为立方体的大小要比金字塔大,同样移入6个单位时,立方体看起来要大的多。这是透视的缘故。越远的对象看起来越小 :)

}

   glBegin(GL_QUADS);                   // 绘制正方形

{

先画立方体的顶面。从中心上移一单位,注意Y坐标始终为一单位,表示这个四边形与Z轴平行。先画右上顶点,向右一单位,再屏幕向里一单位。然后左上顶点,向左一单位,再屏幕向里一单位。然后是靠近观察者的左下和右下顶点。就是屏幕往外一单位。

}
   glColor3f(0.0, 1.0, 0.0);            // 颜色改为蓝色
   glVertex3f(1.0, 1.0, -1.0);          // 四边形的右上顶点 (顶面)
   glVertex3f(-1.0, 1.0, -1.0);         // 四边形的左上顶点 (顶面)
   glVertex3f(-1.0, 1.0, 1.0);          // 四边形的左下顶点 (顶面)
   glVertex3f(1.0, 1.0, 1.0);           // 四边形的右下顶点 (顶面)

{

底面的画法和顶面十分类似。只是Y坐标变成了-1。如果我们从立方体的下面来看立方体的话,您会注意到右上角离观察者最近,因此我们先画离观察者最近的顶点。然后是左上顶点最后才是屏幕里面的左下和右下顶点。

如果您真的不在乎绘制多边形的次序(顺时针或者逆时针)的话,您可以直接拷贝顶面的代码,将Y坐标从1改成 -1,也能够工作。但一旦您进入象纹理映射这样的领域时,忽略绘制次序会导致十分怪异的结果。

}

   glColor3f(1.0, 0.5, 0.0);            // 颜色改成橙色
   glVertex3f(1.0, -1.0, 1.0);          // 四边形的右上顶点(底面)
   glVertex3f(-1.0, -1.0, 1.0);         // 四边形的左上顶点(底面)
   glVertex3f(-1.0, -1.0, -1.0);        // 四边形的左下顶点(底面)
   glVertex3f(1.0, -1.0, -1.0);         // 四边形的右下顶点(底面)

{

接着画立方体的前面。保持Z坐标为一单位,前面正对着我们。

   glColor3f(1.0, 0.0, 0.0);            // 颜色改成红色
   glVertex3f(1.0, 1.0, 1.0);           // 四边形的右上顶点(前面)
   glVertex3f(-1.0, 1.0, 1.0);          // 四边形的左上顶点(前面)
   glVertex3f(-1.0, -1.0, 1.0);         // 四边形的左下顶点(前面)
   glVertex3f(1.0, -1.0, 1.0);          // 四边形的右下顶点(前面)

{

立方体后面的绘制方法与前面类似。只是位于屏幕的里面。注意Z坐标现在保持 -1 不变。

}

   glColor3f(1.0, 1.0, 0.0);            // 颜色改成黄色
   glVertex3f(1.0, -1.0, -1.0);         // 四边形的右上顶点(后面)
   glVertex3f(-1.0, -1.0, -1.0);        // 四边形的左上顶点(后面)
   glVertex3f(-1.0, 1.0, -1.0);         // 四边形的左下顶点(后面)
   glVertex3f(1.0, 1.0, -1.0);          // 四边形的右下顶点(后面)

{

还剩两个面就完成了。您会注意到总有一个坐标保持不变。这一次换成了X坐标。因为我们在画左侧面。

}

   glColor3f(0.0, 0.0, 1.0);            // 颜色改成蓝色
   glVertex3f(-1.0, 1.0, 1.0);          // 四边形的右上顶点(左面)
   glVertex3f(-1.0, 1.0, -1.0);         // 四边形的左上顶点(左面)
   glVertex3f(-1.0, -1.0, -1.0);        // 四边形的左下顶点(左面)
   glVertex3f(-1.0, -1.0, 1.0);         // 四边形的右下顶点(左面)

{

立方体的最后一个面了。X坐标保持为一单位。逆时针绘制。您愿意的话,留着这个面不画也可以,这样就是一个盒子:)

或者您要是有兴趣可以改变立方体所有顶点的色彩值,象金字塔那样混合颜色。您会看见一个非常漂亮的彩色立方体,各种颜色在它的各个表面流淌。

}

   glColor3f(1.0, 0.0, 1.0);            // 颜色改成紫罗兰色
   glVertex3f(1.0, 1.0, -1.0);          // 四边形的右上顶点(右面)
   glVertex3f(1.0, 1.0, 1.0);           // 四边形的左上顶点(右面)
   glVertex3f(1.0, -1.0, 1.0);          // 四边形的左下顶点(右面)
   glVertex3f(1.0, -1.0, -1.0);         // 四边形的右下顶点(右面)

   glEnd();                             // 正方形绘制结束

   rtri := rtri + 0.2;                  // 增加三角形的旋转变量
   rquad := rquad - 0.15;               // 减少四边形的旋转变量

End;

 

运行一下看看效果

NeHe OpenGL系列教程(中英文版附带VC++源码)中英文系列

NeHe OpenGL教程(中英文版附带VC++源码)中英文系列 Lesson 01-lesson 02 创建一个OpenGL窗口: 如何创建三角形和四边形 http://ieee...
  • jmppok
  • jmppok
  • 2013年12月16日 10:25
  • 1791

opengl学习笔记1:vs2013 nehe教程第一课 创建窗口

近来需要想学习一下opengl,但是小白没有任何基础,也非计算机专业出身,只能一步一步学习nehe的程序来学习了。这里实现了在WIN10 vs2013 opengl2.0 环境下跑通nehe教程第一课...
  • caimagic
  • caimagic
  • 2016年01月29日 15:11
  • 936

【OpenGL】nehe教程第一课学习笔记

nehe教程的第一课主要讲了OpenGL程序的创建。 它引用了最基本的gl.h、glu.h、glaux.h三个头文件。 包含了五个函数,分别是InitGL、ResizeGLScene、DrawGLSc...
  • lzh1590
  • lzh1590
  • 2017年03月22日 16:22
  • 211

对OpenGL的初步认识及多版本框架介绍(基于NeHe的OpenGL教程)

由于以后接触的技术和图形有关,所以最近也是来学学习一下opengl的相关知识点。当然有看到《opengl编程指南》这本红宝书,但是对于初学者来言,这本书需要花很多精力,所以我找到了《NeHe的open...
  • aptx704610875
  • aptx704610875
  • 2014年06月30日 01:25
  • 1411

Nehe OpenGL教程第一课-创建一个OpenGL窗口(Win32)

原文地址为:Creating an OpenGL Window (Win32),翻译的chm格式文档下载地址为:OpenGL教程电子书(chm格式)中文版,源代码在官网上也可以下载到,更完整的源代码可...
  • ccf19881030
  • ccf19881030
  • 2014年01月10日 13:41
  • 3503

Qt下使用OpenGL(23)-根据NeHe的教程改写的

第二十三课:球面映射 nehewidget.h
  • H349117102
  • H349117102
  • 2014年04月14日 16:25
  • 1149

Opengl 入门教程的翻译

非常感谢此博客博主的分享,看了之后受益匪浅!(原文http://blog.csdn.net/s_xing/article/details/30244247) Opengl 入门教程的翻译 今天...
  • hbw1992322
  • hbw1992322
  • 2016年07月29日 20:52
  • 437

【OpenGL】(NeHe教程学习)纹理映射及代码实现

本文将要实现的功能是绘制一个立方体,并且在六个面贴上不同的纹理(由外部导入图片)。按下x、y、z按键可以分别围绕x、y、z轴旋转。 在这里我使用的是GLUT库。 【1】读入bmp图片的信息...
  • vampirem
  • vampirem
  • 2013年10月16日 13:18
  • 839

OpenSceneGraph实现的NeHe OpenGL教程 - 第三十五课_附录1

简介 在OSG中支持动态纹理,因此不需要我们对视频文件进行大量的解析工作,这些内容都已经在osgPlugins中完成了,在OSG中通过纹理osg::Image的派生类支持这一特性 ...
  • ALLENJIAO
  • ALLENJIAO
  • 2016年08月17日 14:16
  • 223

OpenGL: 显示列表绘制六面体

#include #include #include #pragma comment(lib,"glut32.lib") const double TWO_PI = 6.2831853; //...
  • Augusdi
  • Augusdi
  • 2014年03月04日 16:10
  • 2125
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:NeHe的opengl教程delphi版(5)----3D
举报原因:
原因补充:

(最多只允许输入30个字)