书签 分享 收藏 举报 版权申诉 / 81
上传文档赚钱

类型计算机图形学试验汇总课件.ppt

  • 上传人(卖家):晟晟文业
  • 文档编号:2711735
  • 上传时间:2022-05-20
  • 格式:PPT
  • 页数:81
  • 大小:1.05MB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《计算机图形学试验汇总课件.ppt》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    计算机 图形学 试验 汇总 课件
    资源描述:

    1、计算机图形学试验刘赏OpenGL的基本语法相关库2vOpenGL核心库:glvOpenGL实用程序库: gluvOpenGL编程辅助库:auxvOpenGL实用程序工具包(OpenGL utility toolkit,GLUT):glutvWindows专用库:wglOpenGL的基本语法命名规则3vOpenGL函数都遵循一个命名约定,即采用以下格式:例如函数glColor3f(),gl表示这个函数来自库gl.h,color表示该函数用于颜色设定,3f表示这个函数采用了三个浮点数参数。OpenGL的基本语法数据类型4OpenGL数据类型内部表示法定义为C类型C字面值后缀GLbyte8位整数si

    2、gned charBGLshort16位整数shortSGLint,GLsizei32位整数longLGLfloat,GLclampf32位浮点数floatFGLdouble,GLclampd64位浮点数doubleDGLubyte,GLboolean8位无符号整数 unsigned charUbGLshort16位无符号整数unsigned shortUsGLuint,GLenum,GLbitfield32位无符号整数unsigned longUi表表2.1 OpenGL的数据结构的数据结构OpenGL程序实例头文件包含5v利用OpenGL实现图形绘制,首先要引入OpenGL核心库以及其他需

    3、要使用的库的头文件。vGLUT保证了gl.h和glu.h被正确包含。 #include #include OpenGL程序实例窗口管理6v初始化( glutInit )v创建窗口( glutCreateWindow)v设定窗口的显示模式( glutInitDisplayMode)v指定窗口的位置和大小( glutInitWindowPosition和glutInitWindowSize )v指定窗口的显示内容函数( glutDisplayFunc)v运行框架( glutMainLoop)OpenGL程序实例绘制图形7v指定窗口背景色( glClearColor)v颜色管理,使用RGB颜色模型。

    4、一种颜色用红、绿、蓝三种颜色成分混合而成,每种颜色成分使用0.0到1.0之间的任意有效浮点数来表示颜色值。OpenGL程序实例绘制图形8混合色红色成分(R)绿色成分(G)蓝色成分(B)黑0.00.00.0红1.00.00.0绿0.01.00.0黄1.01.00.0蓝0.00.01.0紫1.00.01.0青0.01.01.0深灰0.250.250.25浅灰0.750.750.75棕0.600.400.12南瓜橙0.980.6250.12粉红0.980.040.70紫红0.600.400.70白1.01.01.0表表2.2 OpenGL的一些常用混合色的一些常用混合色OpenGL程序实例绘制图形9

    5、v刷新窗口的缓冲区( glClear)v设定投影参数 glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,200.0,0.0,150.0);v绘制图形 glRectf(50.0f, 100.0f, 150.0f, 50.0f);试验1:创建一个OpenGL窗口 v打开VC然后创建一个新工程 ,创建一个新的Win32程序(不是console控制台程序) v链接OpenGL库文件 ,Project- Settings,(工程设置)然后单击LINK标签:增加 OpenGL32.lib GLu32.lib 和 GLaux.lib 后单击OK按钮。 v代码的前3行包括

    6、了我们使用的每个库文件的头文件。如下所示:#include / Windows的头文件 #include / 包含最新的gl.h,glu.h库 #include / 包含OpenGL实用库 v完成程序的开发。如下图所示v参考程序试验2:绘制简单图形vglLoadIdentity() ,重置当前的模型观察矩阵 ,将当前点移到了屏幕中心,X坐标轴从左至右Y坐标轴从下至上,Z坐标轴从里至外。OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点。vglTranslatef(x, y, z)沿着 X, Y 和 Z 轴移动。 glTranslatef(-1.5f,0.0f,-6.0f); / 左移 1.5

    7、 单位,并移入屏幕 6.0 glBegin(GL_TRIANGLES); / 绘制三角形 glVertex3f( 0.0f, 1.0f, 0.0f); / 上顶点 glVertex3f(-1.0f,-1.0f, 0.0f); / 左下顶点 glVertex3f( 1.0f,-1.0f, 0.0f); / 右下顶点 glEnd(); / 三角形绘制结束 0.0f, 1.0f,0.0f0.0f, 1.0f,0.0f-1.0f, -1.0f,0.0f-1.0f, -1.0f,0.0f1.0f, -1.0f,0.0f1.0f, -1.0f,0.0fglBegin(GL_QUADS); / 绘制正方形

    8、glVertex3f(-1.0f, 1.0f, 0.0f); / 左上 glVertex3f( 1.0f, 1.0f, 0.0f); / 右上 glVertex3f( 1.0f,-1.0f, 0.0f); / 左下 glVertex3f(-1.0f,-1.0f, 0.0f); / 右下 glEnd(); / 正方形绘制结束 -1.0f, 1.0f, 0.0f1.0f, 1.0f, 0.0f1.0f, -1.0f, 0.0f-1.0f, -1.0f, 0.0fv在在第一实验的基础上,在完成程序的 DrawGLScene()过程中增加代码: glClear(GL_COLOR_BUFFER_BIT

    9、| GL_DEPTH_BUFFER_BIT); / 清除屏幕及深度缓存 glLoadIdentity(); / 重置当前的模型观察矩阵 glTranslatef(-1.5f,0.0f,-6.0f); / 左移 1.5 单位,并移入屏幕 6.0 glBegin(GL_TRIANGLES); / 绘制三角形 glVertex3f( 0.0f, 1.0f, 0.0f); / 上顶点上顶点 glVertex3f(-1.0f,-1.0f, 0.0f); / 左下左下 glVertex3f( 1.0f,-1.0f, 0.0f); / 右下右下 glEnd(); glTranslatef(3.0f,0.0f

    10、,0.0f); / 右移3单位 glBegin(GL_QUADS); / 绘制正方形 glVertex3f(-1.0f, 1.0f, 0.0f); / 左上 glVertex3f( 1.0f, 1.0f, 0.0f); / 右上 glVertex3f( 1.0f,-1.0f, 0.0f); / 左下 glVertex3f(-1.0f,-1.0f, 0.0f); / 右下 glEnd(); / 正方形绘制结束画完三角形后,我们要移到右半部分来画正方形。否则两个图形会相互重叠v完成程序的开发。如下图所示v参考程序试验3 着色vglColor3f(r,g,b)。括号中的三个参数依次是红、绿、蓝三色分

    11、量。参数取值范围从0,0f到1.0f。glColor3f(1.0f,0.0f,0.0f)红色红色glColor3f(0.0f,1.0f,0.0f)绿色绿色glColor3f(0.0f,0.0f,1.0f)蓝色蓝色v修改实验2中,画三角形的代码为:glBegin(GL_TRIANGLES); / 绘制三角形 glColor3f(1.0f,0.0f,0.0f); / 设置当前色为红色设置当前色为红色 glVertex3f( 0.0f, 1.0f, 0.0f); / 上顶点上顶点 glColor3f(0.0f,1.0f,0.0f); / 设置当前色为绿色设置当前色为绿色 glVertex3f(-1.

    12、0f,-1.0f, 0.0f); / 左下左下 glColor3f(0.0f,0.0f,1.0f); / 设置当前色为蓝色设置当前色为蓝色 glVertex3f( 1.0f,-1.0f, 0.0f); / 右下右下 glEnd();v修改实验2中,画正方形的代码为:glColor3f(0.5f,0.5f,1.0f); / 一次性将当前色设置为蓝色 glBegin(GL_QUADS); / 绘制正方形 glVertex3f(-1.0f, 1.0f, 0.0f); / 左上 glVertex3f( 1.0f, 1.0f, 0.0f); / 右上 glVertex3f( 1.0f,-1.0f, 0.

    13、0f); / 左下 glVertex3f(-1.0f,-1.0f, 0.0f); / 右下 glEnd(); / 正方形绘制结束 v完成程序的开发。如下图所示v参考程序试验4 旋转vglRotatef(Angle,Xvector,Yvector,Zvector)负责让对象绕某个轴旋转。 Xvector , Yvector 和 Zvector 三个参数则共同决定旋转轴的方向。比如(1,0,0)所描述的矢量经过X坐标轴的1个单位处并且方向向右。(-1,0,0)所描述的矢量经过X坐标轴的1个单位处,但方向向左。X轴您正在使用一台台锯。锯片中心的轴从左至右摆放(就像OpenGL中的X轴)。尖利的锯齿绕

    14、着X轴狂转,看起来要么向上转,要么向下转。取决于锯片开始转时的方向。这与我们在OpenGL中绕着X轴旋转什么的情形是一样的。Y轴假设您正处于一个巨大的龙卷风中心,龙卷风的中心从地面指向天空(就像OpenGL中的Y轴)。垃圾和碎片围着Y轴从左向右或是从右向左狂转不止。这与我们在OpenGL中绕着Y轴旋转什么的情形是一样的。Z轴您从正前方看着一台风扇。风扇的中心正好朝着您(就像OpenGL中的Z轴)。风扇的叶片绕着Z轴顺时针或逆时针狂转。这与我们在OpenGL中绕着Z轴旋转什么的情形是一样的。v在实验3中画三角形的语句前添加 glRotatef(rtri,0.0f,1.0f,0.0f); / 绕Y

    15、轴旋转三角形 在屏幕的左面画了一个彩色渐变三角形,并绕着Y轴从左向右旋转。v在实验3中画正方形的前面加上语句:glRotatef(rquad,1.0f,0.0f,0.0f); / 绕X轴旋转四边形 v完成程序,后效果如下:v参考程序试验5 三维图形v给三角形增加一个左侧面,一个右侧面,一个后侧面来生成一个金字塔(四棱锥)。 计算好坐标,绘制其它侧面三角形的方法相同。注意所有的面三角形都是逆时针次序绘制的注意所有的面三角形都是逆时针次序绘制的 v给正方形增加左、右、上、下及背面生成一个立方体。 计算好坐标,绘制其它侧面正方形的方法相同。所有的四边形都以逆时针次序绘制。 v在3D空间创建对象的方法

    16、。必须将OpenGL屏幕想象成一张很大的画纸,后面还带着许多透明的层。差不多就是个由大量的点组成的立方体。这些点从左至右、从上至下、从前到后的布满了这个立方体。如果您能想象的出在屏幕的深度方向,应该在设计新3D对象时没有任何问题。 v程序完成的,效果如下:v参考程序v微分的思想:画圆是由很多个小的三角形组成glBegin(GL_TRIANGLE_FAN); glVertex3f(0,0,0.0f ); for( i=0;i=360;i+=30) float p=(float)(i*3.14/180); glVertex3f(float)sin(p),(float)cos(p),0.0f );

    17、glEnd();画圆柱试验6 纹理映射 v在第一实验代码开始处增加新代码: #include v在 ReSizeGLScene() 之前,增加了下面这一段代码。用来加载位图文件 AUX_RGBImageRec *LoadBMP(char *Filename) / 载入位图图象 FILE *File=NULL; / 文件句柄 if (!Filename) / 确保文件名已提供 return NULL; / 如果没提供,返回 NULL File=fopen(Filename,“r”); / 尝试打开文件 if (File) / 文件存在么? fclose(File); / 关闭句柄 return

    18、auxDIBImageLoad(Filename); / 载入位图并返回指针 return NULL; / 如果载入失败,返回 NULL 涉及到的函数vglGenTextures(1, &texture0) 告诉OpenGL想生成一个纹理名字(如果想载入多个纹理,加大数字)。 vglBindTexture(GL_TEXTURE_2D, texture0) 告诉OpenGL将纹理名字 texture0 绑定到纹理目标上。2D纹理只有高度(在 Y 轴上)和宽度(在 X 轴上)。主函数将纹理名字指派给纹理数据。 vglBindTexture(GL_TEXTURE_2D, texture 所使用纹理对

    19、应的数字 ) 选择要绑定的纹理。当您想改变纹理时,应该绑定新的纹理。有一点值得指出的是,您不能在 glBegin() 和 glEnd() 之间绑定纹理,必须在 glBegin() 之前或 glEnd() 之后绑定。vglTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage0-sizeX, TextureImage0-sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage0-data); 告诉OpenGL此纹理是一个2D纹理 ( GL_TEXTURE_2D )。参数“0”代表图像的详细程度,通常就由它为零去了。参数三是

    20、数据的成分数。因为图像是由红色数据,绿色数据,蓝色数据三种组分组成。 TextureImage0-sizeX 是纹理的宽度。如果您知道宽度,您可以在这里填入,但计算机可以很容易的为您指出此值。 TextureImage0-sizey 是纹理的高度。参数零是边框的值,一般就是“0”。 GL_RGB 告诉OpenGL图像数据由红、绿、蓝三色数据组成。GL_UNSIGNED_BYTE 意味着组成图像的数据是无符号字节类型的。最后. TextureImage0-data 告诉OpenGL纹理数据的来源。此例中指向存放在 TextureImage0 记录中的数据。 vglTexParameteri( )

    21、告诉OpenGL在显示图像时,当它比放大得原始的纹理大 ( GL_TEXTURE_MAG_FILTER )或缩小得比原始得纹理小( GL_TEXTURE_MIN_FILTER )时OpenGL采用的滤波方式。通常这两种情况下都采用 GL_LINEAR 。 v为了将纹理正确的映射到四边形上,您必须将纹理的右上角映射到四边形的右上角,纹理的左上角映射到四边形的左上角,纹理的右下角映射到四边形的右下角,纹理的左下角映射到四边形的左下角。如果映射错误的话,图像显示时可能上下颠倒,侧向一边或者什么都不是。 glTexCoord2f 的第一个参数是X坐标。 0.0f 是纹理的左侧。 0.5f 是纹理的中点

    22、, 1.0f 是纹理的右侧。 glTexCoord2f 的第二个参数是Y坐标。 0.0f 是纹理的底部。 0.5f 是纹理的中点, 1.0f 是纹理的顶部。v所以纹理的左上坐标是 X:0.0f,Y:1.0f ,四边形的左上顶点是 X: -1.0f,Y:1.0f 。其余三点依此类推。v测试glTexCoord2f 的X,Y坐标参数。把 1.0f 改为 0.5f 将只显示纹理的左半部分,把 0.0f 改为 0.5f 将只显示纹理的右半部分。 int LoadGLTextures() / 载入位图(调用上面的代码)并转换成纹理 int Status=FALSE; / 状态指示器 AUX_RGBIma

    23、geRec *TextureImage1; / 创建纹理的存储空间 memset(TextureImage,0,sizeof(void *)*1); / 将指针设为 NULL / 载入位图,检查有无错误,如果位图没找到则退出 if (TextureImage0=LoadBMP(Data/NeHe.bmp) Status=TRUE; / 将 Status 设为 TRUE glGenTextures(1, &texture0); / 创建纹理 / 使用来自位图数据生成 的典型纹理 glBindTexture(GL_TEXTURE_2D, texture0); / 生成纹理 glTexImage2D

    24、(GL_TEXTURE_2D, 0, 3, TextureImage0-sizeX, TextureImage0-sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage0-data); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); / 线形滤波 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); / 线形滤波 if (TextureImage0) / 纹理是否存在 if (TextureImage

    25、0-data) / 纹理图像是否存在 free(TextureImage0-data); / 释放纹理图像占用的内存 free(TextureImage0); / 释放图像结构 vInitGL(GLvoid) 改动为:int InitGL(GLvoid) / 此处开始对OpenGL进行所有设置 if (!LoadGLTextures() / 调用纹理载入子例程 return FALSE; / 如果未能载入,返回FALSE glEnable(GL_TEXTURE_2D); / 启用纹理映射 glShadeModel(GL_SMOOTH); / 启用阴影平滑 glClearColor(0.0f,

    26、0.0f, 0.0f, 0.5f); / 黑色背景 glClearDepth(1.0f); / 设置深度缓存 glEnable(GL_DEPTH_TEST); / 启用深度测试 glDepthFunc(GL_LEQUAL); / 所作深度测试的类型 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); / 真正精细的透视修正 return TRUE; / 初始化 OK vDrawGLScene ()改动为:()改动为:添加语句添加语句glBindTexture(GL_TEXTURE_2D, texture0); / 选择纹理选择纹理 在绘制正方形

    27、的在绘制正方形的 glBegin(GL_QUADS); 中粘帖纹理,中粘帖纹理,以前面以前面 为例为例/ 前面前面 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); / 纹理和四边形的右上纹理和四边形的右上 glTexC

    28、oord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); / 纹理和四边形的左上纹理和四边形的左上 v程序完成后效果v参考程序试验7 光照效果v使用两种不同的光。v第一种称为环境光。环境光来自于四面八方。所有场景中的对象都处于环境光的照射中。v第二种类型的光源叫做漫射光。漫射光由特定的光源产生,并在您的场景中的对象表面上产生反射。处于漫射光直接照射下的任何对象表面都变得很亮,而几乎未被照射到的区域就显得要暗一些。这样在所创建的木板箱的棱边上就会产生的很不错的阴影效果。 v创建光源的过程和颜色的创建完全一致。前三个参数分别是RGB三色分量,最后一个是a

    29、lpha通道参数。 vGLfloat LightAmbient= 0.5f, 0.5f, 0.5f, 1.0f ; / 环境光参数 ,得到的是半亮(0.5f)的白色环境光。如果没有环境光,未被漫射光照到的地方会变得十分黑暗。 vGLfloat LightDiffuse= 1.0f, 1.0f, 1.0f, 1.0f ; / 漫射光参数生成最亮的漫射光。所有的参数值都取成最大值1.0f。它将照在木板箱的前面,看起来挺好。 v最后保存光源的位置。前三个参数和glTranslate中的一样。依次分别是XYZ轴上的位移。由于想要光线直接照射在木箱的正面,所以XY轴上的位移都是0.0f。第三个值是Z轴上

    30、的位移。为了保证光线总在木箱的前面,所以我们将光源的位置朝着观察者挪出屏幕。通常将屏幕也就是显示器的屏幕玻璃所处的位置称作Z轴的0.0f点。所以Z轴上的位移最后定为2.0f。假如您能够看见光源的话,它就浮在您显示器的前方。GLfloat LightPosition= 0.0f, 0.0f, 2.0f, 1.0f ; / 光源位置 v启用光源。没有启用GL_LIGHTING是看不见任何光线。记住:只对光源进行设置、定位、甚至启用,光源都不会工作。glEnable(GL_LIGHT1); / 启用一号光源 v程序完成效果v参考程序试验8 移动图像v把场景沿Y轴旋转。如果旋转90度的话,X轴不再是自

    31、左至右的了,他将由里向外穿出屏幕。假想您站在房子中间。再设想左侧的墙上写着-x,前面的墙上写着-z,右面墙上就是+x,身后的墙上则是+z。加入整个房子向右转90度,但您没有动,那么前面的墙上将是-x而不再是-z了。所有其他的墙也都跟着移动。-z出现在右侧,+z出现在左侧,+x出现在您背后。glRotatef(starloop.angle,0.0f,1.0f,0.0f); / 旋转至当前所画星星的角度 v沿x轴移动一个正值。通常x轴上的正值代表移向了屏幕的右侧,但这里由于绕y轴旋转了坐标系,x轴的正向可以是任意方向。如果我们转180度的话,屏幕的左右侧就镜像反向了。因此,当我们沿 x轴正向移动时

    32、,可能向左,向右,向前或向后。 glTranslatef(starloop.dist,0.0f,0.0f); / 沿X轴正向移动 v采用逆序来抵消旋转希望星星永远正面朝着我们,而不管屏幕如何旋转或倾斜。在绘制星星之前,采用逆序来抵消旋转。也就是以当前角度的负值来旋转星星。例如将星星旋转了10度的话,又将其旋转-10度来使星星在那个轴上重新面对屏幕。抵消了沿y轴的旋转。抵消掉沿x轴的屏幕倾斜。需要将屏幕再旋转-tilt倾角。glRotatef(-starloop.angle,0.0f,1.0f,0.0f); / 取消当前星星的角度 glRotatef(-tilt,1.0f,0.0f,0.0f);

    33、 / 取消屏幕倾斜 v程序运行效果v参考程序试验9 3D世界v每个3D世界基本上可以看作是sector(区段)的集合。一个sector(区段)可以是一个房间、一个立方体、或者任意一个闭合的区间。 typedef struct tagSECTOR / 创建Sector区段结构 int numtriangles; / Sector中的三角形个数 TRIANGLE* triangle; / 指向三角数组的指针 SECTOR; / 命名为SECTOR v一个sector(区段)包含了一系列的多边形,本实验采用三角形。 typedef struct tagTRIANGLE / 创建Triangle三角形

    34、结构 VERTEX vertex3; / VERTEX矢量数组,大小为3 TRIANGLE; / 命名为 TRIANGLE v三角形本质上是由一些(两个以上)顶点组成的多边形,顶点同时也是我们的最基本的分类单位。顶点包含了OpenGL真正感兴趣的数据。我们用3D空间中的坐标值(x,y,z)以及它们的纹理坐标(u,v)来定义三角形的每个顶点。 typedef struct tagVERTEX / 创建Vertex顶点结构 float x, y, z; / 3D 坐标 float u, v; / 纹理坐标 VERTEX; / 命名为VERTEX v允许用户在这个世界中游走和遍历 根据用户的指令旋转

    35、并变换镜头位置。围绕原点,以与镜头相反的旋转方向来旋转世界。(让人产生镜头旋转的错觉) 以与镜头平移方式相反的方式来平移世界(让人产生镜头移动的错觉)。 v程序实现效果v参考程序试验10 飘动的旗帜v#include / 引入数学函数库中的Sin v旗帜是由由44格44格的小方格子依次组成。使用points数组来存放网格各顶点独立的x,y,z坐标。 float points 45 45 3; / Points网格顶点数组 / 沿X平面循环 for(int x=0; x45; x+) / 沿Y平面循环 for(int y=0; y45; y+) / 向表面添加波浪效果 pointsxy0=flo

    36、at(x/5.0f)-4.5f); pointsxy1=float(y/5.0f)-4.5f);pointsxy2=float(sin(x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f); v绘制组成旗帜的4444个小网格,形成旗帜第一帧glBegin(GL_QUADS); / 四边形绘制开始四边形绘制开始 for( x = 0; x 44; x+ ) / 沿沿 X 平面平面 0-44 循环循环(45点点) for( y = 0; y 44; y+ ) / 沿沿 Y 平面平面 0-44 循环循环(45点点) float_x = float(x)/44.0f; /

    37、生成生成X浮点值浮点值 float_y = float(y)/44.0f; / 生成生成Y浮点值浮点值 float_xb = float(x+1)/44.0f; / X浮点值浮点值+0.0227f float_yb = float(y+1)/44.0f; / Y浮点值浮点值+0.0227fglTexCoord2f( float_x, float_y); / 第一个纹理坐标第一个纹理坐标 (左下角左下角) glVertex3f( pointsxy0, pointsxy1, pointsxy2 ); glTexCoord2f( float_x, float_yb ); / 第二个纹理坐标第二个纹理

    38、坐标 (左上角左上角) glVertex3f( pointsxy+10, pointsxy+11, pointsxy+12 ); glTexCoord2f( float_xb, float_yb ); / 第三个纹理坐标第三个纹理坐标 (右上角右上角) glVertex3f( pointsx+1y+10, pointsx+1y+11, pointsx+1y+12 ); glTexCoord2f( float_xb, float_y ); / 第四个纹理坐标第四个纹理坐标 (右下角右下角) glVertex3f( pointsx+1y0, pointsx+1y1, pointsx+1y2 );

    39、glEnd(); / 四边形绘制结束四边形绘制结束 v不断更新绘制小网格。形成旗帜飘动效果/ 用来降低波浪速度(每隔2帧一次)if( wiggle_count = 2 ) for( y = 0; y 45; y+ ) / 沿Y平面循环 hold=points0y2; / 存储当前左侧波浪值存储当前左侧波浪值 for( x = 0; x 44; x+) / 沿沿X平面循环平面循环 / 当前波浪值等于其右侧的波浪值当前波浪值等于其右侧的波浪值 pointsxy2 = pointsx+1y2; points44y2=hold; / 刚才的值成为最左侧的波浪值刚才的值成为最左侧的波浪值 wiggle_

    40、count = 0; / 计数器清零 wiggle_count+; / 计数器加一 v程序运行效果v参考程序试验11 二次几何体v/ 绘制圆柱体 glTranslatef(0.0f,0.0f,-1.5f); v/ 绘制圆锥 gluCylinder(quadratic,1.0f,0.0f,3.0f,32,32); (顶面半径为0 的特殊圆柱体)参数1(1.0F)是圆柱体的底面半径,参数2(1.0F)是圆柱体的饿顶面半径,参数3(3.0F)是圆柱体的高度。参数4(32)是纬线(环绕Z轴有多少细分),参数5(32)是经线(沿着Z轴有多少细分)。细分越多该对象就越细致。我们可以用增加细分的方法来增加对

    41、象的多边形数。 v/ 绘制圆盘gluDisk(quadratic,0.5f,1.5f,32,32); 参数1(0.5F)是盘子的内圆半径,该参数可以为0,则表示在盘子中间没孔,内圆半径越大孔越大。参数2(1.5F)表示外圆半径,这个参数必须比内圆半径大。参数3(32)是组成该盘子的切片的数量,这个数量可以想象成披萨饼中的切片的数量。切片越多,外圆边缘就越平滑。最后一个参数(32)是组成盘子的环的数量。环很像唱片上的轨迹,一环套一环。这些环从内圆半径细分到外圆半径。 v/ 绘制球 gluSphere(quadratic,1.3f,32,32); 参数1是球的半径。如果你无法理解半径/直径等等的话

    42、,可以理解成物体中心到物体外部的距离,在这里我们使用1.3F作为半径。接下来两个参数就是细分了,和圆柱体一样,参数2是纬线,参数3是经线。细分越多球看起来就越平滑 v参考程序试验12 贝塞尔曲面v为了做一个贝塞尔曲面,你需要16个控制点,(4*4),和2个变量t,v。你要做的是计算在分量v的沿4条平行曲线的点,再用这4个点计算在分量t的点。计算了足够的这些点,我们可以用三角带连接他们,画出贝塞尔曲面。typedef struct point_3d / 3D点的结构点的结构 double x, y, z; POINT_3D; typedef struct bpatch / 贝塞尔面片结构贝塞尔面

    43、片结构 POINT_3D anchors44; / 由由4x4网格组成网格组成 GLuint dlBPatch; / 绘制面片的显示列表名称绘制面片的显示列表名称 GLuint texture; / 面片的纹理面片的纹理 BEZIER_PATCH; / 计算贝塞尔方程的值 / 变量u的范围在0-1之间 POINT_3D Bernstein(float u, POINT_3D *p) POINT_3D a, b, c, d, r; a = pointTimes(pow(u,3), p0); b = pointTimes(3*pow(u,2)*(1-u), p1); c = pointTimes(

    44、3*u*pow(1-u),2), p2); d = pointTimes(pow(1-u),3), p3); r = pointAdd(pointAdd(a, b), pointAdd(c, d); return r; / 生成贝塞尔曲面的显示列表 GLuint genBezier(BEZIER_PATCH patch, int divs) int u = 0, v; float py, px, pyold; GLuint drawlist = glGenLists(1); / 创建显示列表创建显示列表 POINT_3D temp4; POINT_3D *last = (POINT_3D*)m

    45、alloc(sizeof(POINT_3D)*(divs+1); / 更具每一条曲更具每一条曲线的细分数,分配相应的内存线的细分数,分配相应的内存 if (patch.dlBPatch != NULL) / 如果显示列表存在则删除如果显示列表存在则删除 glDeleteLists(patch.dlBPatch, 1); temp0 = patch.anchors03; / 获得获得u方向的四个控制点方向的四个控制点 temp1 = patch.anchors13; temp2 = patch.anchors23; temp3 = patch.anchors33; for (v=0;v=divs

    46、;v+) / 根据细分数,创建各个分割点额参数根据细分数,创建各个分割点额参数 px = (float)v)/(float)divs); / 使用使用Bernstein函数求的分割点的坐标函数求的分割点的坐标 lastv = Bernstein(px, temp); glNewList(drawlist, GL_COMPILE); / 创建一个新的显示列表创建一个新的显示列表 glBindTexture(GL_TEXTURE_2D, patch.texture); / 邦定纹理邦定纹理 for (u=1;u=divs;u+) py = (float)u)/(float)divs); / 计算计

    47、算v方向上的细分点的参数方向上的细分点的参数 pyold = (float)u-1.0f)/(float)divs); / 上一个上一个v方向上的细分点的参数方向上的细分点的参数 temp0 = Bernstein(py, patch.anchors0); / 计算每个细分点计算每个细分点v方向上贝塞尔曲方向上贝塞尔曲面的控制点面的控制点 temp1 = Bernstein(py, patch.anchors1); temp2 = Bernstein(py, patch.anchors2); temp3 = Bernstein(py, patch.anchors3); glBegin(GL_T

    48、RIANGLE_STRIP); / 开始绘制三角形带开始绘制三角形带 for (v=0;v=divs;v+) px = (float)v)/(float)divs); / 沿着沿着u轴方向顺序绘制轴方向顺序绘制 glTexCoord2f(pyold, px); / 设置纹理坐标设置纹理坐标 glVertex3d(lastv.x, lastv.y, lastv.z); / 绘制一个顶绘制一个顶点点 lastv = Bernstein(px, temp); / 创建下一个顶点创建下一个顶点 glTexCoord2f(py, px); / 设置纹理设置纹理 glVertex3d(lastv.x, l

    49、astv.y, lastv.z); / 绘制新的绘制新的顶点顶点 glEnd(); / 结束三角形带的绘制结束三角形带的绘制 glEndList(); / 显示列表绘制结束显示列表绘制结束 free(last); / 释放分配的内存释放分配的内存 return drawlist; / 返回创建的显示列表返回创建的显示列表 / 设置贝塞尔曲面的控制点设置贝塞尔曲面的控制点 void initBezier(void) mybezier.anchors00 = makePoint(-0.75, -0.75, -0.50); / 设置贝塞尔曲面的控制点设置贝塞尔曲面的控制点 mybezier.anch

    50、ors01 = makePoint(-0.25, -0.75, 0.00); mybezier.anchors02 = makePoint( 0.25, -0.75, 0.00); mybezier.anchors03 = makePoint( 0.75, -0.75, -0.50); mybezier.anchors10 = makePoint(-0.75, -0.25, -0.75); mybezier.anchors11 = makePoint(-0.25, -0.25, 0.50); mybezier.anchors12 = makePoint( 0.25, -0.25, 0.50);

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:计算机图形学试验汇总课件.ppt
    链接地址:https://www.163wenku.com/p-2711735.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库