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

下载本文档

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

文档简介

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

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

3、构成多边形 .所以应用这些建模函 数,可构造出几乎所有的三维模型。2 ) 坐标变换:包括取景变换,模型变换,投影变换和视区变换。3 ) 颜色模式设置: RGBA 模式和颜色索引模式。4 ) 光照和材质设置:可设置四种光,即辐射光,环境光,镜面光和漫反射光.材质用模型表面的反射特性表示。5 ) 图像功能:提供像素拷贝和读写操作的函数,还提供了反走样,融合和雾化等,以增强图像效果6 ) 纹理映射: OpenGL 的纹理映射功能可十分逼真地再现物体表面的细节。7) 实时动画:利用 OpenGL 的双缓存( Double Buffer )技术可获得平滑逼真的动画 效果。8) 交互技术:方便的三维图形交

4、互接口 (选择,拾取 ,反馈 ),可进行人机交互操作。2.2 Win32 下 OpenGL 的运行机制 :由于 OpenGL 的作用机制是客户 (Client )服务器( Server )机制,由客户 (用 OpenGL 绘制图形的应用程序)向服务器( OpenGL 内核)发送 OpenGL 命令,服务器则负责解释 这些命令。在多数情况下,客户和服务器在同一机器上运行,当然,也可以在网络环境下使 用,所以 OpenGL 具有网络透明性,与在 Win32 下的图形设备接口( GDI )把图形函数库 封装在动态的连接库 GDI32.DLL 内一样, OpenGL 的图形库也被封装在一个动态连接库

5、opengl32.dll 内。从客户应用程序发布的对 OpenGL 函数的调用首先被 opengl32.dll 处理, 然后传送给服务器后,被 Winsrv.dll 进一步处理,再传给 Win32 设备驱动接口( DDI ),最 后把处理过的图形命令送给视频显示驱动程序。图 2.2 显示了整个处理过程。客户应用程序OpenGL DLL Win32.DDI视频驱动程序 OpenGL 命令图 2.2 OpenGL 在 Windows 环境下的运行机制。 2.3 OpenGL 函数及结构 下面以 Microsoft 的 Windows95(98) 为支撑平台,说明 OpenGL 函数及结构。1 )

6、OpenGL 核心函数OpenGL 核心函数有 100 多个,每个函数以 gl 开头。这些函数是最基本的,可运行于 任何的工作平台。可用这些函数创建二维和三维几何形体,设置视点,建立视觉体,设置颜 色及材质,建立灯光,进行纹理映射等。2 ) OpenGL 实用库函数 OpenGL 实用库函数以 glu 开头。 这些函数是基于核心函数 的,提供对辅助函数特性的支持,并且执行了核心的 OpenGL 交互,因而是比核心函数更 高一层的函数,也更具有通用性。3 ) 辅助库函数 辅助库函数有 31 个,这些函数以 aux 开头。主要是帮助初学者尽快 进入编程而做简单练习之用。4 ) Windows 专用

7、函数 这些函数以 wgl 开头,是用于连接 OpenGL 和 Windows 窗 口系统的。 用它们可以管理着色描述表 (Render Context) 及显示列表 (Display List) ,扩展功 能,管理字体位图等。5 ) Win32 API 函数 共 6 个函数,用于处理像素格式及缓存。 ChoosePixelFormatDescribePixelFormat 6 ) OpenGL 结 构 共 有 4 个 , 列 举 如 下 : GLYPHMETRICSFLOATLAYERPLANEDESCRIPTOR PIXELFORMATDESCRIPTOR POINTFLOAT3 VC 环境

8、下的实现 背景 : 对三维物体进行可视化编辑,即增删改点 ,面操作 .模型为用VRML表示的一个人头像流程:数据准备a初始化绘制环境a模型的绘制a交互操作,点和面的编辑a导出数据3.1 数据准备1) 从指定的 VRML 文件中手工挑选出组成各个特征的点数据及面数据,处理后存为 input.dat 文本文件,点由三维坐标表示,面则统一为三角型面片,由三个点索引组成,格式如下:#Vertex/ 点数据,点的三维坐标;#skin/ 特征名称;0.0000 -31.9007 487.6600/ 点坐标31.0000 -28.3430 470.464063.0000 -29.9017 455.9880#

9、facet/ 面数据,相关点的索引;#skin/ 特征名称;0 1 16/ 点的索引;1 15 1616 15 13其中特征分为( skin,tongue,teeth,ear,lip,eye,mouth,nose,eyebrow )2 )从 input.dat 文件中读入点和面数据,存入程序结构中( PointNode,FaceNode ) 同时建立图元(点和面)的显示列表,为绘制模型做好准备。typedef struct pt_nodechar pZT;/ 点的状态, (' V ' -有效;' I' - 无效),为后续编辑作准备;double pt3;/ 点的

10、三维坐标;PointNode;typedef struct fe_nodechar fZT;面的状态(V'-有效;I'-无效);int Pt1Index;/ 面片中第一个 Vertex 的点索引;int Pt2Index;/ 面片中第二个 Vertexint Pt3Index;/ 面片中第三个 Vertex的点索引;的点索引;FaceNode;pt2,void CDisplayView:DrawTriangle(intGLdouble pt3)&i, GLdouble pt1, GLdouble首先计算该面的法向量;i 个显示列表;/ 创建三角行面片的显示列表;Calc

11、ulateNormal(pt1,pt2,pt3,dNormal);/glNewList(i,GL_COMPILE);/ 建立第glBegin(GL_TRIANGLES);glNormal3dv(dNormal);/ 指定该面的法向量为dNormal;glVertex3dv(pt1);glVertex3dv(pt2);glVertex3dv(pt3);glEnd();glEndList();i+;void CDisplayView:DrawPoint(int &n, GLdouble pt)/ 创建点的显示列表;glNewList(n,GL_COMPILE);glBegin(GL_POI

12、NTS);glVertex3dv(pt);glEnd();glEndList();n+;3.2 初始化绘制环境1)填充 PIXELFORMATDESCRIPTOR 结构。 PIXELFORMATDESCRIPTOR pixelDesc=;/按需要填充适当的值;2 ) 设置像素格式m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);/ 确定设备上下文 (DC) 所支持的像素格式中,与给定像素格式描述符最为匹配的像素格式索引值;if(m_GLPixelIndex =0)MessageBox( “ ChoosePixelFormat fail

13、ed!”);return FALSE;/ 执行失败!if(!SetPixelFormat(hDC,m_GLPixelIndex,&pixelDesc) / 将设备上下文 (DC) 中的像素格式 return FALSE;/ 执行失败! 设置为索引值 m_GLPixelIndex 所指定的格式;3 ) 创建着色描述表HWND hWnd = GetSafeHwnd();/ 得到 Windows 窗口的窗口句柄HDC hDC =:GetDC(hWnd);/ 得到设备上下文 (DC) 句柄;if(MyFunction_SetWindowPixelFormat(hDC)=FALSE)/ 测试设置

14、像素格式是否正确;return FALSE;/ 测试失败;hglrc = wglCreateContext(hDC);/建立 hDC 所关联的 OpenGL 绘图上下文( RC)if(hglrc = NULL)return FALSE;/ 创建失败;if(wglMakeCurrent(hDC,hglrc)=FALSE)/ 将一个指定的绘图描述表变为正在调用线程return FALSE;/ 失败; 的当前绘图描述表。4 ) 对灯光,材质等环境相关参数进行初始化int CDisplayView:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CView:OnC

15、reate(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);/ 设置朝向正面的多边型的顶点环绕方向为顺时针方向;GLfloat ambientProperties

16、 =0.15f,0.15f,0.15f,1.0f;/设置环境光分量;GLfloat diffuseProperties =0.7f,0.7f,0.7f,1.0f;/ 设置漫反射光分量;GLfloat specularProperties =0.7f,0.7f,0.7f,1.0f;/ 设置镜面反射光分量;GLfloat position = 1.0,1.0,-5.0,0.0;/设置光源位置;glClearDepth(1.0f);/ 设置深度缓冲的值为 1 ;/ 把各光分量的值赋给光源 0 ;glLightfv(GL_LIGHT0,GL_AMBIENT,ambientProperties);glL

17、ightfv(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 变换有基本变换和投影变换两种,基本变换是对三维物体进行平移、旋转、缩放等。投影变 换则把物体

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

19、 = 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 设置透视投影变换和视区void DisplayView:OnSize(UINT nType, int cx, int cy)CView:OnSize(nType, cx, cy);GLint w=cx;GLint h=cy;glViewport(0,0,w,h);/ 设置视区;glMatrixMode(

20、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_xRotate,1.0

21、f,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 模型的绘制由于侧重模型的编辑操作,在绘制时并未计算顶

22、点的法向量,仅仅求出了各个面片的法向量。void CDisplayView:OnPaint()CPaintDC dc(this);深度glClearColor(0.0f,0.5f,0.5f,1.0f);/ 将显示窗口颜色设置为蓝绿色;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);/ 用该色清除颜色,缓存;DrawScene();/ 绘制模型,即调用显示列表;SwapBuffers(dc.m_ps.hdc);/ 当前设备的前台缓存和后台缓存交换;void CDisplayView:Drawscene()for( int i = 0;i<

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

温馨提示

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

评论

0/150

提交评论