计算机图形学大作业报告_第1页
计算机图形学大作业报告_第2页
计算机图形学大作业报告_第3页
计算机图形学大作业报告_第4页
计算机图形学大作业报告_第5页
已阅读5页,还剩35页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

陈博文图形学期末报告PAGEPAGE1云南大学软件学院期末课程报告FinalCourseReportSchoolofSoftware,YunnanUniversity个人成绩序号学号姓名成绩1学期:2009年秋季学期课程名称: 计算机图形学任课教师: 实践题目: 创建旋转体小组长: 联系电话: 电子邮件: 2009-2010学年上学期计算机图形学成绩考核表年级:专业:软件工程学号:姓名:本人所做工作:指标内容分值指标内涵及评估标准得分技术路线的可行程度10合理可行,具体且有创新合理可行,具体基本合理可行不够合理或不够具体程序或系统设计思路10程序或系统思路非常清晰、运行正确程序或系统思路基本清晰、运行正确程序或系统思路清晰、环境配置错误无法运行程序或系统思路不清晰,程序无法运行小组成员的工作量(每个人分别打分)15高出平均要求工作量的15%以上高出平均要求工作量达到平均要求工作量低于平均要求的工作量理论知识应用水平15用理论知识对程序设计方法、思路和代码进行详尽、准确地分析和总结用理论知识对程序设计方法、思路和代码进行较准确地分析和总结理论知识应用一般理论知识差达到预期目标的程度10完全达到基本达到无法预见未能达到团队合作精神10很强的团队合作精神合作情况良好合作情况一般合作不好,各自为政报告撰写质量(30分)5报告非常完整报告比较完整完整程度一般报告不完整5逻辑结构清晰逻辑组织较好逻辑组织一般逻辑不清5内容非常丰富内容较丰富内容一般内容欠缺5文字表达非常好文字表达较好文字表达一般文字表达差,意思不明了5图表制作非常专业化图件制作良好图件制作一般图件制作效果差5整体效果很好整体效果良好整体效果一般整体效果差综合得分(满分100分)评语创建旋转体总结报告(GB8567——88)1引言 51.1编写目的 51.2背景 51.3定义 51.4参考资料 62实际开发结果 72.1产品 72.2主要功能和性能 72.3基本流程 102.4进度 202.5费用 203开发工作评价 223.1对生产效率的评价 223.2对产品质量的评价 223.3对技术方法的评价 223.4出错原因的分析 224经验与教训 235附录 261.引言1.1.编写目的本学期计算机图形学课程期末大作业二人小组主要的开发项目就是基于OpenGL的旋转体实现,实现语言VC++,编辑、调试环境VS2008,在学期末终于基本开发完成。是对自我工作的检验和测试,在撰写报告的过程中能够更深刻的了解计算机图形学的理念通过这份文档来记录我们在开发此软件的过程中遇到的问题以及改善的方法。现在对整个开发过程加以认识、记录和总结,留下经验,汲取教训。为以后的其他工作留下经验资料,为以后遇到相同的问题和从事类似项目奠定坚实的基础,以便以后有资可寻、有底可查,增长个人见识,为自己程序开发方面的成长而努力奋斗。并作为期末向指导老师报告的材料。通过此次大作业的编写,我要达到进一步熟悉OpenGL编程的目的,并在以后的学习中得到总结。1.2背景计算机图形学(ComputerGraphics,简称CG)是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格形式的科学。简单地说,计算机图形学的主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。图形通常由点、线、面、体等几何元素和灰度、色彩、线型、线宽等非几何属性组成。从处理技术上来看,图形主要分为两类,一类是基于线条信息表示的,如工程图、等高线地图、曲面的线框图等,另一类是明暗图,也就是通常所说的真实感图形。计算机图形学一个主要的目的就是要利用计算机产生令人赏心悦目的真实感图形。为此,必须建立图形所描述的场景的几何表示,再用某种光照模型,计算在假想的光源、纹理、材质属性下的光照明效果。所以计算机图形学与另一门学科计算机辅助几何设计有着密切的关系。事实上,图形学也把可以表示几何场景的曲线曲面造型技术和实体造型技术作为其主要的研究内容。同时,真实感图形计算的结果是以数字图像的方式提供的,计算机图形学也就和图像处理有着密切的关系。图形与图像两个概念间的区别越来越模糊,但还是有区别的:图像纯指计算机内以位图形式存在的灰度信息,而图形含有几何属性,或者说更强调场景的几何表示,是由场景的几何模型和景物的物理属性共同组成的。计算机图形学的研究内容非常广泛,如图形硬件、图形标准、图形交互技术、光栅图形生成算法、曲线曲面造型、实体造型、真实感图形计算与显示算法、非真实感绘制,以及科学计算可视化、计算机动画、自然景物仿真、虚拟现实等OpenGL是个与硬件无关的软件接口,可以在不同的平台如Windows95、WindowsNT、Unix、Linux、MacOS、OS/2之间进行移植。因此,支持OpenGL的软件具有很好的移植性,可以获得非常广泛的应用。由于OpenGL是图形的底层图形库,没有提供几何实体图元,不能直接用以描述场景。但是,通过一些转换程序,可以很方便地将AutoCAD、3DS/3DSMAX等3D图形设计软件制作的DXF和3DS模型文件转换成OpenGL的顶点数组计算机图形学(ComputerGraphics)是近三十年来发展迅速,应用广泛的新兴学科,主要研究怎样用数字计算机生成、处理和显示图形。

图形的具体应用范围很广,但是从基本的处理技术看只有两类,一类是线条,如工程图、地图、曲线图表等;另一类是明暗图,与照片相似。为了生成图形,首先要有原始数据或数学模型,如工程人员构思的草图,地形航测的判读数据,飞机的总体方案模型,企业经营的月统计资料等等。这些数字化的输入经过计算机处理后变成图形输出。可以说计算机图形学在当代社会的运用已经涉及到了各个领域上的运用,无论在什么领域上计算机图形学都发挥到了自己的作用;计算机图形学以其对图像的专业处理技术,对图形图像的加工运用,实现图形的立体转化,三维立体图形的旋转变形,由平面图到三维立体图的转化等等,都是命了计算机图形学强大的图像处理技术。

说明:a.本项目的名称为“计算机图形学期末大作业”,开发出来的项目名称为“旋转体功能图”。b.此软件为2009年秋季学期云南大学软件学院计算机图形学期末大作业最终报告,编写者为原飞、陈博文。1.3定义计算机图形学:计算机图形学的研究内容非常广泛,如图形硬件、图形标准、图形交互技术、光栅图形生成算法、曲线曲面造型、实体造型、真实感图形计算与显示算法、非真实感绘制,以及计算机动画、自然景物仿真、虚拟现实等。OpenGl:用于编写计算机图形学的程序的编译工具。OpenGL是行业领域中最为广泛接纳的2D/3D图形API,其自诞生至今已催生了各种计算机平台及设备上的数千优秀应用程序。OpenGL是独立于视窗操作系统或其它操作系统的,亦是网络透明的。在包含CAD、内容创作、能源、娱乐、游戏开发、制造业、制药业及虚拟现实等行业领域中,OpenGL™帮助程序员实现在PC、工作站、超级计算机等硬件设备上的高性能、极具冲击力的高视觉表现力图形处理软件的开发。OPENGL的功能及特点:OpenGL是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以它为基础开发的应用程序可以十分方便地在各种平台间移植;OpenGL可以与VisualC++紧密接口,便于实现机械手的有关计算和图形算法,可保证算法的正确性和可靠性;OpenGL使用简便,效率高。它具有七大功能:旋转体:一条平面曲线绕着它所在的平面内的一条定直线旋转所形成的曲面叫作旋转面;封闭的旋转面围成的几何体。旋转矩阵:在乘以一个向量的时候有改变向量的方向但不改变大小的效果的矩阵。旋转矩阵不包括反演,它可以把右手坐标系改变成左手坐标系或反之。所有旋转加上反演形成了正交矩阵的集合。旋转变换:简称旋转.欧氏几何中的一种重要变换.即在欧氏平面上(欧氏空间中),让每一点P绕一固定点(固定轴线)旋转一个定角,变成另一点P′,如此产生的变换称为平面上(空间中)的旋转变换.。变换矩阵:在线性代数中,线性变换能够用矩阵表示。如果T是一个把R映射到R的线性变换,且x是一个具有n个元素的列向量,,那么我们把m×n的矩阵A,称为T的变换矩阵。3D坐标系:

三维笛卡儿坐标系是在二维笛卡儿坐标系的基础上根据右手\o"Zgirls_1@utops.cc"定则增加第三维坐标(即Z轴)而形成的。2D坐标系:在同一个平面上互相垂直且有公共原点的两条数轴构成平面直角坐标系。1.4参考资料a.计算机图形学,项志钢,清华大学出版社,第1版,2006年12月;b.软件文档国家标准(GB8567-88);c.属于本项目的其他已发表的文件;d.OpenGL编程手册;e.VC++编程手册;2实际开发结果2.1产品1

系统需求分析一个旋转体由其外轮廓线绕其竖直中心轴旋转而成。程序要求建立一个窗口显示竖直的中心轴,并且要求实现轮廓线的编辑,具体包含功能:节点的增加、删除和节点间自动连线。程序要求建立另外一个窗口显示轮廓线绕中心轴旋转以后的三维物体,本窗口还要求实现三维物体的Phong着色和对三维物体的简单操作,具体包含:放大、缩小和旋转。移动光源纹理映射效果雾化效果轮廓线使用样条技术2总体设计1项目规划:本系统是一个基于OpenGL开发的实现能够进行人机交互的绘制3D旋转体的系统,本系统中的功能模块主要分为以下几种:矩阵运算模块:实现两个或多个矩阵的相关运算,为绘制图形提供数据结构,体现图形转化过程中的算法。显示图形模块:用于设定图像的显示方式,绘制方法,在其中还可以设置光源位置等相关的显示信息。键盘敲击模块:对不同的键盘敲击事件作出相应的处理,包括点线的转化,雾化效果等。鼠标点击模块:在3D显示窗口添加的鼠标事件,对鼠标的事件作出相应的响应效果。动作模块:根据左边用户绘制的2D图形,动态的划出右面相对应的3D图像。找点模块:在左边的用户画图窗口进行锁定鼠标点击时靠近的点。2系统功能结构3设计目标本系统是根据课本中的程序而开发的,基本能够实现需求中所要求的功能,通过本系统可以达到以下目标:1系统运行稳定,安全可靠。2界面美观、友好。3用户操作使用方便。4生成的3D图形效果良好。5能够正确的生成用户所要绘制的3D图形3主要功能模块设计1矩阵运算模块的设计:功能描述:程序启动后,这部分功能模块会为整个应用程序提供算法支持,具体是矩阵直接的相互运算,在2D向3D转化过程中会起到很重要的作用。代码设计:floatvv(float*v1,float*v2){ returnv1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];}voidvxv(float*n,float*v1,float*v2){ n[0]=v1[1]*v2[2]-v1[2]*v2[1];n[1]=v1[2]*v2[0]-v1[0]*v2[2]; n[2]=v1[0]*v2[1]-v1[1]*v2[0];}voidloadIdentity(Matrixm){ Matrixidentity={{1.0,0.0,0.0,0.0}, {0.0,1.0,0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; for(inti=0;i<4;i++) for(intj=0;j<4;j++) m[i][j]=identity[i][j];}voidpreMultiply(Matrixp,Matrixm){ inti,j; Matrixt; for(i=0;i<4;i++) for(j=0;j<4;j++) t[i][j]=p[i][0]*m[0][j]+p[i][1]*m[1][j]+p[i][2]*m[2][j]+p[i][3]*m[3][j]; for(i=0;i<4;i++) for(j=0;j<4;j++) m[i][j]=t[i][j];}2显示图形模块的设计:功能描述:该模块主要为所要画的图形进行描述,是绘制图形的主要函数,通过调用这个功能模块就能画出用于显示给用户的图形。代码设计://2D图形的display函数voiddisplay(){ glClear(GL_COLOR_BUFFER_BIT); if(n==1&&type==GL_LINE_STRIP){ glBegin(GL_POINTS); glVertex2iv(vert[0]); glColor3f(0,0.5,0.5); glVertex2i(width-vert[0][0]-1,vert[0][1]); glEnd();} glColor3f(0,0.5,0.5); glBegin(GL_LINES); glVertex2i(width/2,0); glVertex2i(width/2,height-1); glEnd(); glBegin(type); for(inti=0;i<n;i++)glVertex2i(width-vert[i][0]-1,vert[i][1]); glEnd(); glColor3f(1,1,0);glBegin(type); for(inti=0;i<n;i++)glVertex2iv(vert[i]); glEnd(); glutSwapBuffers(); initQMesh(); glutSetWindow(winid); glutPostRedisplay();}//3D图形的显示函数voidmodelDisplay(){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); floatM[16]; for(intr=0;r<4;r++)for(intc=0;c<4;c++)M[4*c+r]=CRM[r][c]; glMultMatrixf(M); glScalef(zoom,zoom,zoom); drawQMesh(); glPopMatrix(); glPushMatrix();glLightfv(GL_LIGHT0,GL_AMBIENT,amb); glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);glPopMatrix(); glutSwapBuffers();}3键盘敲击模块功能描述:该功能主要为两个窗体添加键盘敲击事件,在2D窗体中主要添加了反走样效果,清除所画的图,点线转化功能,对于3D窗体主要添加了投影方式的变换,雾化效果,光源移动的功能代码设计://2D绘制窗体的键盘敲击处理函数voidkeyboard(unsignedcharkey,intx,inty){ switch(key){ case'a':antialiasing=!antialiasing;//反走样效果 if(antialiasing){ glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); }else{ glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); } break; case'c':n=0;break;//清除界面功能 case'l':type=GL_LINE_STRIP;break;//绘制线功能 case'v':type=GL_POINTS;break;//绘制点功能 } glutPostRedisplay();}//3D显示窗体的键盘敲击事件处理函数:voidmodelKeyboard(unsignedcharkey,intx,inty){ switch(key){ case'o':glMatrixMode(GL_PROJECTION);//正投影 glLoadIdentity(); glOrtho(-4,4,-4,4,6,14); glMatrixMode(GL_MODELVIEW); break; case'p':glMatrixMode(GL_PROJECTION);//侧投影,不过是默认的 glLoadIdentity(); gluPerspective(45.0,1.0,6.0,14.0); glMatrixMode(GL_MODELVIEW); break; case'm':lightPosition[0]=lightPosition[0]-0.5; //光源移动 break; case'n':lightPosition[1]=lightPosition[1]-0.5; break; case'z':lightPosition[2]=lightPosition[2]-0.5; break; case'q':glEnable(GL_FOG);//雾化效果 { glFogi(GL_FOG_MODE,GL_LINEAR); GLfloatfogColor[]={1.9,1.1,2.2,0.5}; glFogfv(GL_FOG_COLOR,fogColor); glFogf(GL_FOG_START,3.0); glFogf(GL_FOG_END,15.0); glHint(GL_FOG_HINT,GL_DONT_CARE); } break; case'k':glDisable(GL_FOG); break; } glutPostRedisplay();}4鼠标点击模块功能描述:该功能模块主要实现了对两个窗体鼠标事件的处理,对于3D窗体实现了鼠标左键旋转,由键放大缩小的效果,2D窗体实现了左键画点,右键可以对已经存在的点改变它的位置。代码设计://3D窗体的鼠标事件voidmodelMouse(intbutton,intstate,intx,inty){ switch(button){ caseGLUT_LEFT_BUTTON: if(state==GLUT_DOWN){ cx=x; cy=h-1-y; dx=dy=0; left_button_down=true; }else left_button_down=false; break; caseGLUT_RIGHT_BUTTON: if(state==GLUT_DOWN){ cx=x; cy=h-1-y; right_button_down=true; }else right_button_down=false; break; }}//2D窗体鼠标事件voidmouse(intbutton,intstate,intx,inty){ y=height-1-y; switch(button){ caseGLUT_LEFT_BUTTON: if(state==GLUT_DOWN&&!rubberbanding){ v=n++; vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; vert[v][1]=(y<0)?0:(y>=height)?height-1:y; rubberbanding=true; glutPostRedisplay(); } elserubberbanding=false; break; caseGLUT_RIGHT_BUTTON: if(state==GLUT_DOWN&&!rubberbanding&&(v=findVertex(x,y))!=-1){ if(glutGetModifiers()==GLUT_ACTIVE_CTRL){ for(inti=v;i<n-1;i++){vert[v][0]=vert[i+1][0]; vert[i][1]=vert[i+1][1]; } n--; }else{ vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; vert[v][1]=(y<0)?0:(y>=height)?height-1:y; rubberbanding=true; } glutPostRedisplay(); } elserubberbanding=false; break; }}5找点模块功能描述:此方法主要用于对用户所需要的点进行锁定。能够改变原来已经存在的点。intfindVertex(intx,inty){//锁定鼠标靠近的点 intdx,dy; for(inti=0;i<n;i++){ dx=vert[i][0]-x; dy=vert[i][1]-y; if(dx*dx+dy*dy<16)returni; } return-1;}2.2主要功能和性能逐项列出本软件产品所实际具有的主要功能和性能,对照可行性研究报告、项目开发计划、功能需求说明书的有关内容,说明原定的开发目标是达到了、未完全达到、或超过了。通过Editpolygons窗口(二维多边形编辑视窗)绘制多边形。对绘制出的多边形能增删顶点改变多边形形状。通过Objectwindow:李文云,向明海窗口(三维旋转体显示视窗)显示在二维多边形编辑视窗中编辑好的旋转体轮廓的三维旋转体映射。在三维旋转体显示视窗中通过o键切换到正投影显示,通过p键切换到透视投影投影显示在三维旋转体显示视窗中:通过小写字母x用于对电光源位置的x坐标做减量操作,大写字母X用于对电光源位置的x坐标做增量操作;小写字母y用于对电光源位置的x坐标做减量操作,大写字母Y用于对电光源位置的y坐标做增量操作;小写字母z用于对电光源位置的z坐标做减量操作,大写字母Z用于对电光源位置的z坐标做增量操作;字母f、F用于开启雾化效果,小写字母n用于关闭雾化效果在三维旋转体显示视窗中,通过按下鼠标右键同时移动光标来改变三维旋转体大小在三维旋转体显示视窗中,通过按下鼠标左键同时移动光标来转动三维旋转体。说明:原定的开发目标达到了。所要求的全部实现附加要求实现了移动光源,雾化效果两项。功能截图:同时本程序还实现了在编辑基础图形窗口的反走样效果,使用键盘的“a”键进行控制,当按下“a”键时将出现以下的效果

本程序还实现了按下“c”将编辑窗口中的所有图形清除本程序实现了只显示点来作为基础图形的轮廓,通过按下键盘的“v”键可以实现这一功能。如果希望恢复原本的使用线来画出图形的效果的话可以通过按下键盘的“L”键来进行控制,这样就会恢复为默认的情况了在3D图形显示框中实现了对旋转体的Phong着色,旋转体的基本放大,缩小,旋转等操作在图形框中使用鼠标左键按下之后进行拖动,就可以对旋转体进行旋转的控制在3D图形显示框中实现了对旋转体的Phong着色,旋转体的基本放大,缩小,旋转等操作在图形框中使用鼠标左键按下之后进行拖动,就可以对旋转体进行旋转的控制使用鼠标控制旋转之后在图形框中使用鼠标右键按下之后拖动就可以控制旋转体进行缩放下图是缩小之后的图形下图是放大之后的图形关闭雾化效果移动光源删除顶点:本程序同样实现了光源的移动按下“x”之后可以进行光源坐标1的负相移动,按下“y”之后可以实现光源坐标2的负相移动,按下“z”之后可以实现光源坐标3的负相移动,按下“1”之后可以实现光源坐标1的正相移动,按下“2”之后可以实现光源坐标2的正相移动,按下“3”之后可以实现光源坐标3的正相移动。2.3基本流程这个程序使用VS为编译工具,使用C++语言,运用OPENGL技术,使窗口能够动态的接收用户的输入信息,包括鼠标和键盘的事件响应,使用户能够画出自己想要的对称二维图形,再由程序将其转换为三维图像,并最终实现三维图像的各种操纵功能,具体实现是一个一个窗体进行实现的Editpolygons窗体的实现:首先,绘制基本窗体,包括左边,色调等内容接着,绘制中轴线及相关的内容接着,在窗体中加入键盘和鼠标的事件截获功能,使其能捕获鼠标或键盘的事件接着,制作点绘制线的功能,将线绘制成几何图形。接着,利用中轴线使线的坐标关于中轴对称,使其成为对称图形接着,添加反走样效果,添加清楚界面功能,添加绘制线和绘制点的功能。DisplayObject窗口的实现首先,绘制基本窗体,包括左边,色调等内容接着,通过第一个窗体的内容绘制三维图形接着,实现其视角的转移接着,增加其视角缩进效果最后,增加其雾化效果,光源移动效果通过二维制图视窗(程序中为Editpolygons)用户可以以交互的方式描绘与修改旋转体的轮廓二维多边形。多边形在程序中由一个名为vert的数组代表,它的元素为顶点坐标(x,y)。器显示的形式可以是一系列的点,一条折现或一条闭合折线。绘制多边形:通过交互用户可以增加,删除或改变顶点位置进而给代表旋转体的多边形带来相应网格的变化。当鼠标光标在Editpolygons视窗中时,不按下鼠标键,光标移动将不会产生任何影响。当按下左键时,就会在现存顶点序列后面加上一个当前光标位置的顶点。如果这个新顶点是第一个顶点,则他就以点的形式出现。否则这个顶点就以线段的形式与前一个顶点相连。在左键保持被保持被按下状态时的任何光标移动都经过橡皮圈技术处理。释放左键,新顶点与光标脱离。用户可以把光标移动到一个现存顶点的重力场之内,并压下鼠标右键键就可以选中该顶点。如果选中成功,就可以在保持右键被压下的状态下,改变顶点位置(使用橡皮圈技术),如果选择失败,则不会对图形产生影响。函数为:intfindVertex(intx,inty){如果在Ctrl建被按下的状态下选择点成功的话,可以删除该顶点。函数为:voidmouse(intbutton,intstate,intx,inty)绘制三维旋转体:在键盘事件处理子程序voidkeyboard(unsignedcharkey,intx,inty)中定义了几个单字指令键:a用于启动和终止反走样功能;c,C用于清除显示区域,就是删除所有顶点;l,L以线条的方式显示多边形;v,V仅显示顶点display子函数在多边形绘制视窗正中间画出一条垂直线来作为旋转轴位置的位置视觉指南:glBegin(GL_LINES);//绘制中间分界线。另外还画出当前轮廓线相对于旋转轴的镜面反射来突出正在绘制中的物体的完整外形: initQMesh();。最后创建与低昂前轮廓相对应的三位模型,并刷新显示视窗:glutSetWindow(winid);//显示三位物体显示窗口;glutPostRedisplay();。回调子程序motion函数跟踪鼠标按钮被按下时的光标位置,在这对顶点以橡皮圈方式附属于于光标的有效范围作了限制,这样每个顶点都不会离开绘制视窗的有半侧:voidmotion(intx,inty){ if(rubberbanding){//如果橡皮圈打开,更新顶点vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x;//顶点被用新的索引标记 y=height-1-y;vert[v][1]=(y<0)?0:(y>=height)?height-1:y;//光标位置glutPostRedisplay();//重画顶点同样在回调子程序mouse中也限制了新定点的初始位置以及现存顶点与绘图光标的起始附属关系,使得所有顶点在任何时刻都停留在绘图视窗的右半侧。有五个函数用来建立三位模型,实现着色,处理用户与显示视窗的交互活动旋转体的表面有存放在数组QMesh中的一个四边形网格代表,表面的前后两面被赋予了不同颜色特征,现场有一个位于物体与观察点之间,大约在十到十一点钟的点光源。在main函数中,在glutMainLoop之前,下列代码用于对显示窗进行初始化,比设置有关材料,光照,投影和观察的参数,以及把单位矩阵放入RM和CRM:2.4进度原计划:十七周搞清基本原理,十八周完实现及完成全部代码。实际进度:十八周完才搞清基本原理,十九周四才实现全部代码。实际进度延迟了。延迟原因:总体上来讲这学期选课太多,且有五门都有实验和大作业,负担太重,很是力不从心。大一没好好学,数学基础太差,很多东西理解起来十分困难。对课程基础知识掌握不好,也造成相当大的困难。项目的实际总体进度是延迟了,在做需求分析时,我们基本按照提到的的要求进行了需求分析,其中做的比较完善的部分是第一个窗体的部分,可是由于技术问题,需求分析并没有真正达到指导的目的,所以我们便开始代码开发部分。由于对Opengl的运用并不十分熟练,使我们延长了较长时间,前一部分时间我们是在进行了对技术的基本学习和掌握,而在实际开发的过程中也是一个边学习边实践的过程,也就造成了一些不必要的错误,而在开发过程中也遇到了许多预期之外的问题和困难,也有一些比较难解决的困难,并且由于C++的原因,调试起来比较不方便,而我们本身对代码并不十分熟悉,所以总体上我们的开发时间使用了较长的时间。而测试文档本打算比较快速的完成,但是却发现在测试时候发现比较多的程序问题,使我们的测试进度受到影响,基本是边改边进行继续测试整体来说工程进度拖后了不少,但是最终实现了。总的来说是由于之前对项目难度的估计不足和对自身实力的不明确造成的。但是我们在一步一步开发的过程中,渐渐掌握了技术的要点,使整个项目并没有停滞下来,问题渐渐比较快速的解决完成。使我们收获很多3开发工作评价3.3对技术方法的评价在开发的过程中,我们是由浅到深的进行开发,我们先争取实现基本功能,之后再进一步实现扩展功能。具体来说,我们首先编写我们已经掌握到了的知识,例如窗体的创建,窗体的基本功能,然后再添加一些通过查阅资料得到的知识要点,例如对称图形的绘制,键盘和鼠标的事件触发问题,点和线的图形分别绘制。之后再添加核心的功能,例如获得点的矩阵,通过旋转实现最终的三维图形。最后再增加扩展功能,例如通过查阅资料和咨询实现的雾化效果和光源效果等内容。在整体调试时,出现了很多问题,甚至使程序不能运行的问题,所以这也是我们遇到的最大障碍。而主要的所有困难来源是对于C++语言和OpenGL的不够熟悉和一些错误的认识,由于开发过程比较底层,我们几乎是一边熟悉编译环境,熟悉C++,熟悉OpenGL,一边进行的项目,这使我们走了不少弯路,但是也从中获得了很多的知识。但是无论之前怎样,最终实现了基本功能就是一种成功,同时也实现了部分附加功能,尤其是这部分,我们投入了比较大的精力去研究和实现,所以,这就比较锻炼我们的能力。这次大作业我们投入了较大的心血,所以对自己比较满意,同时也体现了团队的精神,互相合作和分工,使我们的项目能够顺利完成,最后也是对我们自己的一种肯定3.4出错原因的分析本次大作业通过OPENGL制作的,由于之前对于OPENGL并不十分了解,也对C++并不十分了解,所以,我们在写程序的过程中遇到了很多不应该有的低级错误,由于动手过程并不十分多,所以,我们对于错误的修改也并不十分在行,所以致使我们遇到了很多错误。同时,我们对于图形学的理解也并不十分透彻,有些地方由于理解性错误和习惯思维,致使我们走了比较多弯路。4经验与教训个人小结陈博文学号20071120118通过对本次大作业报告的重新编写,对本次大作业有了更加深入的理解,更进一步了解了OpenGL的用法,从计算机图形学课程中可能收获最多的并不是图形学的一些基础知识,虽然这些很重要,但是真正有些成就感的还是用OpenGL开发出来的这些程序。特别是这个项目,和前面几个只需抄抄代码就能出来的实验相比,是需要好好动动脑筋的。在这个项目中需要处理鼠标等设备的输入,然后再根据输入捕捉相应的变化再进行处理。这一块对于我来说是比较困难的。在解决这个问题上花了不少的时间,在解决这个问题之后应当说后面的工作还是比较轻松的。计算机图形学是交互式图形开发的基本理论,同时也是一门实践性的学科,我通过做老师布置的4个试验后,真正体会了下使用OpenGL编程,感觉OpenGL对底层的封装很好,自己原本来认为会很复杂的东西,使用OpenGL几行代码就解决了,我觉得要学好OpenGL就要对它的API有足够的了解,很多时候就是因为一个函数想不起来而花费大量的时间去网上搜寻结果,所以对一些常用的函数还是要牢记的。本项目实现的代码结构还是非常简单。但编程的时候遇到的一个比较大的问题是起初对于坐标系及在3D坐标系中向量的变换。由于我们主要从设备那只能获得相对于屏幕的x-y坐标系的值,所以要经过一系列的转换才能获得重新获得渲染3D图像的一些值。整了很久才弄懂了这个过程,所以在此记录下来。 控制物体的大小是通过鼠标检测左右鼠标的按下状态来控制的。而物体的旋转则是通过跟踪鼠标在窗体里的移动来实现的。用上一次保存的光标位置和现在通过检测得到的位置可以算出当前的旋转轴,两点和这根旋转轴可以确定两个点之间的距离。通过连个计算公式就可以确定2D坐标和3D坐标的联系。从而实现2D坐标系的变换和与之相应的3D坐标的变换。总之通过这学期的图形学的学习,为以后有机会接触图形学相关知识打下了一定的基础,同时也激发了自己对图形学的兴趣,我想如果以后有机会我会更加深入的去学习有关计算机图形学的知识。至于OpenGL,还是比较底层,我想继续在这学期的基础上,再学些比较高层次的框架。

附录:完整代码#include<gl/glut.h>#include<math.h>#defineQMeshSize256intwidth=400,height=600,vert[100][2],n=0,type=GL_LINE_STRIP,v;boolrubberbanding=false,antialiasing=false;floatQMesh[100][QMeshSize+1][3];GLfloatlightPosition[]={-4.0,4.0,-6.0,1.0};GLfloatamb[]={0.3f,0.3f,0.3f,0.3f};GLfloatfrontDiffAmb[]={0.95f,0.3f,0.1f,1.0};GLfloatbackDiffAmb[]={0.1f,0.3f,0.95f,1.0};GLfloatSpec[]={0.45f,0.45f,0.45f,1.0};GLfloatSpecExp=15.0;boolleft_button_down=false,right_button_down=false;intw=600,h=600,winid,cx,cy,dx=0,dy=0;floatzoom=1.0;typedeffloatMatrix[4][4];MatrixRM,CRM;voidinitQMesh(){ floatr; for(inti=0;i<n;i++){ r=vert[i][0]-width/2.0; for(intj=0;j<QMeshSize;j++){ QMesh[i][j][0]=r*cos(3.14159*2*j/QMeshSize)/100; QMesh[i][j][1]=(vert[i][1]-height/2.0)/100; QMesh[i][j][2]=r*sin(3.14159*2*j/QMeshSize)/100; } QMesh[i][QMeshSize][0]=QMesh[i][0][0];QMesh[i][QMeshSize][1]=QMesh[i][0][1]; QMesh[i][QMeshSize][2]=QMesh[i][0][2]; }}voiddisplay(){ glClear(GL_COLOR_BUFFER_BIT); if(n==1&&type==GL_LINE_STRIP){ glBegin(GL_POINTS); glVertex2iv(vert[0]); glColor3f(0,0.5,0.5); glVertex2i(width-vert[0][0]-1,vert[0][1]); glEnd();} glColor3f(0,0.5,0.5); glBegin(GL_LINES); glVertex2i(width/2,0); glVertex2i(width/2,height-1); glEnd(); glBegin(type); for(inti=0;i<n;i++)glVertex2i(width-vert[i][0]-1,vert[i][1]); glEnd(); glColor3f(1,1,0);glBegin(type); for(inti=0;i<n;i++)glVertex2iv(vert[i]); glEnd(); glutSwapBuffers(); initQMesh(); glutSetWindow(winid); glutPostRedisplay();}voidkeyboard(unsignedcharkey,intx,inty){ switch(key){ case'a':antialiasing=!antialiasing; if(antialiasing){ glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); }else{ glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); } break; case'c':n=0;break; case'l':type=GL_LINE_STRIP;break; case'v':type=GL_POINTS;break; } glutPostRedisplay();}intfindVertex(intx,inty){ intdx,dy; for(inti=0;i<n;i++){ dx=vert[i][0]-x; dy=vert[i][1]-y; if(dx*dx+dy*dy<16)returni; } return-1;}voidmouse(intbutton,intstate,intx,inty){ y=height-1-y; switch(button){ caseGLUT_LEFT_BUTTON: if(state==GLUT_DOWN&&!rubberbanding){ v=n++; vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; vert[v][1]=(y<0)?0:(y>=height)?height-1:y; rubberbanding=true; glutPostRedisplay(); } elserubberbanding=false; break; caseGLUT_RIGHT_BUTTON: if(state==GLUT_DOWN&&!rubberbanding&&(v=findVertex(x,y))!=-1){ if(glutGetModifiers()==GLUT_ACTIVE_CTRL){ for(inti=v;i<n-1;i++){vert[v][0]=vert[i+1][0]; vert[i][1]=vert[i+1][1]; } n--; }else{ vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; vert[v][1]=(y<0)?0:(y>=height)?height-1:y; rubberbanding=true; } glutPostRedisplay(); } elserubberbanding=false; break; }}voidmotion(intx,inty){ if(rubberbanding){vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; y=height-1-y;vert[v][1]=(y<0)?0:(y>=height)?height-1:y;glutPostRedisplay(); }}voidnormalize(float*v){ floatm=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); for(inti=0;i<3;i++) v[i]=v[i]/m;}floatvv(float*v1,float*v2){ returnv1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];}voidvxv(float*n,float*v1,float*v2){ n[0]=v1[1]*v2[2]-v1[2]*v2[1];n[1]=v1[2]*v2[0]-v1[0]*v2[2]; n[2]=v1[0]*v2[1]-v1[1]*v2[0];}voidloadIdentity(Matrixm){ Matrixidentity={{1.0,0.0,0.0,0.0}, {0.0,1.0,0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; for(inti=0;i<4;i++) for(intj=0;j<4;j++) m[i][j]=identity[i][j];}voidpreMultiply(Matrixp,Matrixm){ inti,j; Matrixt; for(i=0;i<4;i++) for(j=0;j<4;j++) t[i][j]=p[i][0]*m[0][j]+p[i][1]*m[1][j]+p[i][2]*m[2][j]+p[i][3]*m[3][j]; for(i=0;i<4;i++) for(j=0;j<4;j++) m[i][j]=t[i][j];}voidrotate(floatangle,float*axis){ floatv[3]={axis[0],axis[1],0}, i[3]={1,0,0}, k[3]={0,0,1};loadIdentity(RM); normalize(v); floatr1=(v[1]<0)?acos(vv(v,i)):-acos(vv(v,i)); MatrixRz={{cos(r1),-sin(r1),0.0,0.0}, {sin(r1),cos(r1),0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(Rz,RM); floatr2=-acos(vv(axis,k)); MatrixRy={{cos(r2),0.0,sin(r2),0.0}, {0.0,1.0,0.0,0.0}, {-sin(r2),0.0,cos(r2),0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(Ry,RM); MatrixR={{cos(angle),-sin(angle),0.0,0.0}, {sin(angle),cos(angle),0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(R,RM); MatrixR_y={{cos(-r2),0.0,sin(-r2),0.0}, {0.0,1.0,0.0,0.0}, {-sin(-r2),0.0,cos(-r2),0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(R_y,RM); MatrixR_z={{cos(-r1),-sin(-r1),0.0,0.0}, {sin(-r1),cos(-r1),0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(R_z,RM); preMultiply(RM,CRM);}voiddrawQMesh(){ inti,j; floatv1[3],v2[3],norm[3]; glBegin(GL_QUADS);for(i=0;i<n-1;i++) for(j=0;j<QMeshSize;j++){ v1[0]=QMesh[i+1][j+1][0]-QMesh[i][j][0];v1[1]=QMesh[i+1][j+1][1]-QMesh[i][j][1]; v1[2]=QMesh[i+1][j+1][2]-QMesh[i][j][2]; v2[0]=QMesh[i+1][j][0]-QMesh[i][j+1][0]; v2[1]=QMesh[i+1][j][1]-QMesh[i][j+1][1]; v2[2]=QMesh[i+1][j][2]-QMesh[i][j+1][2]; vxv(norm,v1,v2); glNormal3fv(norm); glVertex3fv(QMesh[i][j]); glVertex3fv(QMesh[i][j+1]); glVertex3fv(QMesh[i+1][j+1]); glVertex3fv(QMesh[i+1][j]); } glEnd();}voidmodelDisplay(){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); floatM[16]; for(intr=0;r<4;r++)for(intc=0;c<4;c++)M[4*c+r]=CRM[r][c]; glMultMatrixf(M); glScalef(zoom,zoom,zoom); drawQMesh(); glPopMatrix(); glPushMatrix();glLightfv(GL_LIGHT0,GL_AMBIENT,amb); glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);glPopMatrix(); glutSwapBuffers();}voidmodelKeyboard(unsignedcharkey,intx,inty){ switch(key){ case'o':glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-4,4,-4,4,6,14); glMatrixMode(GL_MODELVIEW); break; case'p':glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0,1.0,6.0,14.0); glMatrixMode(GL_MODELVIEW); break; case'x':lightPosition[0]=lightPosition[0]-0.5; break; case'X':lightPosition[0]=lightPosition[0]+0.5; break; case'y':lightPosition[1]=lightPosition[1]-0.5; break; case'Y':lightPosition[1]=lightPosition[1]+0.5; break; case'z':lightPosition[2]=lightPosition[2]-0.5; break; case'Z':lightPosition[2]=lightPosition[2]+0.5; break; case'W': case'w':glEnable(GL_FOG); { glFogi(GL_FOG_MODE,GL_LINEAR); GLfloatfogColor[]={1.9,1.1,2.2,0.5}; glFogfv(GL_FOG_COLOR,fogColor); glFogf(GL_FOG_START,3.0); glFogf(GL_FOG_END,15.0); glHint(GL_FOG_HINT,GL_DONT_CARE); } break; case'K': case'k':glDisable(GL_FOG); break; } glutPostRed

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论