




已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于OpenGL的虚拟校园开发结题报告1 用到的开发工具介绍OpenGL:严格讲,OpenGL被定义为“图形硬件的一种软件接口”。从本质上说,它是一个3D图形和模型库,具有高度可移植性,并且具有非常快的速度。OpenGL并不像c或c+一样是门编程语言,它更像一个C运行时的函数库,提供一些预包装的功能。事实上并不存在像“OpenGL程序”之类的东西,而是开发人员所编写的程序恰好使用了OpenGL作为它的应用程序编程接口之一。一般而言,OpenGL是供那些专门设计用来显示和操纵3D图形的计算机硬件所用的。也可以实现纯软件的OpenGL泛型。OpenGL是独立于视窗操作系统或其它操作系统的,亦是网络透明的。它最早是SGI为图形工作站开发的。随着OpenGL成为高性能图形与交互式视景处理的工业标准,以它为基础开发的应用程序可以十分方便地在各种平台间移植, OpenGL 帮助程序员实现在 PC、工作站、超级计算机等硬件设备上的高性能、极具冲击力的高视觉表现力图形处理软件的开发。目前几乎所有的3D图形显示卡都已经支持OpenGL。OpenGL的应用范围已经从游戏开发、三维设计等逐步扩展到3D图形、图像处理、广告、动画、虚拟现实、科学计算可视化、仿真等多种领域多个层面。OpenGL可以与Visual C+紧密接口,而且使用简便,效率高。3ds max:3D Studio Max,常简称为3ds Max或MAX,是Autodesk公司开发的基于PC系统的三维动画渲染和制作软件。其前身是基于DOS操作系统的3D Studio系列软件,最新版本是2011。是目前市场上最流行的三维造型和动画制作软件之一,也是当前世界上销售量最大的三维建模、动画及渲染解决方案之一。在当今的数字化时代,3ds max为用户提供了极为强大的三维制作解决方案,在诸如建筑,工业机械设计,电影特效制作等方面,3ds max都能为人们提供完善的三维制作和实现引擎在影视特效方面也有一定的应用。而在国内发展的相对比较成熟的建筑效果图和建筑动画制作中,3ds max的使用率更是占据了绝对的优势。根据不同行业的应用特点对3ds max的掌握程度也有不同的要求,建筑方面的应用相对来说要局限性大一些,它只要求单帧的渲染效果和环境效果,只涉及到比较简单的动画;片头动画和视频游戏应用中动画占的比例很大,特别是视频游戏对角色动画的要求要高一些;影视特效方面的应用则把3ds max的功能发挥到了极至。VC+:MicrosoftVisual C+,(简称Visual C+、MSVC、VC+或VC)微软公司的C+开发工具,具有集成开发环境,可提供编辑C语言,C+以及C+/CLI等编程语言。VC+整合了便利的除错工具,特别是整合了微软视窗程式设计(Windows API)、三维动画DirectX API,Microsoft .NET框架。它是Microsoft公司推出的开发Win32环境程序,面向对象的可视化集成编程系统。它不但具有程序框架自动生成、灵活方便的类管理、代码编写和界面设计集成交互操作、可开发多种程序等优点,而且通过简单的设置就可使其生成的程序框架支持数据库接口、OLE2,WinSock网络、3D控制界面。2项目实施步骤:2.1 OpenGl的学习:通过对OpenGL的理论学习,我们了解了OpenGL的图形生成原理,通常来讲在计算机上生成三维图形一般需要经过以下几个步骤:建立模型;选择有利的视角;颜色处理;光照和材质处理;纹理贴图;图形增强;绘制和显示。现对此过程一一进行描述。2.1.1建立模型真实世界里的多数物体都可以在计算机中用简单的点、线、多边形及过程式方法来描述。在OpenGL中提供了丰富的基本图元绘制命令,从而可以方便地绘制物体。此外,还提供复杂的三维物体,如球、锥、多面体、茶壶以及复杂曲线和曲面(例如Bzier、NURBS等曲线或曲面)的绘制函数。1)绘图的一些基本操作 glClear*语句的作用是用当前缓冲区清除值,也就是glClearColor或者glClearDepth等函数所指定的值来清除指定的缓冲区。比如:glClearColor(0.0,0.0,0.0,0.0);glClear(GL_COLOR_BUFFER_BIT);第一条语句表示清除颜色设为黑色,第二条语句表示把整个窗口清除为当前的清除颜色,glClear*的唯一参数表示需要被清除的缓冲区。glutMainLoop,进行一个消息循环。使用void glFlush( void );和void glFinish( void );两个函数强制完成绘图操作。2)绘制基本的几何图形OpenGL绘制的基本几何图元由函数void glBegin( GLenum mode);void glEnd( void); 完成。mode指定图元的类型,如下图。另外OpenGL的工具库GLUT还提供了一些绘制三维物体的函数:在绘制过程中可以设置线宽,虚线实线,法线等状态,另外还可以使用顶点数组绘制几何图形。3)面和体 对于多边形的面(三角形,四边形同样适用),OpenGL定义了与线型相似的填充模式。可以用glPolygonMode*函数实现。 一般约定为“顶点以逆时针顺序出现在屏幕上的面”为“正面”,另一个面即成为“反面”。 可以通过glFrontFace函数来交换“正面”和“反面”的概念。glFrontFace(GL_CCW);/设置CCW方向为“正面”,CCW即CounterClockWise,逆时针glFrontFace(GL_CW);/设置CW方向为“正面”,CW即ClockWise,顺时针 在三维空间中,一个多边形虽然有两个面,但我们无法看见背面的那些多边形,而一些多边形虽然是正面的,但被其他多边形所遮挡。如果将无法看见的多边形和可见的多边形同等对待,无疑会降低我们处理图形的效率。在这种时候,可以将不必要的面剔除。首先,使用glEnable(GL_CULL_FACE);来启动剔除功能(使用glDisable(GL_CULL_FACE)可以关闭之)然后,使用glCullFace来进行剔除。glCullFace的参数可以是GL_FRONT,GL_BACK或者GL_FRONT_AND_BACK,分别表示剔除正面、剔除反面、剔除正反两面的多边形。 多边形可以进行镂空,使用glEnable(GL_POLYGON_STIPPLE);来启动镂空模式(使用glDisable(GL_POLYGON_STIPPLE)可以关闭之)。然后,使用glPolygonStipple*来设置镂空的样式。voidglPolygonStipple(constGLubyte*mask); 其中的参数mask指向一个长度为128字节的空间,它表示了一个32*32的矩形应该如何镂空。2.1.2变换OpenGL图形库的变换包括基本变换和投影变换,基本变换有平移、旋转、缩放三种种变换,投影变换有平行投影(又称正射投影)和透视投影两种变换。1)几何变换物体是相对远点定义与绘制的,所以移动坐标原点就相当于物体的平移运动。 平移变换:void glTranslatef (x, y, z)void glTranslated (x, y, z)函数分别采用浮点数和整数,将原点移动到(x, y, z)位置。 旋转变换:Void glRotatef (angle, x, y, z)Void glRotated (angle, x, y, z)函数分别采用浮点数与整数,绕着从原点指向(x, y, z)的射线,逆时针旋转angle(单位:度)。 缩放变换:Void glScalef (a, b, c)Void glScaled (a, b, c)函数分别采用浮点数与整数,将坐标系的x轴、y轴、z轴分别缩放a、b、c倍。坐标系中的物体将同步缩放。2)投影变换平行投影使用函数void glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)透视投影使用void glFrustum(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top, GLdouble znear, GLdouble zfar)和void gluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)进行设置。3) 剪切变换当场景中物体的顶点通过试图矩阵和投影矩阵进行变换之后,位于视景之外的所有物体都将被裁减掉。如果想自己指定裁剪平面则可以使用函数:void glClipPlane( GLenum plane, const GLdouble *equation)。4)视区变换视口变换主要用于确定图形在系统窗口中的显示大小,可以使用glViewPort()函数自定义一个像素矩阵,最终的图像将被映射到这个矩阵中。另外Z坐标的编码也是在视口变换期间进行的,可以使用glDepthRange()为Z坐标定义一种编码形式。2.1.3颜色模式设置OpenGL中颜色有RGBA和颜色索引两种模式。在RGBA模式下指定颜色使用glColor*(),在颜色索引模式下指定颜色使用glIndexsifd ubv()。另外还可以指定着色模型,可以选择单调着色和平滑着色,由函数glShaeModel()指定。2.1.4光照和材质设置1)创建光源void glLightifv(GLenum light , GLenum pname, TYPE param);glLight*函数具有三个参数,第一个参数指明是设置哪一个光源的属性,第二个参数指明是设置该光源的哪一个属性,第三个参数则是指明把该属性值设置成多少。光源的属性众多,如下:(1)GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR属性。这三个属性表示了光源所发出的光的反射特性(以及颜色)。每个属性由四个值表示,分别代表了颜色的R,G,B,A值。GL_AMBIENT表示该光源所发出的光,经过非常多次的反射后,最终遗留在整个光照环境中的强度(颜色)。GL_DIFFUSE表示该光源所发出的光,照射到粗糙表面时经过漫反射,所得到的光的强度(颜色)。GL_SPECULAR表示该光源所发出的光,照射到光滑表面时经过镜面反射,所得到的光的强度(颜色)。(2)GL_POSITION属性。表示光源所在的位置。由四个值(X,Y,Z,W)表示。如果第四个值W为零,则表示该光源位于无限远处,前三个值表示了它所在的方向。这种光源称为方向性光源,通常,太阳可以近似的被认为是方向性光源。如果第四个值W不为零,则X/W,Y/W,Z/W表示了光源的位置。这种光源称为位置性光源。对于位置性光源,设置其位置与设置多边形顶点的方式相似,各种矩阵变换函数例如:glTranslate*、glRotate*等在这里也同样有效。方向性光源在计算时比位置性光源快了不少,因此,在视觉效果允许的情况下,应该尽可能的使用方向性光源。(3)GL_SPOT_DIRECTION、GL_SPOT_EXPONENT、GL_SPOT_CUTOFF属性。表示将光源作为聚光灯使用(这些属性只对位置性光源有效)。很多光源都是向四面八方发射光线,但有时候一些光源则是只向某个方向发射,比如手电筒,只向一个较小的角度发射光线。GL_SPOT_DIRECTION属性有三个值,表示一个向量,即光源发射的方向。GL_SPOT_EXPONENT属性只有一个值,表示聚光的程度,为零时表示光照范围内向各方向发射的光线强度相同,为正数时表示光照向中央集中,正对发射方向的位置受到更多光照,其它位置受到较少光照。数值越大,聚光效果就越明显。GL_SPOT_CUTOFF属性也只有一个值,表示一个角度,它是光源发射光线所覆盖角度的一半(见图2),其取值范围在0到90之间,也可以取180这个特殊值。取值为180时表示光源发射光线覆盖360度,即不使用聚光灯,向全周围发射。(4)GL_CONSTANT_ATTENUATION、GL_LINEAR_ATTENUATION、GL_QUADRATIC_ATTENUATION属性。这三个属性表示了光源所发出的光线的直线传播特性(这些属性只对位置性光源有效)。现实生活中,光线的强度随着距离的增加而减弱,OpenGL把这个减弱的趋势抽象成函数:衰减因子=1/(k1+k2*d+k3*k3*d)其中d表示距离,光线的初始强度乘以衰减因子,就得到对应距离的光线强度。k1,k2,k3分别就是GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION。通过设置这三个常数,就可以控制光线在传播过程中的减弱趋势。2) 启用和关闭光照glEnable(GL_LIGHTING); /之后使用光照模型计算顶点颜色。glDisable(GL_LIGHTING);/之后顶点颜色为当前颜色,当前颜色可以通过glColor*函数指定。3) 启动和关闭特定光源glEnable(GL_LIGHTi); glDisable(GL_LIGHTi);i为光源序号4) 设置光照模式void glLightModelifv(GLenum pname,TYPE param);在OpenGL中,光照模型包括四个部分的内容:全局环境光线(即那些充分散射,无法分清究竟来自哪个光源的光线)的强度、观察点位置是在较近位置还是在无限远处、物体正面与背面是否分别计算光照、镜面颜色(即GL_SPECULAR属性所指定的颜色)的计算是否从其它光照计算中分离出来,并在纹理操作以后在进行应用。以上四方面的内容都通过同一个函数glLightModel*来进行设置。该函数有两个参数,第一个表示要设置的项目,第二个参数表示要设置成的值。GL_LIGHT_MODEL_AMBIENT表示全局环境光线强度,由四个值组成。GL_LIGHT_MODEL_LOCAL_VIEWER表示是否在近处观看,若是则设置为GL_TRUE,否则(即在无限远处观看)设置为GL_FALSE。GL_LIGHT_MODEL_TWO_SIDE表示是否执行双面光照计算。如果设置为GL_TRUE,则OpenGL不仅将根据法线向量计算正面的光照,也会将法线向量反转并计算背面的光照。GL_LIGHT_MODEL_COLOR_CONTROL表示颜色计算方式。如果设置为GL_SINGLE_COLOR,表示按通常顺序操作,先计算光照,再计算纹理。如果设置为GL_SEPARATE_SPECULAR_COLOR,表示将GL_SPECULAR属性分离出来,先计算光照的其它部分,待纹理操作完成后再计算GL_SPECULAR。后者通常可以使画面效果更为逼真。5) 设置材质属性材质与光源相似,也需要设置众多的属性。不同的是,光源是通过glLight*函数来设置的,而材质则是通过glMaterial*函数来设置的。glMaterial*函数有三个参数。第一个参数表示指定哪一面的属性。可以是GL_FRONT、GL_BACK或者GL_FRONT_AND_BACK。分别表示设置“正面”“背面”的材质,或者两面同时设置。(关于“正面”“背面”的内容需要参看前些课程的内容)第二、第三个参数与glLight*函数的第二、三个参数作用类似。下面分别说明glMaterial*函数可以指定的材质属性。(1)GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR属性。这三个属性与光源的三个对应属性类似,每一属性都由四个值组成。GL_AMBIENT表示各种光线照射到该材质上,经过很多次反射后最终遗留在环境中的光线强度(颜色)。GL_DIFFUSE表示光线照射到该材质上,经过漫反射后形成的光线强度(颜色)。GL_SPECULAR表示光线照射到该材质上,经过镜面反射后形成的光线强度(颜色)。通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,可以达到比较真实的效果。使用GL_AMBIENT_AND_DIFFUSE可以同时设置GL_AMBIENT和GL_DIFFUSE属性。(2)GL_SHININESS属性。该属性只有一个值,称为“镜面指数”,取值范围是0到128。该值越小,表示材质越粗糙,点光源发射的光线照射到上面,也可以产生较大的亮点。该值越大,表示材质越类似于镜面,光源照射到上面后,产生较小的亮点。(3)GL_EMISSION属性。该属性由四个值组成,表示一种颜色。OpenGL认为该材质本身就微微的向外发射光线,以至于眼睛感觉到它有这样的颜色,但这光线又比较微弱,以至于不会影响到其它物体的颜色。(4)GL_COLOR_INDEXES属性。该属性仅在颜色索引模式下使用,由于颜色索引模式下的光照比RGBA模式要复杂,并且使用范围较小,这里不做讨论。6)设置顶点法线void glNormal3bdfis( GLbyte nx,GLbyte ny,GLbyte nz);void glNormal3bdfisv(const GLshort *v);2.1.5纹理映射OpenGL使用图像表示纹理,二维纹理用得最多。纹理被“贴到”物体上的过程被称为纹理映射。纹理有自己的单位坐标空间,称为纹理空间,在绘图时需要为每个顶点指定纹理坐标或者指定映射关系。纹理贴图的大致操作步骤有:图像准备:既可以在程序中生成图像,也可以读取图像文件。生成纹理号:适用于多个纹理反复切换时,一个纹理时不需要。设置当前纹理:切换纹理,又称为纹理绑定。定义纹理:指定当前纹理的图象。设置纹理参数:指定纹理的重叠方式和插值方式。设置纹理环境参数:决定怎样使用纹理颜色,例如是否与光照色合成。启动纹理功能,绘制场景,给出顶点的纹理坐标和几何坐标退出前删除纹理。2.1.6图形增强这里使用的技术主要包括混合、抗锯齿、雾和多边形偏移等技术。1) 混合(Blending)混合将一个碎片的R、G、B、A值与保存在帧缓冲对应位置的值结合起来。混合只在RGBA模式下进行,基于碎片及现存对应象素的alpha值;同时也基于RGB值。可以使用如下一些函数控制混合:void glBlendFunc(GLenum sfactor,GLenum dfactor );void glBlendFuncSeparate(GLenum srcRGB,GLenum destRGB,GLenum srcAlpha,GLenum destAlpha);void glBlendColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf);void glBlendEquation(GLenum mode);void glBlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha);2)抗锯齿(Anti-aliasing)抗锯齿用于减少物体边缘的锯齿状,使物体边缘看起来更平滑。在OpenGL如果需要使用抗锯齿则需要使用函数glHint()来进行,函数形式如下:void glHint(GLeum target,GLenum hint);3)雾(fog)通过添加雾可以使一些场景变得更逼真,雾可以用于模拟模糊、薄雾、烟和污染等。要使用雾可以直接在glEnable()中使用参数GL_FOG,并使用glFog*()函数设置用于控制雾浓度的方程式。这些函数的原型如下:void glFogif(GLenum pname,GLfloat param);void glFogifv(GLenum pname,const GLint * params);还可以为每个顶点指定雾坐标:void glFogCoordfd(TYPE z);void glFogCoordfdv(const TYPE* z);2.1.7双缓存动画绝大多数OpenGL实现提供了双缓冲,即两个完整的颜色缓冲区。当一个缓冲区先试试另外一个缓冲区正在进行绘图。要在OpenGL中实现双缓冲首先需要设置双缓冲器显示模式:glutInitDisplayMode(GLUT_RGB |GLUT_DOUBLE);/GLUT_DOUBLE为双缓冲然后再需要的时候调换缓冲:glutSwapBuffers();2.2设计关键步骤2.2.1 三维建模3D Studio 是一套用于制作三维动画的应用软件, 其三维建模功能十分强大, 并且生成的3DS 文件是一种非常普遍的数据格式, 3ds文件是基于“块”存储的,这些块描述了诸如场景数据,每个编辑窗口(Viewport)的状态,材质,网格数据(我们最关心的就是这个)等等数据。每个块都包含一个ID和块长度的块头,如果你对该块的信息不感兴趣的话,可以直接跳过该块读取下一个块。跟许多文件格式类似,为了读取的方便,3ds文件中数据的存储方式是Intel式的,也就是说是高位放在后面,低位放在前面。以下是一个描述块组织方式的部分图表:MAIN3DS (0x4D4D) |(注意,此处并不是紧接着EDIT块的,还有一些描述文件版本信息的块) +-EDIT3DS (0x3D3D) | | | +-EDIT_MATERIAL (0xAFFF) | | | | | +-MAT_NAME01 (0xA000) (See mli Doc) | | | +-EDIT_CONFIG1 (0x0100) | +-EDIT_CONFIG2 (0x3E3D) | +-EDIT_VIEW_P1 (0x7012) | | | | | +-TOP (0x0001) | | +-BOTTOM (0x0002) | | +-LEFT (0x0003) | | +-RIGHT (0x0004) | | +-FRONT (0x0005) | | +-BACK (0x0006) | | +-USER (0x0007) | | +-CAMERA (0xFFFF) | | +-LIGHT (0x0009) | | +-DISABLED (0x0010) | | +-BOGUS (0x0011) | | | +-EDIT_VIEW_P2 (0x7011) | | | | | +-TOP (0x0001) | | +-BOTTOM (0x0002)了解了它的结构够后就可以利用OpenGL 编写相关程序能读取3DS 文件, 把3DS 文件转换成OpenGL 可以识别的文件, 以便于实现对模型的控制。用它建模可以大大缩短建模时间而且提高建模效率。我们建立的模型如图所示:2.2.2 VC+结合MFC 读取3DS 文件下面介绍转换的过程:( 1) 将块的3DS 格式的内容读入块结构中int C3dsReader:Read3DSChunk(FILEF fp, Chunk3DS& chunk)读入字符串, 如果字符串的长度大于缓冲区, 则截去多余的部分( 2) 读入3DS 文件中定义的颜色int C3dsReader:ReadColor(FILEF fp, float& red, float& green, float& blue)( 3) 读入3DS 文件中模型的顶点int C3dsReader:ReadPointArray (CTriObjectF newchild, long fileSize, FILE Ffp)( 4) 读入3DS 文件中多边形文件int C3dsReader:ReadFaceArray (CTriObjectF newchild, long unsigned fileSize, FILEF fp)( 5) 读入3DS 对象所用的材质int C3dsReader:ReadMeshMatGroup(CTriObjectF newchild, MaterialDictF )( 6) 读入3DS 文件中对象数据int C3dsReader:ReadTriObject (MaterialDictF matdict, long fileSize, FILEF fp, long triStart, long triSize,charF groupName)( 7) 读入3DS 文件int C3dsReader:Read3DSFile(long fileSize, long fileStart, long fileLen, FILEF fp)2.2.3 编写相关的CTriObject类进行绘制CTriObject:CTriObject()x = y = z = nx = ny = nz = NULL;matfaces = faces = NULL;materials = NULL;numvertices = 0;numnormals = 0;numfaces = 0;nummatfacesapplied = 0;i = 0;nummaterials=0;pivot0 = 0.0f;pivot1 = 0.0f;pivot2 = 0.0f;pivotrot0 = 0.0f;pivotrot1 = 0.0f;pivotrot2 = 0.0f;pivotrot3 = 0.0f;normalapplied = FALSE;materialsapplied = FALSE;CTriObject:CTriObject()delete x;delete y;delete z;delete nx;delete ny;delete nz;delete faces;delete matfaces;delete materials;void CTriObject:applyNormals()if (numfaces = 0) return;delete nx;delete ny;delete nz;nx = new floatnumfaces/3;ny = new floatnumfaces/3;nz = new floatnumfaces/3;if( nx=NULL | ny=NULL | nz=NULL )delete nx;delete ny;delete nz;normalapplied = FALSE;return;float normal3;for ( int i=0 ; inumfaces/3 ; i+ )/get to workCalcNormal(3*i, normal);ReduceToUnit(normal);nxi = normal0;nyi = normal1;nzi = normal2;normalapplied = TRUE;void CTriObject:CalcNormal(int entry, float out 3 )float v13,v23;/ 根据空间三个点计算两个矢量值v10 = x facesentry - x facesentry+1 ;v11 = y facesentry - y facesentry+1 ;v12 = z facesentry - z facesentry+1 ;v20 = x facesentry+1 - x facesentry+2 ;v21 = y facesentry+1 - y facesentry+2 ;v22 = z facesentry+1 - z facesentry+2 ;/ 计算法向矢量out0 = v11*v22 - v12*v21;out1 = v12*v20 - v10*v22;out2 = v10*v21 - v11*v20;void CTriObject:ReduceToUnit(float vector 3 )float length;/ 计算矢量的长度length = (float)sqrt(vector0*vector0) + (vector1*vector1) +(vector2*vector2);if(length = 0.0f)length = 1.0f;/ 单位化矢量vector0 /= length;vector1 /= length;vector2 /= length;void CTriObject:drawGL()if (normalapplied)int j;glBegin(GL_TRIANGLES);for (i=0; i numfaces/3; i+)j = 3*i;if(materialsapplied) glColor4f( materialsmatfacesi.diffuseColor0, materialsmatfacesi.diffuseColor1, materialsmatfacesi.diffuseColor2, 1/materialsmatfacesi.transparency );else glColor3f( 0.0f, 0.0f, 1.0f );:glNormal3f( nxi, nyi, nzi);:glVertex3f( xfacesj , yfacesj , zfacesj);:glVertex3f( xfacesj+1, yfacesj+1, zfacesj+1);:glVertex3f( xfacesj+2, yfacesj+2, zfacesj+2);glEnd();elseglBegin(GL_TRIANGLES);for (i=0; i numfaces; i+=3)if(materialsapplied) glColor3f( materialsmatfacesi/3.diffuseColor0, materialsmatfacesi/3.diffuseColor1, materialsmatfacesi/3.diffuseColor2 );else glColor3f( 0.0f, 0.0f, 1.0f );glVertex3f( xfacesi , yfacesi , zfacesi);glVertex3f( xfacesi+1, yfacesi+1, zfacesi+1);glVertex3f( xfacesi+2, yfacesi+2, zfacesi+2);glEnd();glPopMatrix();int CTriObject:addMaterial(tMaterial * _material)tMaterial * tmp;nummaterials+;if (nummaterials=1)materials = new tMaterialnummaterials;if (materials = NULL)nummaterials = 0;materialsapplied = FALSE;return -1;elsetmp = materials;materials = new tMaterialnummaterials;if (materials = NULL)delete tmp;nummaterials = 0;materialsapplied = FALSE;return -1;for (i=0; iambientColor0;materialsnummaterials-1.ambientColor1=_material-ambientColor1;materialsnummaterials-1.ambientColor2=_material-ambientColor2;materialsnummaterials-1.diffuseColor0=_material-diffuseColor0;materialsnummaterials-1.diffuseColor1=_material-diffuseColor1;materialsnummaterials-1.diffuseColor2=_material-diffuseColor2;materialsnummaterials-1.specularColor0=_material-specularColor0;materialsnummaterials-1.specularColor1=_material-specularColor1;materialsnummaterials-1.specularColor2=_material-specularColor2;materialsnummaterials-1.emissiveColor0=_material-emissiveColor0;materialsnummaterials-1.emissiveColor1=_material-emissiveColor1;materialsnummaterials-1.emissiveColor2=_material-emissiveColor2;materialsnummaterials-1.shininess = _material-shininess;materialsnummaterials-1.transparency = _material-transparency;materialsapplied = TRUE;return (nummaterials -1); 3设计的成果程序一边读取文件,一边绘图,同时运行DMy3DSLoaderView类中的OnDraw(初始化)调用RenderScene进行场景绘制与渲染,确定坐标轴以及画图后进入CTriObject类,调用CTriObject类中的drawGL开始绘图,在画图过程中引用了参数face(多边形)和materials(材质)。参数materials,存在于C3dsReader类中,通过ReadMatEntry()(读入3DS文件材质定义,并添加进材质库中)函数来赋值。ReadMatEntry调用了ReadColor函数与ReadPercentage函数,前者读取材质的环境反射光强(RGB),漫反射光强(RGB)和镜面反射光强(RGB);后者读取了材质镜面系数(百分比)和材质透明度(百分比)。因此,可以绘出从3DS文件中解析出来的图像。最后成果如图所示:4实现中遇到的问题,及解决方案。首先,对于OpenGL概念的理解,前期对于OpenGL是何物感到十分困惑,经过深入的学习,以及对相关资料的查阅,我们知道它类似于一个VC+的函数库,可以调用它进行三维图像的创作。其次,是对于三维建模的困难,我们知道可以直接用OpenGL创建三维模型,但是工作量繁琐,而且需要相关的建模知识进行支撑,周期较长。经过选取,以及老师的建议,我们最后决定用3ds max进行三维建模,其优点在于建模简单,直观,周期较短。接着,我们面临的问题在于,如何将所建模型的3ds文件变成OpenGL可以识别的数据,经过资料的查阅,加上对VC+的学习,我们编写了相关的导入类来实现,具体在程序中体现。穿插在其中的是VC+调试的相关问题,根据提示以及学长的帮助,经过反复修改,大部分得以解决。5主要收获通过这个项目的流程,我们每一位参与的同学都收获颇丰。我们几乎从零开始,不断学习,虚心请教,克服了很多的困难,最后终于基本完成了项目。我们利用3DS MAX 进行三维建模, 通过VC编程调用所得的三维数据模型, 大大的提高了开发的效率。OpenGL作为一个优秀的图形接口,有很大的发展空间,在跨平台和科学计算方面有着重大的优势。经过这段时间,我们提高了理论结合实践的能力,解决问题的能力,和团队协作的能力。袁节膅薂羄肅蒃薁蚃芀荿薀螆肃芅蕿袈芈膁蚈羀肁蒀蚇蚀袄莆蚇螂肀莂蚆羅袂芈蚅蚄膈膄蚄螇羁蒂蚃衿膆莈蚂羁罿芄螁蚁膄膀螁螃羇葿螀袅膃蒅蝿肈羆莁螈螇芁芇莄袀肄膃莄羂艿蒂莃蚂肂莈蒂螄芈芄蒁袆肀膀蒀罿袃薈葿螈聿蒄葿袁羁莀蒈羃膇芆蒇蚃羀膂蒆螅膅蒁薅袇羈莇薄罿膄芃薃虿羆艿薃袁节膅薂羄肅蒃薁蚃芀荿薀螆肃芅蕿袈芈膁蚈羀肁蒀蚇蚀袄莆蚇螂肀莂蚆羅袂芈蚅蚄膈膄蚄螇羁蒂蚃衿膆莈蚂羁罿芄螁蚁膄膀螁螃羇葿螀袅膃蒅蝿肈羆莁螈螇芁芇莄袀肄膃莄羂艿蒂莃蚂肂莈蒂螄芈芄蒁袆肀膀蒀罿袃薈葿螈聿蒄葿袁羁莀蒈羃膇芆蒇蚃羀膂蒆螅膅蒁薅袇羈莇袄芈蒇袇螀芇蕿蚀聿芆艿蒃肅芅蒁螈羁芄薃薁袆芃芃螆螂芃莅蕿肁节蒈螅羇莁薀薈袃莀艿螃蝿荿莂薆膈莈薄袁肄莇蚆蚄羀莇莆袀袆羃蒈蚂螂羂薁袈肀肁芀蚁羆肁莃袆袂肀薅虿袈聿蚇蒂膇肈莇螇肃肇葿薀罿肆薂螆袅肅芁薈螁膅莃螄聿膄蒆薇羅膃蚈螂羁膂莈蚅袇膁蒀袀螃膀薂蚃肂腿节衿羈腿莄蚂袄芈蒇袇螀芇蕿蚀聿芆艿蒃肅芅蒁螈羁芄薃薁袆芃芃螆螂芃莅蕿肁节蒈螅羇莁薀薈袃莀艿螃蝿荿莂薆膈莈薄袁肄莇蚆蚄羀莇莆袀袆羃蒈蚂螂羂薁袈肀肁芀蚁羆肁莃袆袂肀薅虿袈聿蚇蒂膇肈莇螇肃肇葿薀罿肆薂螆袅肅芁薈螁膅莃螄聿膄蒆薇羅膃蚈螂羁膂莈蚅袇膁蒀袀螃膀薂蚃肂腿节衿羈腿莄蚂袄芈蒇袇螀芇蕿蚀聿芆艿蒃肅芅蒁螈羁芄薃薁袆芃芃螆螂芃莅蕿肁节蒈螅羇莁薀薈袃莀艿螃蝿荿莂薆膈莈薄袁肄莇蚆蚄羀莇莆袀袆羃蒈蚂螂羂薁袈肀肁芀蚁羆肁莃袆袂肀薅虿袈聿蚇蒂膇肈莇螇肃肇葿薀罿肆薂螆袅肅芁薈螁膅莃螄聿膄蒆薇羅膃蚈螂羁膂莈蚅袇膁蒀袀螃膀薂蚃肂腿节衿羈腿莄蚂袄芈蒇袇螀芇蕿蚀聿芆艿蒃肅芅蒁螈羁芄薃薁袆芃芃螆螂芃莅蕿肁节蒈螅羇莁薀薈袃莀艿螃蝿荿莂薆膈莈薄袁肄莇蚆蚄羀莇莆袀袆羃蒈蚂螂羂薁袈肀肁芀蚁羆肁莃袆袂肀薅虿袈聿蚇蒂膇肈莇螇肃肇葿薀罿肆薂螆袅肅芁薈螁膅莃螄聿膄蒆薇羅膃蚈螂羁膂莈蚅袇膁蒀袀螃膀薂蚃肂腿节衿羈腿莄蚂袄芈蒇袇螀芇蕿蚀聿芆艿蒃肅芅蒁螈羁芄薃薁袆芃芃螆螂芃莅蕿肁节蒈螅羇莁薀薈袃莀艿螃蝿荿莂薆膈莈薄袁肄莇蚆蚄羀莇莆袀袆羃蒈蚂螂羂薁袈肀肁芀蚁羆肁莃袆袂肀薅虿袈聿蚇蒂膇肈莇螇肃肇葿薀罿肆薂螆袅肅芁薈螁膅莃螄聿膄蒆薇羅膃蚈螂羁膂莈蚅袇膁蒀袀螃膀薂蚃肂腿节衿羈腿莄蚂袄芈蒇袇螀芇蕿蚀聿芆艿蒃肅芅蒁螈羁芄薃薁
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年跨境电商物流承运合作协议范本
- 2025版瓷砖行业电子商务平台建设与运营合同
- 2025年度特殊区域拆迁补偿协议范本
- 2025年度环保设备安装与节能审计合同
- 2025吊装合同协议:电力设备吊装与维护合同
- 2025短期国际商务翻译雇工劳动合同
- 2025年度食用油加工设备租赁及维护服务合同
- 2025年度防盗门产品研发与安全性能提升合同
- 2025年度特色小吃店试用期厨师聘用合同
- 2025版国有企业员工外包与绩效评估一体化协议
- 储能消防培训课件
- 混凝土浇筑作业平台承重验算
- JG/T 220-2016铜铝复合柱翼型散热器
- 美乐家退会员终止协议书
- 情侣间恋爱合同协议书
- 会务服务技能试题及答案
- 城市轨道交通施工机械设备管理措施
- 《2023 AHA心肺复苏与心血管急救指南》解读
- 2025年有限空间作业安全考试题库:有限空间作业安全教育与培训试题
- 胰岛素皮下注射团体标准解读
- 宁德时代shl测评题库
评论
0/150
提交评论