基于Opengl的屏幕对象拾取 毕业论文(5)
4 系统的设计及实现
有些图形应用程序只绘制两维和三维物体构成的静态图形,另一些允许用户识别屏幕上的物体并移动、修改、删除或用其它方法操纵这些物体。OpenGL正是设计用于支持这些交互式应用程序的。因为绘制在屏幕上的物体通常经过多次旋转、移动和透视变换,所以确定用户选中了三维场景中的哪个物体会很困难。为了解决这个问题,OpenGL提供了一个选择机制可惟自动告诉你哪个物体被绘制在窗口的提定区域里。
本文的拾取考虑到简单地拾取三个不同的物体,分别是一个一个拾取,而不是同时拾取的过程且拾取物体是简单的选择体,这些正好都不是OpenGL的选择机制的各种缺点且OpenGL的选择机制是OpenGL本身自带的因素,所以采用了OpenGL的选择机制的拾取方法,来实现对三个不同的物体拾取。拾取过程如下:
使用OpenGL的选择机制时,首先把场景画进帧缓冲,然后进入选择模式并重新绘制这个场景。然而,一旦进入了选择模式,帧缓冲的内容将保存不变,直到退出选择模式。当退出选择时,OpenGL返回一个图元(premitives)清单,图元可能被视见体(viewing volume)分割。每个被视见体图元引出一资选择命中(hit)。确切的说,图元清单是作为一个取整数值的名字(integer-valued names)数组和相关的数据-命中记录(hit record)-对应名字栈(name stack)的当前内容。当在选择模式下发布图元绘制命令时向名字栈中加入名字就可建立起名字栈。这样,当名字清单被返回后,就可以用它来确定屏幕上的哪个图元可能被用户选中了。
除了这个选择机制之外,OpenGL提供了一个工具例程,以便在某些情况下通过限定在视口(viewport)一个小区域内绘制来简化选择。可以用这个例程决定哪个物体被画在光标附近了,这样就能识别用户拾取了哪个物体,也可以通过指定附加的裁剪面来界定一个选择区域。 4.1系统的选择机制
选择机制分以下几个部分来进行: (1)进入选择模式之前; (2)获取当前选择模式; (3)退出当前选择模式; (4)拾取。
4.1.1进入选择模式之前
用glSelectBuffer()指定用于返回命中记录的数组; 下面描述glSelectBuffer()和glRenderMode()。
void glSelectBuffer(GLsizei size,GLuint *buffer);指定用于返回选择数据的数组。
参数buffer是指向无符号整数(unsigned integer)数组的指针,数据就存在这个数组中,size参数说明数组中最多能够保存的值的个数。要在进入选择模式之前调用glSelectBuffer() 4.1.2获取当前选择模式
以GL_SELECT为参数调用glRenderMode()进入选择模式;
GLint glRenderMode(GLenum mode);控制应用程序是否进入绚染(rendering)、选择或反馈模式。mode参数可以是GL_RENDER(默认)、GL_SELECT或GL_FEEDBACK之一。应用程序将保持处于给定模式,直到再次以不同的参数调用glRenderMode()。在进入选择模式之前必须调用glSelectBuffer()指定选择数组。类似的,进入反馈模式之前要调用glFeedbackBuffer()指定反馈数组。如果当前模式是GL_SELECT或GL_FEEDBACK之一,那么glRenderMode()的返回值有意义。返回值是当前退出当前模式时,选择命中数或放在反馈数组中的值的个数。负值意味着选择或反馈数组溢出(overflowed)。用GL_RENDER_MODE调用glGetIntegerv()获取当前模式。 定义用于选择的视见体
通常它与原来用于绘制场景的视见体不同,也可以用glPushMatrix()和glPopMatrix()来保存
18
和恢复当前的变换矩阵;在选择模式下,被视见体裁剪的每个图元引起一个选择命中。当前一个名字栈控制命令被执行或glRenderMode()被调用后,OpenGL将一个命中记录写进选择数组,如果从上一次名字栈操纵或glRenderMode()调用以来有了一个命中记录的话。这个过程中,共用同样名字的物体-例如:由多个图元组成的物体-不生成多个命中记录。当然,命中记录不保证会被写进数组中直到glRenderMode()被调用。
除图元之外,glRasterPos()产生的有效坐标也可以引起选择命中。在多边形的情况下,如果它已经被消隐掉的话不会有命中记录出现。 每个命中记录由四项组成,依次是: (1)当命中出现时名字栈中的名字数;
(2)至上次记录的命中以来,被视见体裁剪后的图元的所有顶点的窗口Z坐标的最大; (3)被视见体裁剪后的图元的所有顶点的窗口Z坐标最小值; (4)本次命中时名字栈的内容,最底元素最前。
进入选择模式时,OpenGL初始化一个指针指向选择数组的起点。每写入一个命中记录,指针相应更新。如果写入一个命中记录会使数组中值的个数超过glSelectBuffer()的size参数时,OpenGL会写入尽可能多的记录并设置一个溢出标志。当用glRenderMode()退出选择模式时,这条命令返回被写入的记录的个数(包括一条部分记录如果有的话),清除名字栈,复位溢出标识,重置栈指针。如设定溢了出标识则返回值是-1。
用glInitName()和glPushName()初始化名字栈
名字栈是返回给你的选择信息的基础,要建立名字栈,首先用glInitNames()初始化它,这将简单地清空栈。然后当发布相应的绘制命令时向其中加入整数名字。栈控制命令允许你压入名字(glPushName()),弹出名字(glPopName()),替换栈顶的名字(glLoadName())。 举个例子:
Example 12-1: Creating a Name Stack glInitNames(); glPushName(-1);
glPushMatrix(); /*保存当前的转型的状态*/ glLoadName(1); drawSomeObject(); glLoadName(2);
drawAnotherObject(); glLoadName(3);
drawYetAnotherObject(); drawJustOneMoreObject();
glPopMatrix (); /*恢复以前的转型的状态*/
在这个例子中,前两个被绘制的物体有自己的名字,第三和第四个共用一个名字。这样,如果第三或第四个物体中的一个或全部引起一个选择命中,只有一个命中记录返回给你。如果处理命中记录时不想区分各个物体的话,可以让多个物体共享一个名字。 void glInitNames(void); 清空名字栈。
void glPushName(GLuint name); 将name压入名字栈
压入名字超过栈容量时将生成一个GL_STACK_OVERFLOW错误。名字栈深度因OpenGL实现(implementations)不同而不同,但最少要能容纳64个名字。可以用参数GL_NAME_STACK_DEPTH调用glGetIntegerv()以获取名字栈深度。
void glPopName(void);弹出名字栈栈顶的那一个名字
19
从空栈中弹出名字引发GL_STACK_UNDERFLOW错误。
void glLoadName(GLuint name);用name取代名字栈栈顶的那个名字。如果栈是空的,刚调用过glInitName()后就是这样,glLoadName()生成一个GL_INVALID_OPRATION错。为避免这种情况,如果栈初始时是空的,那么在调用glLoadName()之前至少调用一次glPushName()以在名字栈中放上点东西。
交替发布图元绘制命令和名字栈控制命令,这样每个感兴趣的图元都会被指定适当的名字; 4.1.3退出选择模式
退出选择模式并处理返回的选择数据(命中记录)。 4.1.4拾取
用选择模式确定物体是否被拾取了,要做到这一点,用一个与投影矩阵相关联的拾取矩阵将绘制限制在视口的一个很小的区域里,通常是在光标附近。然后允许某种形式的输入,如点击鼠标的一个键,引发选择模式的初始化。建立起选择模式并使用特定的拾取矩阵,绘制在光标附近的物体引发选择命中。即,通常在拾取的时候确定哪个物体被画在 …… 此处隐藏:2808字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [综合文档]应答器设备技术规范(征求意见稿)A1
- [综合文档]教师 2012年高考政治试题按考点分类汇
- [综合文档]保险公司的总经理助理竞职演说
- [综合文档]卫生应急大练兵大比武活动考试--题库(
- [综合文档]徐州经济技术开发区总体规划环境影响报
- [综合文档]汉语拼音表(带声调)
- [综合文档]二年级 上 思维训练( 1~18)
- [综合文档]特色学校五年发展规划
- [综合文档]机床经常出现报警“X1轴定位监控”
- [综合文档]《电子技术基础》21.§5—2、3、4 习题
- [综合文档]浙江省深化普通高中课程改革
- [综合文档]CRISP原理 - 图文
- [综合文档]2017年电大社会调查研究与方法形考答案
- [综合文档]浅析建筑施工安全毕业论文
- [综合文档]《回忆我的母亲》名师教案
- [综合文档]装饰装修工程监理规划
- [综合文档]三下乡心得体会-文艺
- [综合文档]柱计算长度系数 - 图文
- [综合文档]全流程思考,提高燃电系统热电转换率--
- [综合文档]2018年嘉定区中考物理一模含答案
- 433M车库门滚动码遥控器
- 8、架空线路施工规范
- 大学四年声乐学习的体会
- 新北师大版五年级数学上册《轴对称再认
- 部编版五年级上册语文第六单元小结复习
- 小学六年级英语形容词用法
- 第2课 抗美援朝保家卫国 课件01(岳麓版
- 2015年天津大学运筹学基础考研真题,考
- 微机计算机控制技术课后于海生(第2版)
- 安全教育实践活动
- Delphi程序设计教程_第1章_Delphi概述
- 第八讲 工业革命与启蒙运动
- 《中华人民共和国药典》2005年版二部勘
- 科粤版九年级化学2.3构成物质的微粒(1)
- 西师大版数学三年级下册《长方形、正方
- ch6_冒泡排序演示
- 第4章 冲裁模具设计
- 浙江中小民营企业员工流失论文[终稿]
- 再议有线数字电视市场营运模式
- 昆明供水工程监理大纲




