博文

乱弹OpenGL选择-拾取机制(下)(转)(2009-09-11 10:40:00)

摘要:本篇紧随上篇,探讨一下OpenGL内置的拾取机制,给出一个完整的拾取部分实现代码,请有心人批评指正。前篇是:[乱弹OpenGL选择-拾取机制(上)] —— ZwqXin.com
前篇主要讲了名字栈机制,这是拾取机制中对拾取结果进行识别的机制,是后处理的前提。而本篇则从拾取机制的“拾取”部分,揭露一下我所理解的OpenGL内置拾取机制。
3. 真正的拾取机制
还记得前篇提及的一般游戏引擎中所使用的“射线检测”机制吗?这确实是实现成本非常小的技术,而且无关OPENGL或D3D管道。但是依靠人工的进行点面检测将涉及两个难题:屏幕场景中很多物件怎么办?要把射线与所有这些物件都做一次叉叉检测么;物件由很大量三角形面组成怎么办?连渲染模型本身都够呛了,何况还得在点选时把射线方程与各个面纠缠一次直到检测到或全部检测完发现做了无用功为止……(所以现在都改射线-包围盒检测了~但前一问题尤在。)
OpenGL内置拾取机制利用的是固定渲染管道的东西——视截体裁减。留意过3D图形学的朋友应该记得流水线是怎么“砍掉”场景中不在视野内的部分的,这里我就不探讨其数学原理了——其实也就相交检测之类,不过交给更可靠的流水线去快速实现而已。而这里,OpenGL也是应用的流水线的这个能力,只不过用来“砍”场景的平头视锥题是个“萎缩版”的而已。
(看不到图片的见贴:[显示本站所有图片] )
这是去年9月做的一个小DEMO,场景中有三个模型(物件),能进行鼠标拾取操作从而对模型进行平面移动。如你所见,整个渲染窗口是一个投影平面,也是视锥的近截面。流水线把视锥之外的都喀嚓掉了,譬如船模的船头部分,实际上已经被切断,然后在切断处形成暂时的流水线顶点。那么,我们看鼠标吧。它正在拾取其中一个白色模型,在点击鼠标进行拾取的刹那,在渲染窗口屏幕上形成了一个看不见的小矩形(我在画图工具里用个黄色矩形形象化表示~),这个小矩形就是在拾取时(renderMode == GL_SELECT),OPENGL世界中唯一能显示出来的区域——没错,它就是拾取刹那产生的新平头视截体的近平面!这个新视截体在下图草草表现出来:  注意红色椭圆圈着的就是新视截体的近、远截面,与之间的四条连线构成一个小型平头锥体,是不是形同于意同于“目光”呢?其实也算一种射线吧哈哈。(注意,在屏幕上的小矩形实......

阅读全文(3668) | 评论:1

乱弹OpenGL选择-拾取机制(上)(转)(2009-09-11 10:39:00)

摘要:转自:http://www.zwqxin.com/archives/opengl/opengl-picking-what.html
无论是游戏还是VR,三维世界总免不了与用户的交互。而这其中常也免不了“用户对场景中物件的选择(也就是,拾取)”这种需求。OpenGL本身就内置有一套拾取机制,这次就乱弹一下吧。(乱弹不少了哦~)——ZwqXin.com
OpenGL内置的拾取方法,应该是第三次要接触了。头次是课程作业,套例子糊里糊涂弄成功了;第二次是去年9月,做一个DEMO,实现起来终于遇到了诸多麻烦,好不容易通过艰辛调试得到了正确的结果,相关代码被我供奉捧信至今,但其实也不算真正理解了这套机制。这次则是跟老师做的一个项目需要,虽说把之前的代码弄进来这个选取逻辑就差不多了,但我觉得嘛,还是趁机作一次更深入的了解吧。
假设用户是通过鼠标左键单击来选择场景物件的。先说说一般游戏引擎里的“射线检测”实现思路,也就是在用户拾取物件,点击渲染窗口(屏幕)上的相应的某一点的时候,激发一条从相机位置(眼睛)过该点的射线,这条射线反映在世界空间中,就是“穿过”视像平面发射到三维世界空间的光束。根据三维投影的知识(小孔成像原理)可知,该光速必然可以“射中”用户所点击处的物件,问题转化为线面相交检测——检测通过则意味着“射中”该面所属的三维物件。
1.名字标识
这“射线检测”比较好理解。好吧,请先认为OpenGL也遵循这种机制(可不要先入为主哦,后面或许会否定这个假设的),那么,从工序的后端往前看,要解决些什么问题呢?恩,三维物件知道自己身体某一部分的面被一条线叉中了,但它怎么通知应用程序“我被叉叉了”呢?简单的就是给上头打报告,报告内容首项写上自己的姓名。好吧,在三维世界里允许长一个样的但不允许有同样的识别码,换言之,你最好给场景中每样你在意的物件分配一个唯一的ID,好在它们打报告的时候不会弄混。于是,在这层意义上,ID就是名字。
OpenGL拾取机制觉得ID这太俗了,于是用名字(Name)来唯一表示每个可拾取物件。但是我们作为应用者就该记住,这里的Name就是ID,即使它真是一个名字"Allan",那背后肯定也有这么一句"#define Allan 13"之类的。OpenGL拾取的名字机制也就是ID机制。当然,它里面没有什么排斥不唯一性的,但你......

阅读全文(3711) | 评论:0