- 1、本文档共7页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
使用OpenGL实现三维坐标的拣选
使用OpenGL实现三维坐标的鼠标拣选
Implementation of RIP(Ray-Intersection-Penetration)
3D Coordinates Mouse Selection Using OpenGL
顾 露 (武汉理工大学 计算机系 中科院智能设计与智能制造研究所 湖北武汉 430070)
摘要(Abstract):
本文提出并实现一种用于三维坐标拣选的RIP(Ray-Intersection-Penetration)方法。介绍了如何在已经渲染至窗口的三维场景中,使用鼠标或者相关设备拣选特定三维对象的方法。此方法对于正交投影或透视投影均有效,相对于OpenGL自带的选择与反馈机制,本方法无论是拣选精度还是算法实现效率均高出许多,是一种比较通用的解决方案。
关键词(Keywords)
正交投影(Ortho-Projection)、透视投影(Perspective-Projection)
世界坐标系、屏幕坐标系、三维拣选、OpenGL
一、简介(Introduction)
OpenGL是一种比较“纯粹”的3D图形API,一般仅用于三维图形的渲染,对于特定领域的开发者(如游戏开发者)而言,如果选择使用 OpenGL进行开发,类似碰撞检测的机制就都需要自行编写了。但是由于鼠标在图形程序中的应用非常非常之广泛(例如现在已经很少有PC游戏能完全地脱离鼠标),OpenGL在图形库的基础上添加了选择与反馈机制(Select Feedback)来满足用户使用鼠标实时操作三维图形的需要。但由于种种原因,我们需要更为特殊的选择机制以满足特定需求,在这里我们提出了一种简单迅速的RIP(Ray-Intersection-Penetration)方法,可以满足绝大多数典型应用的需要。
二、相关研究(Related Work)
用过OpenGL选择与反馈机制的开发者,或多或少可能都会觉得它难以令人满意。大致表现在下面几个方面:
编写程序比较繁琐。
想要使用选择反馈机制就需要切换渲染模式,操作命名堆栈,计算拣选矩阵,检查选中记录,这些繁琐的步骤很容易出错,而且非常不便于调试,只会降低工作效率和热情。
只能做基于图元的选定。
如下图(1 - a),使用GL_TRIANGLES绘制了一个三角形,三个顶点分别为 P1、P2和P3。若使用该机制,你将只能判断是否在三维场景中选中了这个三角形(用户点击处是否在P1、P2和P3的范围内),而无法判断用户是点击了这个三角形哪一部分(是左边的m区域内还是右边的n区域内),因为所绘制的P1、P2和P3本身构成的三角形就是一个基本图元,对于拣选机制而言是不可分的。当然,把这个三角形拆成两个三角形再分别进行测试也是一个可行的方案,可是看看图(1 - b),这可怎么拆呢?还有图(1 – c)呢?另外,如果n和m两个平面不共面呢?对于使用者而言,OpenGL提供的拣选机制功能的确有限。
三、降低了渲染效率。
OpenGL中的选择和反馈是与普通渲染方式不同的一种特殊的渲染方式。我们使用时一般是先在帧缓存中渲染普通场景,然后进入选择模式重绘场景,此时帧缓存的内容并无变化。也就是说,为了选择某些物体,我们需要在一帧中使用不同的渲染方式将其渲染两遍。我们知道对对象进行渲染是比较耗时的操作,当场景中需要选择的对象多而杂的时候,采用这个机制是非常影响速度的。
另外在OpenGL红宝书中介绍了一种简便易行的办法:在后缓冲中使用不同的颜色重绘所有对象,每个对象用一个单色来标示其颜色,这样画好之后我们读取鼠标所在点的颜色,就能够确定我们拣选了哪个物体。这种方法有一个缺陷,当场景中需要选择的对象的数目超出一定限度时,可能会出现标识数的溢出。对于这个问题,红宝书给出的解决办法就是多次扫描。实践证明这种方法的确简便易行,但仍有不少局限性,而且做起来并不比第一种机制方便多少。限于篇幅,不再赘述。
三、具体描述(Related Work)
看过了上面两种方法,我们会发现这两种方法都不是十分的方便,而且使用者不能对其进行完全的控制,不能精确地判定鼠标定位与实际的世界空间中三维坐标的关系。那么有什么更好的办法能够更简单更精确地对其加以控制呢?
实际上此处给出的解决方案十分简单,就是一个很普通也很有用的 GLU 函数 gluUnProject()。
此函数的具体用途是将一个OpenGL视区内的二维点转换为与其对应的场景中的三维坐标。
转换过程如下图所示(由点P在窗口中的XY坐标得到其在三维空间中的世界坐标):
这个函数在glu.h中的原型定义如下:
int APIENTRY gluUnProject (
GLdouble winx,
GLdouble winy,
文档评论(0)