转自【翻译】NeHe OpenGL 教程

前言

声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改。对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢。

NeHe OpenGL第十八课:二次几何体

二次几何体:

利用二次几何体,你可以很容易的创建球,圆盘,圆柱和圆锥。

 

二次曲面是一种画复合对象的方法,这种方法通常并不需要很多的三角形。我们将要使用第七课的代码。我们将要增加7个变量以及修改纹理以增加一些变化 : 

  

bool    sp;      // 空格键是否按下

int part1;      // 圆盘的起始角度

int part2;      // 圆盘的结束角度

int p1=0;      // 增量1

int p2=1;      // 增量1

GLUquadricObj *quadratic;     // 二次几何体

GLuint  object=0;      // 二次几何体标示符

好了我们现在开始搞InitGL()函数。我们打算增加3行代码用来初始化我们的二次曲面。这3行代码将在你使1号光源有效后增加,但是要在返回之前。第一行代码将初始化二次曲面并且创建一个指向改二次曲面的指针

,如果改二次曲面不能被创建的话,那么该指针就是NULL。第二行代码将在二次曲面的表面创建平滑的法向量,这样当灯光照上去的时候将会好看些。另外一些可能的取值是:GLU_NONE和GLU_FLAT。最后我们使在二

次曲面表面的纹理映射有效。

quadratic=gluNewQuadric();    // 创建二次几何体

 gluQuadricNormals(quadratic, GLU_SMOOTH);  // 使用平滑法线

 gluQuadricTexture(quadratic, GL_TRUE);  // 使用纹理

  

现在我决定在本课里保留立方体,这样你可以看到纹理是如何映射到二次曲面对象上的。而且我打算将绘制立方体的代码定义为一个单独的函数,这样我们在定义函数Draw()的时候它将会变的不那么凌乱。每个人都应

该记住这些代码:

GLvoid glDrawCube()     // 绘制立方体

{

  glBegin(GL_QUADS);   

  // 前面

  glNormal3f( 0.0f, 0.0f, 1.0f);  

  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); 

  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); 

  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); 

  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); 

  // 后面

  glNormal3f( 0.0f, 0.0f,-1.0f);  

  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 

  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); 

  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); 

  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 

  // 上面

  glNormal3f( 0.0f, 1.0f, 0.0f);  

  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); 

  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f); 

  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f); 

  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); 

  // 下面

  glNormal3f( 0.0f,-1.0f, 0.0f);  

  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 

  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 

  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); 

  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); 

  // 右面

  glNormal3f( 1.0f, 0.0f, 0.0f);  

  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 

  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); 

  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); 

  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); 

  // 左面

  glNormal3f(-1.0f, 0.0f, 0.0f);  

  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 

  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); 

  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); 

  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); 

 glEnd();     

}

接下来就是场景绘制函数了,在这里我只写一个简单的例子。并且当我绘制一个部分的盘子的时候,我将使用一个静态变量(一个局部的变量,该变量可以保留他的值不论你任何时候调用他)来表达一个非常酷的效果。

为了清晰起见我将要重写DrawGLScene函数。

   你们将会注意到当我讨论这些正在使用的参数时我忽略了当前函数的第一个参数(quadratic)。这个参数将被除立方体外的所有对象使用。所以当我讨论这些参数的时候我忽略了它。 

  

int DrawGLScene(GLvoid)      

{

  //...

// 这部分是新增加的

 switch(object)      // 绘制哪一种二次几何体

 {

 case 0:       // 绘制立方体

  glDrawCube();     

  break;

我们创建的第2个对象是一个圆柱体。参数1(1.0F)是圆柱体的底面半径,参数2(1.0F)是圆柱体的饿顶面半径,参数3(3.0F)是圆柱体的高度。参数4(32)是纬线(环绕Z轴有多少细分),参数5(32)是经线

(沿着Z轴有多少细分)。细分越多该对象就越细致。我们可以用增加细分的方法来增加对象的多边形数。因此你可以牺牲速度换回质量(以时间换质量),大多数的时候我们都可以很容易的找到一个合适的“度”。

case 1:       // 绘制圆柱体

  glTranslatef(0.0f,0.0f,-1.5f);   

  gluCylinder(quadratic,1.0f,1.0f,3.0f,32,32); 

  break;      

  

对象3将会创建一个CD样子的盘子。参数1(0.5F)是盘子的内圆半径,该参数可以为0,则表示在盘子中间没孔,内圆半径越大孔越大。参数2(1.5F)表示外圆半径,这个参数必须比内圆半径大。参数3(32)是组成

该盘子的切片的数量,这个数量可以想象成披萨饼中的切片的数量。切片越多,外圆边缘就越平滑。最后一个参数(32)是组成盘子的环的数量。环很像唱片上的轨迹,一环套一环。这些环从内圆半径细分到外圆半径。

再说一次,细分越多,速度越慢。

case 2:       // 绘制圆盘

  gluDisk(quadratic,0.5f,1.5f,32,32);  

  break;      

  

我们的第4个对象我知道你们为描述它耗尽精力。就是球。绘制球将会变的非常简单。参数1是球的半径。如果你无法理解半径/直径等等的话,可以理解成物体中心到物体外部的距离,在这里我们使用1.3F作为半径。接

下来两个参数就是细分了,和圆柱体一样,参数2是纬线,参数3是经线。细分越多球看起来就越平滑,通常球需要多一些的细分以使他们看起来平滑。

case 3:       // 绘制球

  gluSphere(quadratic,1.3f,32,32);  

  break;      

  

我们创建的第4个对象使用与我们曾经创建的圆柱体一样的命令来创建,如果你还记得的话,我们可以通过控制参数2和参数3来控制顶面半径和地面半径。因此我们可以使顶面半径为0来绘制一个圆锥体,顶面半径为0将

会在顶面上创建一个点。因此在下面的代码中,我们使顶面半径等于0,这将会创建一个点,同时也就创建了我们的圆锥。

case 4:       // 绘制圆锥

  glTranslatef(0.0f,0.0f,-1.5f);   

  gluCylinder(quadratic,1.0f,0.0f,3.0f,32,32); 

  break;      

  

我们的第6个对象将被gluPartialDisk函数创建。我们打算创建的这个对象使用了一些命令,这些命令在我们创建对象之前,你将会清楚的看到。但是命令gluPartialDisk拥有两个新的参数。第5个参数是我们想要

绘制的部分盘子的开始角度,参数6是旋转角,也就是转过的角度。我们将要增加旋转角,这将引起盘子沿顺时针方向缓慢的被绘制在屏幕上。一旦旋转角达到360度我们将开始增加开始角度,这样盘子看起来就想是被逐

渐的抹去一样。我们将重复这些过程。

case 5:       // 绘制部分圆盘

  part1+=p1;     

  part2+=p2;

if(part1>359)     

  {

   p1=0;     

   part1=0;    

   p2=1;     

   part2=0;    

  }

  if(part2>359)     

  {

   p1=1;     

   p2=0;     

  }

  gluPartialDisk(quadratic,0.5f,1.5f,32,32,part1,part2-part1); 

  break;      

 };

//...

}

In the KillGLWindow()
section of code, we need to delete the quadratic to free up system
resources. We do this with the command gluDeleteQuadratic.  

  

GLvoid KillGLWindow(GLvoid)     

{

 gluDeleteQuadric(quadratic);    // 删除二次几何体

在最后,我给出键盘输入代码。仅仅增加一些对剩余键的检查。

if (keys[' '] && !sp)  // 空格是否按下

    {

     sp=TRUE;   // 是,则绘制下一种二次几何体

     object++;  

     if(object>5)  

      object=0; 

    }

    if (!keys[' '])   // 空格是否释放

    {

     sp=FALSE;   // 记录这个状态

    }

原文及其个版本源代码下载:

http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=18

NeHe OpenGL教程 第十八课:二次几何体的更多相关文章

  1. NeHe OpenGL教程 第二十八课:贝塞尔曲面

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

  2. NeHe OpenGL教程 第二十六课:反射

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

  3. NeHe OpenGL教程 第十九课:粒子系统

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

  4. NeHe OpenGL教程 第十五课:纹理图形字

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

  5. NeHe OpenGL教程 第二十九课:Blt函数

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

  6. NeHe OpenGL教程 第二十五课:变形

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

  7. NeHe OpenGL教程 第二十四课:扩展

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

  8. NeHe OpenGL教程 第十六课:雾

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

  9. NeHe OpenGL教程 第十四课:图形字体

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

随机推荐

  1. EXT3_DX_ADD_ENTRY: DIRECTORY INDEX FULL!

    inode问题故障1例故障关键字:ext3_dx_add_entry: Directory index full! 线上业务的一台服务器无缘无故突然挂了让机房帮忙连接显示器后发现报错 http://i ...

  2. Clr core

    http://hllvm.group.iteye.com/group/topic/43559

  3. Oracle Enterprise Manager Cloud Control 12c的安装

    这里,我介绍的是Cloud Control 12c的安装.之前的版本叫Grid Control,这也是11g里面的叫法.在我写这篇博客时,Cloud Control 13c已经出来了,这个版本后续我再 ...

  4. C#Linq中的Union All/Union/Intersect和Top/Bottom和Paging和SqlMethods,skip,take,takewhile,skipwhile,编译查询等

    我们继续讲解LINQ to SQL语句,这篇我们来讨论Union All/Union/Intersect操作和Top/Bottom操作和Paging操作和SqlMethods操作 . Union Al ...

  5. 010. 使用.net框架提供的属性

    C#允许在类和类成员上声明特性(类), 可在运行时解释类和类的成员. 这个特性也称为属性, 使用Attribute.下面演示如何使用.net框架提供的属性. using System; using S ...

  6. rsync-3.0.6-64

    http://rsync.samba.org/ 用的是rsync-3.0.6-12.el6.x86_64 Rsync version 3.1.1 released June 22nd, 2014 Rs ...

  7. (委托事件处理)关于多线程执行显示进度条的实例(转)&&线程间操作无效: 从不是创建控件“rtxtEntryNO”的线程访问它。

    关于多线程执行显示进度条的实例! 之前回答了一篇关于怎么在线程中操作进度条的帖子,估计有人看的不是很明白今天没事,写了一个小小的实例,很简单,就2个文件权当抛砖引玉,希望有更好解决方案的人发表一下意见 ...

  8. 重新加载maven项目的依赖项

    最近在调试reportNG,测试允许完以后,报告总是使用的testNG的格式,并且只有index和overview两个文件. 找了好多帖子,大家都是那么设置的都没有问题,难道是哥人品不好?错! 大家基 ...

  9. Kindle 实用技巧

    1.Kindle Mate:可以连接kindle导出生词本,笔记,注释,超级棒. 2.把PDF发送到Kindle的时候,邮件主题写convert,这样系统会自动把PDF转换成适合Kindle阅读的格式 ...

  10. Oracle内存参数配置及版本问题

    Oracle的内存配置与Oracle性能息息相关.从总体上讲,可以分为两大块:共享部分(主要是SGA)和进程独享部分(主要是PGA).在 32 位操作系统下 的Oracle版本,不时有项目反馈关于内存 ...