您好,欢迎访问三七文档
1一、设计实验目的通过实验可以更了解Bezier曲线曲面的概念,理解Bezier曲面生成的原理,加深对Bezier生成算法的理解,加强理论的学习,锻炼对知识的运用能力和实践能力;进一步对OpenGL强大功能的认识,并对一些函数如display()、makeImage()、init()、reshape(intw,inth)等的功能的运用又进一步的了解,为以后的学习打下基础。二、设计实验要求呈现Bezier曲面,并使其能够旋转和平移三、实验原理本程序用VisualC++Win32ConsoleApplicstion(32控制台应用程序)创建一个应用程序,再添加一个c++程序源—Bezier曲面。绘制Bezier曲面主要运用多个多边形逼近而成,,并通过少数几个控制点对其进行描述。通过定义曲面和均匀网格绘制一个具有光照和明暗处理效果的Bezier曲面,并实现曲面的放大和缩小,绕x轴,y轴,z轴旋转四、算法分析:下面给出程序中主函数中各函数功能说明:glutInit(&argc,argv)初始化GLUT,用来接收来自main函数的参数,程序可以具体实现相关方式来使用这些参数。glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH)颜色缓存的缓存模式,用于显示图形的颜色;glutInitWindowSize(1000,600)函数功能是创建一个窗口大小为(1000,600);glutInitWindowPosition(30,40)函数是所创建的窗口的(0,0)坐标在电脑窗口(30,40)出显示出来;glutCreateWindow(argv[0])函数的功能实在屏幕上创建一个窗口;glutDisplayFunc(display)函数display在每次对窗口重绘时使用;glutReshapeFunc(reshape)函数主要是改变窗口大小的操作进行重绘;glutMainLoop()是程序进入无限事件处理循环计算函数,该函数的调用应为main函数最后一条语句出现。下面是各函数中的组成函数功能说明:定义控制点坐标数组:GLfloatctrlpoints[4][4][3]绘制曲面(包含的代码描述了所要绘制的Bezier曲面)函数:display()2生成图形的纹理函数:makeImage()负责状态变量初始化的函数:init()改变窗口大小的操作进行重绘的函数:reshape()程序进入无限事件处理循环计算函数:glutMainLoop()glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)主要定义窗口底面颜色voidglEvalMesh2(GLenummode,GLintp1,GLintp2,GLintq1,GLintq2)的mode参数除了可以是GL_POINT和GL_LINE外,也可以是GL_FILL(生成填充空间曲面)。voidglMap2{fd}(GLenumtarget,TYPEu1,TYPEu2,GLintustride,GLintuorder,TYPEv1,TYPEv2,Glintvstride,GLintvorder,TYPEpoints);这里target的意义与在glMap1*()中的意义相同;(u1,u2),(v1,v2)是二维曲面坐标;其他参数如uorder,vorder,ustride和vstride等的定义都类似于在曲线中的定义;points为控制点坐标。对曲面任意一点的计算可通过函数voidglEvalCoord2{fd}[v](TYPEu,TYPEv);来完成,通过在定义域内的曲线坐标值u,v来计算曲面内任意一点的世界坐标位置。对于曲面,也可以象曲线一样通过函数来定义均匀间隔的曲面坐标值:voidglMapGrid2{fd}(GLenumnu,TYPEu1,TYPEu2,GLenumnv,TYPEv1,TYPEv2);该函数定义曲面参数空间均匀网格,从u1到u2分为等间隔nu步,从v1到v2分为等间隔nv步,然后由glEvalMesh2()将此网格应用到已经启动的曲面计算上。一般来说,纹理图像为正方形或长方形。但当它映射到一个多边形或曲面上并变换到屏幕坐标时,纹理的单个纹素很少对应于屏幕图像上的象素。根据所用变换和所用纹理映射,屏幕上单个象素可以对应于一个纹素的一小部分(即放大)或一大批纹素(即缩小)。下面用函数glTexParameteri()说明放大和缩小的方法:glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);实际上,第一个参数可以是GL_TEXTURE_1D或GL_TEXTURE_2D,即表明所用的纹理是一维的还是二维的;第二个参数指定滤波方法,其中参数值GL_TEXTURE_MAG_FILTER指定为放大滤波方法,GL_TEXTURE_MIN_FILTER指定为缩小滤波方法。若选择GL_NEAREST则采用坐标最靠近象素中心的纹素,这有可能使图像走样;若选GL_LINEAR则采用最靠近象素中心的四个象素的加权平均值。GL_NEAREST所需计算比GL_LINEAR要少,因而执行得更快,但GL_LINEAR提供了比较光滑的效果。GLfloatambient[4]={0.8,0.6,0.4,1.0}定义初始化光照、材质的过程GLfloatposition[4]={0.0,1.0,3.0,1.0}为定义一个黄色光源GLfloatmat_diffuse[4]={0.8,0.2,0.1,1.0}是定义特定颜色的镜面反射GLfloatmat_specular[4]={0.8,0.6,0.3,1.0}是定义镜面反射的光亮度GLfloatmat_shininess[1]={60.0}为光源发光的角度五、源程序:#includestdlib.h#includeGL/glut.h#includemath.hGLfloatctrlpoints[4][4][3]={//控制点坐标{{-1.5,-1.5,4.0},{-0.5,-1.5,2.0},{0.5,-1.5,-1.0},{1.5,-1.5,2.0}},3{{-1.5,-0.5,1.0},{-0.5,-0.5,3.0},{0.5,-0.5,0.0},{1.5,-0.5,-1.0}},{{-1.5,0.5,4.0},{-0.5,0.5,0.0},{0.5,0.5,3.0},{1.5,0.5,4.0}},{{-1.5,1.5,-2.0},{-0.5,1.5,-2.0},{0.5,1.5,0.0},{1.5,1.5,-1.0}}};GLfloattheta[3]={0.0,0.0,0.0};GLfloatd=0;GLfloattexpts[2][2][2]={{{0.0,0.0},{0.0,1.0}},{{1.0,0.0},{1.0,1.0}}};voiddisplay(void){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glColor3f(1.0,1.0,1.0);glEvalMesh2(GL_FILL,0,20,0,20);glFlush();glutSwapBuffers();}#defineimageWidth64#defineimageHeight64GLbyteimage[3*imageWidth*imageHeight];voidmakeImage(void){inti,j;floatti,tj;for(i=0;iimageWidth;i++){ti=2.0*3.14159265*i/imageWidth;for(j=0;jimageHeight;j++){tj=2.0*3.14159265*j/imageHeight;image[3*(imageHeight*i+j)]=(GLubyte)127*(1.0+sin(ti));image[3*(imageHeight*i+j)+1]=(GLubyte)127*(1.0+cos(2*tj));image[3*(imageHeight*i+j)+2]=(GLubyte)127*(1.0+cos(ti+tj));}}}voidinit(void){glClearColor(0.0,0.0,0.0,1.0);//清屏glEnable(GL_DEPTH_TEST);//激活深度比较glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,&ctrlpoints[0][0][0]);//定义曲面glMap2f(GL_MAP2_TEXTURE_COORD_2,0,1,2,2,0,1,4,2,&texpts[0][0][0]);glEnable(GL_MAP2_TEXTURE_COORD_2);//启动曲面glEnable(GL_MAP2_VERTEX_3);4glEnable(GL_MAP2_VERTEX_3);//启用曲面glEnable(GL_AUTO_NORMAL);//启用曲面法向向量计算glEnable(GL_NORMALIZE);//启用法向归一化glMapGrid2f(20,0.0,1.0,20,0.0,1.0);//定义参数空间的均匀网格GLfloatambient[4]={0.8,0.6,0.4,1.0};//初始化光照、材质的过程GLfloatposition[4]={0.0,1.0,3.0,1.0};//定义一个黄色光源GLfloatmat_diffuse[4]={0.8,0.2,0.1,1.0};//定义特定颜色的镜面反射GLfloatmat_specular[4]={0.8,0.6,0.3,1.0};//定义镜面反射的光亮度GLfloatmat_shininess[1]={60.0};//光源发光的角度glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);glLightfv(GL_LIGHT0,GL_POSITION,position);glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);//makeImage();glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,imageWidth,imageHeight,0,GL_RGB,GL_UNSIGNED_BYTE,image);//定义一个二维纹理映射glEnab
本文标题:Bezier曲面
链接地址:https://www.777doc.com/doc-5301751 .html