




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
计算机图形学试验第1页,共70页,2023年,2月20日,星期四试验1:创建一个OpenGL窗口
打开VC然后创建一个新工程,创建一个新的Win32程序(不是console控制台程序)第2页,共70页,2023年,2月20日,星期四链接OpenGL库文件,Project->Settings,(工程—>设置)然后单击LINK标签:增加OpenGL32.libGLu32.lib和GLaux.lib后单击OK按钮。
第3页,共70页,2023年,2月20日,星期四代码的前3行包括了我们使用的每个库文件的头文件。如下所示:
#include<windows.h>//Windows的头文件#include<glew.h>//包含最新的gl.h,glu.h库#include<glut.h>//包含OpenGL实用库第4页,共70页,2023年,2月20日,星期四完成程序的开发。如下图所示参考程序第5页,共70页,2023年,2月20日,星期四试验2:绘制简单图形glLoadIdentity(),重置当前的模型观察矩阵,将当前点移到了屏幕中心,X坐标轴从左至右Y坐标轴从下至上,Z坐标轴从里至外。OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点。第6页,共70页,2023年,2月20日,星期四glTranslatef(x,y,z)沿着X,Y和Z轴移动。
glTranslatef(-1.5f,0.0f,-6.0f);//左移1.5单位,并移入屏幕6.0第7页,共70页,2023年,2月20日,星期四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.0f-1.0f,-1.0f,0.0f1.0f,-1.0f,0.0f第8页,共70页,2023年,2月20日,星期四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();//正方形绘制结束-1.0f,1.0f,0.0f1.0f,1.0f,0.0f1.0f,-1.0f,0.0f-1.0f,-1.0f,0.0f第9页,共70页,2023年,2月20日,星期四在在第一实验的基础上,在完成程序的DrawGLScene()过程中增加代码:
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);//清除屏幕及深度缓存glLoadIdentity();//重置当前的模型观察矩阵
glTranslatef(-1.5f,0.0f,-6.0f);//左移1.5单位,并移入屏幕6.0glBegin(GL_TRIANGLES);//绘制三角形glVertex3f(0.0f,1.0f,0.0f);//上顶点glVertex3f(-1.0f,-1.0f,0.0f);//左下glVertex3f(1.0f,-1.0f,0.0f);//右下
glEnd();第10页,共70页,2023年,2月20日,星期四
glTranslatef(3.0f,0.0f,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();//正方形绘制结束画完三角形后,我们要移到右半部分来画正方形。否则两个图形会相互重叠第11页,共70页,2023年,2月20日,星期四完成程序的开发。如下图所示参考程序第12页,共70页,2023年,2月20日,星期四试验3着色glColor3f(r,g,b)。括号中的三个参数依次是红、绿、蓝三色分量。参数取值范围从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)蓝色第13页,共70页,2023年,2月20日,星期四修改实验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.0f,-1.0f,0.0f);//左下glColor3f(0.0f,0.0f,1.0f);//设置当前色为蓝色
glVertex3f(1.0f,-1.0f,0.0f);//右下
glEnd();第14页,共70页,2023年,2月20日,星期四修改实验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.0f);//左下
glVertex3f(-1.0f,-1.0f,0.0f);//右下
glEnd();//正方形绘制结束第15页,共70页,2023年,2月20日,星期四完成程序的开发。如下图所示参考程序第16页,共70页,2023年,2月20日,星期四试验4旋转glRotatef(Angle,Xvector,Yvector,Zvector)负责让对象绕某个轴旋转。Xvector,Yvector和Zvector三个参数则共同决定旋转轴的方向。比如(1,0,0)所描述的矢量经过X坐标轴的1个单位处并且方向向右。(-1,0,0)所描述的矢量经过X坐标轴的1个单位处,但方向向左。
第17页,共70页,2023年,2月20日,星期四X轴-您正在使用一台台锯。锯片中心的轴从左至右摆放(就像OpenGL中的X轴)。尖利的锯齿绕着X轴狂转,看起来要么向上转,要么向下转。取决于锯片开始转时的方向。这与我们在OpenGL中绕着X轴旋转什么的情形是一样的。Y轴-假设您正处于一个巨大的龙卷风中心,龙卷风的中心从地面指向天空(就像OpenGL中的Y轴)。垃圾和碎片围着Y轴从左向右或是从右向左狂转不止。这与我们在OpenGL中绕着Y轴旋转什么的情形是一样的。Z轴-您从正前方看着一台风扇。风扇的中心正好朝着您(就像OpenGL中的Z轴)。风扇的叶片绕着Z轴顺时针或逆时针狂转。这与我们在OpenGL中绕着Z轴旋转什么的情形是一样的。第18页,共70页,2023年,2月20日,星期四在实验3中画三角形的语句前添加
glRotatef(rtri,0.0f,1.0f,0.0f);//绕Y轴旋转三角形在屏幕的左面画了一个彩色渐变三角形,并绕着Y轴从左向右旋转。第19页,共70页,2023年,2月20日,星期四在实验3中画正方形的前面加上语句:glRotatef(rquad,1.0f,0.0f,0.0f);//绕X轴旋转四边形第20页,共70页,2023年,2月20日,星期四完成程序,后效果如下:参考程序第21页,共70页,2023年,2月20日,星期四试验5三维图形给三角形增加一个左侧面,一个右侧面,一个后侧面来生成一个金字塔(四棱锥)。计算好坐标,绘制其它侧面三角形的方法相同。注意所有的面-三角形都是逆时针次序绘制的第22页,共70页,2023年,2月20日,星期四给正方形增加左、右、上、下及背面生成一个立方体。计算好坐标,绘制其它侧面正方形的方法相同。所有的四边形都以逆时针次序绘制。第23页,共70页,2023年,2月20日,星期四在3D空间创建对象的方法。必须将OpenGL屏幕想象成一张很大的画纸,后面还带着许多透明的层。差不多就是个由大量的点组成的立方体。这些点从左至右、从上至下、从前到后的布满了这个立方体。如果您能想象的出在屏幕的深度方向,应该在设计新3D对象时没有任何问题。第24页,共70页,2023年,2月20日,星期四程序完成的,效果如下:参考程序第25页,共70页,2023年,2月20日,星期四试验6纹理映射在第一实验代码开始处增加新代码:#include<stdio.h>第26页,共70页,2023年,2月20日,星期四在ReSizeGLScene()之前,增加了下面这一段代码。用来加载位图文件AUX_RGBImageRec*LoadBMP(char*Filename)//载入位图图象{FILE*File=NULL;//文件句柄
if(!Filename)//确保文件名已提供{returnNULL;//如果没提供,返回NULL}File=fopen(Filename,“r”);//尝试打开文件
if(File)//文件存在么?{ fclose(File);//关闭句柄
returnauxDIBImageLoad(Filename);//载入位图并返回指针
}returnNULL;//如果载入失败,返回NULL第27页,共70页,2023年,2月20日,星期四涉及到的函数glGenTextures(1,&texture[0])告诉OpenGL想生成一个纹理名字(如果想载入多个纹理,加大数字)。第28页,共70页,2023年,2月20日,星期四glBindTexture(GL_TEXTURE_2D,texture[0])告诉OpenGL将纹理名字texture[0]绑定到纹理目标上。2D纹理只有高度(在Y轴上)和宽度(在X轴上)。主函数将纹理名字指派给纹理数据。第29页,共70页,2023年,2月20日,星期四glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);告诉OpenGL此纹理是一个2D纹理(GL_TEXTURE_2D)。参数“0”代表图像的详细程度,通常就由它为零去了。参数三是数据的成分数。因为图像是由红色数据,绿色数据,蓝色数据三种组分组成。TextureImage[0]->sizeX是纹理的宽度。如果您知道宽度,您可以在这里填入,但计算机可以很容易的为您指出此值。TextureImage[0]->sizey是纹理的高度。参数零是边框的值,一般就是“0”。
GL_RGB告诉OpenGL图像数据由红、绿、蓝三色数据组成。
GL_UNSIGNED_BYTE意味着组成图像的数据是无符号字节类型的。最后...TextureImage[0]->data告诉OpenGL纹理数据的来源。此例中指向存放在TextureImage[0]记录中的数据。第30页,共70页,2023年,2月20日,星期四glTexParameteri()告诉OpenGL在显示图像时,当它比放大得原始的纹理大(GL_TEXTURE_MAG_FILTER)或缩小得比原始得纹理小(GL_TEXTURE_MIN_FILTER)时OpenGL采用的滤波方式。通常这两种情况下都采用GL_LINEAR。
第31页,共70页,2023年,2月20日,星期四glBindTexture(GL_TEXTURE_2D,texture[所使用纹理对应的数字])选择要绑定的纹理。当您想改变纹理时,应该绑定新的纹理。有一点值得指出的是,您不能在glBegin()和glEnd()之间绑定纹理,必须在glBegin()之前或glEnd()之后绑定。
第32页,共70页,2023年,2月20日,星期四为了将纹理正确的映射到四边形上,您必须将纹理的右上角映射到四边形的右上角,纹理的左上角映射到四边形的左上角,纹理的右下角映射到四边形的右下角,纹理的左下角映射到四边形的左下角。如果映射错误的话,图像显示时可能上下颠倒,侧向一边或者什么都不是。glTexCoord2f的第一个参数是X坐标。0.0f是纹理的左侧。0.5f是纹理的中点,1.0f是纹理的右侧。glTexCoord2f的第二个参数是Y坐标。0.0f是纹理的底部。0.5f是纹理的中点,1.0f是纹理的顶部。所以纹理的左上坐标是X:0.0f,Y:1.0f,四边形的左上顶点是X:-1.0f,Y:1.0f。其余三点依此类推。试着玩玩glTexCoord2f的X,Y坐标参数。把1.0f改为0.5f将只显示纹理的左半部分,把0.0f改为0.5f将只显示纹理的右半部分。第33页,共70页,2023年,2月20日,星期四
intLoadGLTextures()//载入位图(调用上面的代码)并转换成纹理{ intStatus=FALSE;//状态指示器
AUX_RGBImageRec*TextureImage[1];//创建纹理的存储空间
memset(TextureImage,0,sizeof(void*)*1);//将指针设为NULL//载入位图,检查有无错误,如果位图没找到则退出if(TextureImage[0]=LoadBMP("Data/NeHe.bmp")){Status=TRUE;//将Status设为TRUE glGenTextures(1,&texture[0]);//创建纹理//使用来自位图数据生成的典型纹理
glBindTexture(GL_TEXTURE_2D,texture[0]);//生成纹理
glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//线形滤波glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//线形滤波
第34页,共70页,2023年,2月20日,星期四if(TextureImage[0])//纹理是否存在{ if(TextureImage[0]->data)//纹理图像是否存在{ free(TextureImage[0]->data);//释放纹理图像占用的内存
} free(TextureImage[0]);//释放图像结构
}第35页,共70页,2023年,2月20日,星期四InitGL(GLvoid)改动为:intInitGL(GLvoid)//此处开始对OpenGL进行所有设置{if(!LoadGLTextures())//调用纹理载入子例程{returnFALSE;//如果未能载入,返回FALSE}glEnable(GL_TEXTURE_2D);//启用纹理映射glShadeModel(GL_SMOOTH);//启用阴影平滑glClearColor(0.0f,0.0f,0.0f,0.5f);//黑色背景glClearDepth(1.0f);//设置深度缓存glEnable(GL_DEPTH_TEST);//启用深度测试glDepthFunc(GL_LEQUAL);//所作深度测试的类型glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);//真正精细的透视修正returnTRUE;//初始化OK}第36页,共70页,2023年,2月20日,星期四DrawGLScene()改动为:添加语句glBindTexture(GL_TEXTURE_2D,texture[0]);//选择纹理在绘制正方形的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);//纹理和四边形的右上glTexCoord2f(0.0f,1.0f);glVertex3f(-1.0f,1.0f,1.0f);//纹理和四边形的左上第37页,共70页,2023年,2月20日,星期四程序完成后效果参考程序第38页,共70页,2023年,2月20日,星期四试验7光照效果使用两种不同的光。第一种称为环境光。环境光来自于四面八方。所有场景中的对象都处于环境光的照射中。第二种类型的光源叫做漫射光。漫射光由特定的光源产生,并在您的场景中的对象表面上产生反射。处于漫射光直接照射下的任何对象表面都变得很亮,而几乎未被照射到的区域就显得要暗一些。这样在所创建的木板箱的棱边上就会产生的很不错的阴影效果。第39页,共70页,2023年,2月20日,星期四创建光源的过程和颜色的创建完全一致。前三个参数分别是RGB三色分量,最后一个是alpha通道参数。GLfloatLightAmbient[]={0.5f,0.5f,0.5f,1.0f};//环境光参数,得到的是半亮(0.5f)的白色环境光。如果没有环境光,未被漫射光照到的地方会变得十分黑暗。第40页,共70页,2023年,2月20日,星期四GLfloatLightDiffuse[]={1.0f,1.0f,1.0f,1.0f};//漫射光参数生成最亮的漫射光。所有的参数值都取成最大值1.0f。它将照在木板箱的前面,看起来挺好。第41页,共70页,2023年,2月20日,星期四最后保存光源的位置。前三个参数和glTranslate中的一样。依次分别是XYZ轴上的位移。由于想要光线直接照射在木箱的正面,所以XY轴上的位移都是0.0f。第三个值是Z轴上的位移。为了保证光线总在木箱的前面,所以我们将光源的位置朝着观察者挪出屏幕。通常将屏幕也就是显示器的屏幕玻璃所处的位置称作Z轴的0.0f点。所以Z轴上的位移最后定为2.0f。假如您能够看见光源的话,它就浮在您显示器的前方。GLfloatLightPosition[]={0.0f,0.0f,2.0f,1.0f};//光源位置第42页,共70页,2023年,2月20日,星期四启用光源。没有启用GL_LIGHTING是看不见任何光线。记住:只对光源进行设置、定位、甚至启用,光源都不会工作。glEnable(GL_LIGHT1);//启用一号光源第43页,共70页,2023年,2月20日,星期四程序完成效果参考程序第44页,共70页,2023年,2月20日,星期四试验8移动图像把场景沿Y轴旋转。如果旋转90度的话,X轴不再是自左至右的了,他将由里向外穿出屏幕。假想您站在房子中间。再设想左侧的墙上写着-x,前面的墙上写着-z,右面墙上就是+x,身后的墙上则是+z。加入整个房子向右转90度,但您没有动,那么前面的墙上将是-x而不再是-z了。所有其他的墙也都跟着移动。-z出现在右侧,+z出现在左侧,+x出现在您背后。glRotatef(star[loop].angle,0.0f,1.0f,0.0f);//旋转至当前所画星星的角度第45页,共70页,2023年,2月20日,星期四沿x轴移动一个正值。通常x轴上的正值代表移向了屏幕的右侧,但这里由于绕y轴旋转了坐标系,x轴的正向可以是任意方向。如果我们转180度的话,屏幕的左右侧就镜像反向了。因此,当我们沿x轴正向移动时,可能向左,向右,向前或向后。
glTranslatef(star[loop].dist,0.0f,0.0f);//沿X轴正向移动第46页,共70页,2023年,2月20日,星期四采用逆序来抵消旋转希望星星永远正面朝着我们,而不管屏幕如何旋转或倾斜。在绘制星星之前,采用逆序来抵消旋转。也就是以当前角度的负值来旋转星星。例如将星星旋转了10度的话,又将其旋转-10度来使星星在那个轴上重新面对屏幕。抵消了沿y轴的旋转。抵消掉沿x轴的屏幕倾斜。需要将屏幕再旋转-tilt倾角。glRotatef(-star[loop].angle,0.0f,1.0f,0.0f);//取消当前星星的角度glRotatef(-tilt,1.0f,0.0f,0.0f);//取消屏幕倾斜第47页,共70页,2023年,2月20日,星期四程序运行效果参考程序第48页,共70页,2023年,2月20日,星期四试验93D世界每个3D世界基本上可以看作是sector(区段)的集合。一个sector(区段)可以是一个房间、一个立方体、或者任意一个闭合的区间。typedefstructtagSECTOR//创建Sector区段结构{intnumtriangles;//Sector中的三角形个数
TRIANGLE*triangle;//指向三角数组的指针
}SECTOR;//命名为SECTOR第49页,共70页,2023年,2月20日,星期四一个sector(区段)包含了一系列的多边形,本实验采用三角形。typedefstructtagTRIANGLE//创建Triangle三角形结构
{VERTEXvertex[3];//VERTEX矢量数组,大小为3}TRIANGLE;//命名为TRIANGLE第50页,共70页,2023年,2月20日,星期四三角形本质上是由一些(两个以上)顶点组成的多边形,顶点同时也是我们的最基本的分类单位。顶点包含了OpenGL真正感兴趣的数据。我们用3D空间中的坐标值(x,y,z)以及它们的纹理坐标(u,v)来定义三角形的每个顶点。typedefstructtagVERTEX//创建Vertex顶点结构{floatx,y,z;//3D坐标floatu,v;//纹理坐标}VERTEX;//命名为VERTEX第51页,共70页,2023年,2月20日,星期四允许用户在这个世界中游走和遍历根据用户的指令旋转并变换镜头位置。围绕原点,以与镜头相反的旋转方向来旋转世界。(让人产生镜头旋转的错觉)以与镜头平移方式相反的方式来平移世界(让人产生镜头移动的错觉)。第52页,共70页,2023年,2月20日,星期四程序实现效果参考程序第53页,共70页,2023年,2月20日,星期四试验10飘动的旗帜#include<math.h>//引入数学函数库中的Sin
旗帜是由由44格×44格的小方格子依次组成。使用points数组来存放网格各顶点独立的x,y,z坐标。floatpoints[45][45][3];//Points网格顶点数组第54页,共70页,2023年,2月20日,星期四//沿X平面循环
for(intx=0;x<45;x++){//沿Y平面循环
for(inty=0;y<45;y++){//向表面添加波浪效果points[x][y][0]=float((x/5.0f)-4.5f);points[x][y][1]=float((y/5.0f)-4.5f);points[x][y][2]=float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));}}第55页,共70页,2023年,2月20日,星期四绘制组成旗帜的44×44个小网格,形成旗帜第一帧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;//生成X浮点值float_y=float(y)/44.0f;//生成Y浮点值
float_xb=float(x+1)/44.0f;//X浮点值+0.0227ffloat_yb=float(y+1)/44.0f;//Y浮点值+0.0227fglTexCoord2f(float_x,float_y);//第一个纹理坐标(左下角)glVertex3f(points[x][y][0],points[x][y][1],points[x][y][2]);glTexCoord2f(float_x,float_yb);//第二个纹理坐标(左上角)glVertex3f(points[x][y+1][0],points[x][y+1][1],points[x][y+1][2]);glTexCoord2f(float_xb,float_yb);//第三个纹理坐标(右上角)glVertex3f(points[x+1][y+1][0],points[x+1][y+1][1],points[x+1][y+1][2]);glTexCoord2f(float_xb,float_y);//第四个纹理坐标(右下角)glVertex3f(points[x+1][y][0],points[x+1][y][1],points[x+1][y][2]);}}glEnd();//四边形绘制结束第56页,共70页,2023年,2月20日,星期四不断更新绘制小网格。形成旗帜飘动效果//用来降低波浪速度(每隔2帧一次)if(wiggle_count==2){for(y=0;y<45;y++)//沿Y平面循环{
hold=points[0][y][2];//存储当前左侧波浪值
for(x=0;x<44;x++)//沿X平面循环{//当前波浪值等于其右侧的波浪值points[x][y][2]=points[x+1][y][2]; }points[44][y][2]=hold;//刚才的值成为最左侧的波浪值
}wiggle_count=0;//计数器清零
}wiggle_count++;//计数器加一
第57页,共70页,2023年,2月20日,星期四程序运行效果参考程序第58页,共70页,2023年,2月20日,星期四试验11二次几何体//绘制圆柱体glTranslatef(0.0f,0.0f,-1.5f);//绘制圆锥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轴有多少细分)。细分越多该对象就越细致。我们可以用增加细分的方法来增加对象的多边形数。第59页,共70页,2023年,2月20日,星期四//绘制圆盘gluDisk(quadratic,0.5f,1.5f,32,32);
参数1(0.5F)是盘子的内圆半径,该参数可以为0,则表示在盘子中间没孔,内圆半径越大孔越大。参数2(1.5F)表示外圆半径,这个参数必须比内圆半径大。参数3(32)是组成该盘子的切片的数量,这个数量可以想象成披萨饼中的切片的数量。切片越多,外圆边缘就越平滑。最后一个参数(32)是组成盘子的环的数量。环很像唱片上的轨迹,一环套一环。这些环从内圆半径细分到外圆半径。第60页,共70页,2023年,2月20日,星期四//绘制球gluSphere(quadratic,1.3f,32,32);
参数1是球的半径。如果你无法理解半径/直径等等的话,可以理解成物体中心到物体外部的距离,在这里我们使用1.3F作为半径。接下来两个参数就是细分了,和圆柱体一样,参数2是纬线,参数3是经线。细分越多球看起来就越平滑第61页,共70页,2023年,2月20日,星期四参考程序第62页,共70页,2023年,2月20日,星期四试验12贝塞尔曲面为了做一个贝塞尔曲面,你需要16个控制点,(4*4),和2个变量t,v。你要做的是计算在分量v的沿4条平行曲线的点,再用这4个点计算在分量t的点。计算了足够的这些点,我们可以用三角带连接他们,画出贝塞尔曲面。
第63页,共70页,2023年,2月20日,星期四typedefstructpoint_3d{//3D点的结构
doublex,y,z;}POINT_3D;typedefstructbpatch{//贝塞尔面片结构POINT_3Danchors[4][4];//由4x4网格组成GLuintdlBPatch;//绘制面片的显示列表名称GLuinttexture;//面片的纹理}BEZIER_PATCH;第64页,共70页,2023年,2月20日,星期四//计算贝塞尔方程的值//变量u的范围在0-1之间
POINT_3DBernstein(floatu,POINT_3D*p){POINT_3Da,b,c,d,r;a=pointTimes(pow(u,3),p[0]);b=pointTimes(3*pow(u,2)*(1-u),p[1]);c=pointTimes(3*u*pow((1-u),2),p[2]);d=pointTimes(pow((1-u),3),p[3]);r=pointAdd(pointAdd(a,b),pointAdd(c,d));returnr;}第65页,共70页,2023年,2月20日,星期四//生成贝塞尔曲面的显示列表
GLuintgenBezier(BEZIER_PATCHpatch,intdivs){intu=0,v;floatpy,px,pyold;GLuintdrawlist=glGenLists(1);//创建显示列表POINT_3Dtemp[4];POINT_3D*last=(POINT_3D*)malloc(sizeof(POINT_3D)*(divs+1));//更具每一条曲线的细分数,分配相应的内存if(patch.dlBPatch!=NULL)//如果显示列表存在则删除glDeleteLists(patch.dlBPatch,1);temp[0]=patch.anchors[0][3];//获得u方向的四个控制点temp[1]=patch.anchors[1][3];temp[2]=patch.anchors[2][3];temp[3]=patch.anchors[3][3];第66页,共70页,2023年,2月20日,星期四for(v=0;v<=divs;v++){//根据细分数,创建各个分割点额参数px=((float)v)/((float)divs);//使用Bernstein函数求的分割点的坐标last[v]=Bernstein(px,temp);}glNewList(drawlist,GL_COMPILE);//创建一个新的显示列表glBindTexture(GL_TEXTURE_2D,patch.texture);//邦定纹理for(u=1;u<=divs;u++){py=((float)u)/((float)divs);//计算v方向上的细分点的参数pyold=((float)u-1.0f)/((float)divs);//上一个v方向上的细分点的参数temp[0]=Bernstein(py,patch.anchors[0]);//计算每个细分点v方向上贝塞尔曲面
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025版人力资源项目外包合同模板
- 人力资源服务合同正规格式指南2025
- 天然气购销标准合同
- 云南省昭通市昭阳区苏家院乡中学2024-2025学年初三年级下学期第二次月考试题含解析
- 铜仁学院《生物合成实验》2023-2024学年第二学期期末试卷
- 南阳工艺美术职业学院《急诊医学Ⅰ》2023-2024学年第二学期期末试卷
- 云南省临沧市达标名校2025届初三下学期期末学业质量监测生物试题理试题含解析
- 西安电子科技大学《行为医学》2023-2024学年第一学期期末试卷
- 内蒙古乌海市海南区2024-2025学年初三下学期第八次统练(一模)生物试题含解析
- 上海中医药大学《媒体展示策划》2023-2024学年第二学期期末试卷
- 专题01《水银花开的夜晚》 高考语文二轮复习
- 机动车维修竣工出厂合格证样式
- JJF 1338-2012相控阵超声探伤仪校准规范
- 中考数学复习备考-几何专题突破与拓展训练题
- GB/T 14388-1993木工硬质合金圆锯片
- 卫生院B超、心电图室危急值报告制度及流程
- 肿瘤化疗-课件
- 第三节钢筋混凝土排架结构单层工业厂房结构吊装课件
- 普通高中学生综合素质评价档案
- 产品路标规划-综述2.1
- 2023年郑州工业应用技术学院单招考试面试题库及答案解析
评论
0/150
提交评论