使用OpenGL来开发模型编辑器_第1页
使用OpenGL来开发模型编辑器_第2页
使用OpenGL来开发模型编辑器_第3页
使用OpenGL来开发模型编辑器_第4页
使用OpenGL来开发模型编辑器_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

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

文档简介

1、实用文案1前言:在计算机图形图像处理中,由于OpenGL库带来的便利,使得其取得了越来越广泛的应用.本文旨在通过一个小的应用实例,介绍了OpenGL的基本编程思路,希望这些知识和经验能有助于OpenGL的推广。2OpenGL简介:OpenGL(OpenGraphicsLibrary)是独立于操作系统和硬件环境的三维图形软件库由于其开放性和高度的可重用性,目前已成为业界标准.很多优秀的软件都是以它为基础开发出来的,象著名的产品有动画制作软件3DMAX,SoftImage,VR软件和GIS软件等等。OpenGL认可开发人员对真实世界中的二维图形和三维几何物体的描述,而且将这些几何形体绘制到三维图形

2、加速卡的帧缓存中,可用一个简单的工作流程图来描述OpenGL的工作原理,如图2所示。图像像素像素操作光栅化评价器顶点操作几何物体顶点显示列表纹理存储器基本操作帧缓存器标准文档实用文案图2OpenGL工作流程2.1 OpenGL的主要功能有:1)几何建模:在OpenGL中提供了绘制点,线多边形等基本形体的函数,还提供了绘制复杂三维曲线,曲面(如Bezier,Nurbs等)和三维形体(如球,锥体和多面体等)的函数.由于OpenGL是以顶点为图元,由点构成线,由线及其拓扑结构构成多边形.所以应用这些建模函数,可构造出几乎所有的三维模型。2)坐标变换:包括取景变换,模型变换,投影变换和视区变换。3)颜

3、色模式设置:RGBA模式和颜色索引模式。标准文档实用文案4)光照和材质设置:可设置四种光,即辐射光,环境光,镜面光和漫反射光.材质用模型表面的反射特性表示。5)图像功能:提供像素拷贝和读写操作的函数,还提供了反走样,融合和雾化等,以增强图像效果6)纹理映射:OpenGL的纹理映射功能可十分逼真地再现物体表面的细节。7)实时动画:利用OpenGL的双缓存(DoubleBuffer)技术可获得平滑逼真的动画效果。8)交互技术:方便的三维图形交互接口(选择才合取,反馈),可进行人机交互操作。2.2 Win32下OpenGL的运行机制:由于OpenGL的作用机制是客户(Client)服务器(Serve

4、r)机制,由客户(用OpenGL绘制图形的应用程序)向服务器(OpenGL内核)发送OpenGL命令,服务器则负责解释这些命令。在多数情况下,客户和服务器在同一机器上运行,当然,也可以在网络环境下使用,所以OpenGL具有网络透明性,与在Win32下的图形设备接口(GDI)把图形函数库封装在动态的连接库GDI32.DLL内一样,OpenGL的图形库也被封装在一个动态连接库标准文档实用文案opengl32.dll内。从客户应用程序发布的对OpenGL函数的调用首先被opengl32.dll处理,然后传送给服务器后,被Winsrv.dll进一步处理,再传给Win32设备驱动接口(DDI),最后把处

5、理过的图形命令送给视频显示驱动程序。图2.2显示了整个处理过程。客户应用程序OpenGLDLLWin32.DDI视频驱动程序OpenGL命令图2.2OpenGL在Windows环境下的运行机制。2.3OpenGL函数及结构下面以Microsoft的Windows95(98)为支撑平台,说明OpenGL函数及结构。1) OpenGL核心函数标准文档实用文案OpenGL核心函数有100多个,每个函数以gl开头。这些函数是最基本的,可运行于任何的工作平台。可用这些函数创建二维和三维几何形体,设置视点,建立视觉体,设置颜色及材质,建立灯光,进行纹理映射等。2) OpenGL实用库函数OpenGL实用库

6、函数以glu开头。这些函数是基于核心函数的,提供对辅助函数特性的支持,并且执行了核心的OpenGL交互,因而是比核心函数更高一层的函数,也更具有通用性。3) 辅助库函数辅助库函数有31个,这些函数以aux开头。主要是帮助初学者尽快进入编程而做简单练习之用。4) Windows专用函数这些函数以wgl开头,是用于连接OpenGL和Windows窗口系统的。用它们可以管理着色描述表(RenderContext)及显示列表(DisplayList),扩展功能,管理字体位图等。5) Win32API函数共6个函数,用于处理像素格式及缓存。ChoosePixelFormatDescribePixelFo

7、rmat6) )OpenGL结构共有4个,列举如下:GLYPHMETRICSFLOATLAYERPLANEDESCRIPTORPIXELFORMATDESCRIPTORPOINTFLOAT标准文档实用文案7) VC环境下的实现背景:对三维物体进行可视化编辑,即增删改点,面操作.模型为用VRML表示的一个人头像.流程:数据准备a初始化绘制环境a模型的绘制a交互操作,点和面的编辑a导出数据7.1 数据准备1)从指定的VRML文件中手工挑选出组成各个特征的点数据及面数据,处理后存为input.dat文本文件,点由三维坐标表示,面则统一为三角型面片,由三个点索引组成,格式如下:#Vertex/点数据,

8、点的三维坐标;#skin/特征名称;0.0000-31.9007487.6600点坐标31.0000-28.3430470.464063.0000-29.9017455.9880标准文档实用文案#facet/面数据,相关点的索弓I;#skin/特征名称;0116/点的索弓I;11516161513其中特征分为(skin,tongue,teeth,ear,lip,eye,mouth,nose,eyebrow);2)从input.dat文件中读入点和面数据,存入程序结构中(PointNode,FaceNode)同时建立图元(点和面)的显示列表,为绘制模型做好准备。标准文档实用文案typedefst

9、ructpt_nodecharpZT;/点的状态,(V'-有效;'I',为后续编辑作准备;doublept3;/点的三维坐标;PointNode;typedefstructfe_nodecharfZT;/面的状态('V'-有效;'I'-无效)intPt1Index;面片中第一个Vertex的点索弓I;标准文档实用文案intPt2Index;/面片中第二个Vertex的点索弓I;intPt3Index;/面片中第三个Vertex的点索弓I;voidCDisplayView:DrawTriangle(intFaceNode;&i,GL

10、doublept1,GLdoublept2,GLdoublept3)首先计算该面的法向量;/创建三角行面片的显示列表;CalculateNormal(pt1,pt2,pt3,dNormal);glNewList(i,GL_COMPILE);/建立第i个显示列表;glBegin(GL_TRIANGLES);标准文档实用文案glNormal3dv(dNormal);/指定该面的法向量为dNormal;glVertex3dv(pt1);glVertex3dv(pt2);glVertex3dv(pt3);glEnd();glEndList();i+;voidCDisplayView:DrawPoint

11、(int&n,GLdoublept)/创建点的显示列表;标准文档实用文案glNewList(n,GL_COMPILE);glBegin(GL_POINTS);glVertex3dv(pt);glEnd();glEndList();n+;7.2 初始化绘制环境1)填充PIXELFORMATDESCRIPTOR结构。PIXELFORMATDESCRIPTORpixelDesc=;按需要填充适当的值;标准文档实用文案2)设置像素格式m_GLPixelIndex=ChoosePixelFormat(hDC,&pixelDesc);确定设备上下文(DC)所支持的像素格式中,与给定像素格式

12、描述符最为匹配的像素格式索引值;if(m_GLPixelIndex=0)MessageBox("ChoosePixelFormatfailed!");/将设备上下文(DC)中的像returnFALSE;/执行失败!if(!SetPixelFormat(hDC,m_GLPixelIndex,&pixelDesc)标准文档实用文案素格式returnFALSE;/执行失败!设置为索引值m_GLPixelIndex所指定的格式;3)创建着色描述表HWNDhWnd=GetSafeHwnd();/得到Windows窗口的窗口句柄HDChDC=:GetDC(hWnd);得到设备上

13、下文(DC)句柄;if(MyFunction_SetWindowPixelFormat(hDC)=FALSE)/测试设置像素格式是否正确;returnFALSE;/测试失败;hglrc=wglCreateContext(hDC);/建立hDC所关联的OpenGL绘图上下文(RC);if(hglrc=NULL)标准文档实用文案returnFALSE;/创建失败;if(wglMakeCurrent(hDC,hglrc)=FALSE)将一个指定的绘图描述表变为正在调用线程returnFALSE;/失败;的当前绘图描述表。4)对灯光,材质等环境相关参数进行初始化intCDisplayView:OnCr

14、eate(LPCREATESTRUCTlpCreateStruct)if(CView:OnCreate(lpCreateStruct)=-1)return-1;标准文档实用文案glPolygonMode(GL_FRONT,GL_FILL);多边型的正面为填充模式;glPolygonMode(GL_BACK,GL_FILL);多边形的背面为填充模式;glShadeModel(GL_SMOOTH);/明暗模式为平滑型;glEnable(GL_DEPTH_TEST);使能深度消隐;glEnable(GL_NORMALIZE);使能法向量单位化;glFrontFace(GL_CW);/设置朝向正面的多

15、边型的顶点环绕方向为顺时针方向;GLfloatambientProperties口=0.15f,0.15f,0.15f,1.0f;/设置环境光分量;GLfloatdiffuseProperties口=0.7f,0.7f,0.7f,1.0f;/设置漫反射光分量;标准文档实用文案GLfloatspecularProperties=0.7f,0.7f,0.7f,1.0f;/设置镜面反射光分量;GLfloatposition=1.0,1.0,-5.0,0.0;/设置光源位置;glClearDepth(1.0f);设置深度缓冲的值为1;/把各光分量的值赋给光源0;glLightfv(GL_LIGHT0,

16、GL_AMBIENT,ambientProperties);glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseProperties);glLightfv(GL_LIGHT0,GL_SPECULAR,specularProperties);glLightfv(GL_LIGHT0,GL_POSITION,position);标准文档实用文案glEnable(GL_LIGHTING);使能照明效果;glEnable(GL_LIGHT0);使能灯光0;)5) 场景布置为了将物体放置在场景中合适的位置,需要使用一些OpenGL的变换操作。OpenGL变换有基本变换和投影变换两种

17、,基本变换是对三维物体进行平移、旋转、缩放等。投影变换则把物体从三维投影到二维。视区则决定物体的投影图像在显示设备中的尺寸和位置。OpenGL中的多数变换均对应于相应的变换矩阵,可以说就是实现将物体的各个顶点通过各种变换矩阵的作用映射到屏幕的过程。根据变化的类型,分为三种矩阵模式,GL_MODELVIEW对应于基本变换,GL_PROJECTION对应于投影变换,GL_TEXTURE对应于纹理矩阵类型。具体应用见小节1,小节2。1 .对几何造型初始化voidCDisplayView:InitGeometry()标准文档实用文案/x,y,z方向的默认旋转角度;m_xRotate=0.0f;m_yR

18、otate=0.0f;m_zRotate=0.0f;/x,y,z方向默认的平移大小;m_xTrans=0.0f;m_yTrans=-0.5f;m_zTrans=-3.5f;标准文档实用文案/x,y,z方向默认的缩放大小;m_xScaling=1.0f;m_yScaling=1.0f;m_zScaling=1.0f;2.设置透视投影变换和视区voidDisplayView:OnSize(UINTnType,intcx,intcy)CView二OnSize(nType,cx,cy);标准文档实用文案GLintw=cx;GLinth=cy;glViewport(0,0,w,h);/设置视区;glMa

19、trixMode(GL_PROJECTION);表明下面的矩阵操作是关于投影变换矩阵的;glLoadIdentity();/单位阵作为当前矩阵;gluPerspective(60.0,h/w,1.0f,128.0);/设置透视投影矩阵;glMatrixMode(GL_MODELVIEW);/表明下面的矩阵操作是关于模型-取景变换矩阵的标准文档实用文案glLoadIdentity();/同上;glPushMatrix();/把当前的变换矩阵压栈;glTranslatef(m_xTrans,m_yTrans,m_zTrans);/x,y,z方向按给定实参值进行平移;glRotatef(m_xRot

20、ate,1.0f,0.0f,0.0f);/x轴旋转m_xRotate度;glRotatef(m_yRotate,0.0f,1.0f,0.0f);/y轴旋转m_yRotate度;glRotatef(m_zRotate,0.0f,0.0f,1.0f);/z轴旋转m_zRotate度;glScalef(m_xScaling,m_yScaling,m_zScaling);/x,y,z方向按给定实参值进行缩放;glPopMatrix();原来的变换矩阵出栈;标准文档实用文案glDrawBuffer(GL_BACK);/绘制操作在后台缓存;3.3 模型的绘制由于侧重模型的编辑操作,在绘制时并未计算顶点的法

21、向量,仅仅求出了各个面片的法向量。voidCDisplayView:OnPaint()CPaintDCdc(this);标准文档实用文案glClearC010r(0.0f,0.5f,0.5f,1.0f);将显示窗口颜色设置为蓝绿色;深度g1C1ear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);用该色清除颜色,缓存;DrawScene();绘制模型,即调用显示列表;SwapBuffers(dc.m_ps.hdc);当前设备的前台缓存和后台缓存交换;voidCDisplayView:Drawscene()标准文档实用文案for(inti=0;i<Tot

22、alNum;i+)glCallList(i);/调用显示列表,该数据已在2.4.1节准备完毕;)3.4 点和面的编辑为了能够编辑点和面,必须首先在显示窗口中获取相关数据,即拾取到相应的点和面,然后才能对其进行正确的编辑操作。一般的绘图程序通常只是在屏幕上绘制场景中物体的二维或三维静态图像,用户不能对其中的图形进行有效的交互。为了方便人机交互,往往需要通过鼠标等设备来选定观察体积中的某个或某几个图元,以便对其进行进一步的操作。这种在选择模式下确定选中物体的操作称为拾取操作。选择模式下的拾取操作通过将一个特殊的拾取矩阵与投影矩阵相乘,从而将绘图操作限制在视口中鼠标附近的一个小区域内。通过鼠标点击来激活选择模式,这样鼠标附近绘制的物体就会被选中,即确定了鼠标附近所绘制的物体名称。3.5 取数据实现如下:标准文档实用文案voidCDisplayView二OnLButtonDown(UINTnFlags,CPointpoint)得到当前的视口;/拾取操作有鼠标的LBUTTONDOWN消息触发;glGetIntegerv(GL_VIEWPORT,viewport);/w=viewport2;h=viewport3;glSelectBuffer(512,buf);指定返回的选中纪录所使用的数组;glRenderMode(GL_SELECT);进入选择模式;标准文档实用文案glI

温馨提示

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

评论

0/150

提交评论