如何使用OpenGL进行3D选择/拾取

11

场景中有些物体可能会遮挡其他物体。当我单击鼠标或拖动选择时,我希望只选择/拾取从这个视角可以看到的物体。应用程序当前使用GL_SELECT渲染模式,但我们知道,这也会选择被遮挡的物体。此外,我读到在OpenGL 3中,GL_SELECT已被弃用。

目前有两种方法吸引我的注意。第一种是使用后备缓冲区的对象选择(《红宝书》,第14章):将每个对象的颜色设置为其对象ID,并从后帧缓冲区读取像素的颜色。第二种是遮挡查询(《超级圣经》,第4版,第13章)。

我排除了其他方法,比如查看选择缓冲区中的最小/最大z值以及在GL之外进行自定义光线/物体检测等。

我有一些问题: 1)如果GL_SELECT在最近的OpenGL中已被弃用,开发人员应该使用什么替代品? 2)我只读过遮挡查询被用来加速渲染。它们能用于选择/拾取吗?是否存在缺点? 3)现有应用程序有几个glColorXXX调用。如果我选择了使用后备缓冲区的路线,并使用glColorMask(FALSE,FALSE,FALSE,FALSE),这是否会有效地将glColorXXX调用转换为没有效果的调用,从而在选择模式下让我控制颜色? 4)哪种方法是最好/标准的?


2
你真的找不到在SO上已经问过并回答了的内容吗? - Ben Voigt
2
@Ben:就我所知,在OpenGL中,关于拾取的遮挡检测方面,SO上没有任何问题,也没有将其与读取点击像素颜色的方法进行对比的问题。 - PeteUK
1
你为什么排除了“在GL之外进行物体检测”的可能性?即使是最简单的图形显示也可以从空间加速结构中受益。 - cmannett85
1
@cbamber85:好问题!我正在处理一个现有的应用程序,如果要在GL之外进行对象检测,则需要进行更多更改,以便提供准确的边界体积。其次,当涉及到这方面的知识时,我是个新手(即我三分钟前从未听说过空间加速结构!)。我会研究一下这个方法,并在适当的时候将其纳入我的系统中,但现在我想走OpenGL路线。顺便问一下,你能提供任何关于你建议的方法的学习指南吗?(维基页面上没有相关链接)。 - PeteUK
@cbamber85:看起来我应该调查八叉树、KD树等相关内容? - PeteUK
我目前正在开发一款类似CAD的应用程序,由于其动态结构,我发现包围体层次结构是最有效/最简单的。KD树通常是最快的,但只适用于静态场景。搜索“BVH选择性重构”以探索一个好的途径 - 请注意,空间加速结构是一个庞大的研究领域,可能会在一开始时感到非常压抑... - cmannett85
1个回答

4

我决定使用后备缓冲区来实现选择。以下是我的尝试来回答我的问题:

如果GL_SELECT在最近的OpenGL中已经过时,开发人员应该使用什么替代方案?
我认为最好不要使用OpenGL来完成此任务,而是像用户chamber85在原始问题的评论中建议的那样使用空间加速结构。

我只读过遮挡查询用于加速渲染。它们可以用于选择/拾取吗?有什么缺点吗?
我确定它们可以用于选择/拾取,但是需要在绘制之前知道所有想要查询的对象。使用后备缓冲区和颜色选择,可以看到光标下或矩形区域内的内容并从中过滤。

现有应用程序有一些glColorXXX调用。如果我采用后备缓冲区路线,并使用glColorMask(FALSE,FALSE,FALSE,FALSE),这将有效地将glColorXXX调用转换为没有效果的调用,从而让我在选择模式下控制颜色是否正确?
答案是否定的。调用glColorMask()时,所有参数都是GL_FALSE不会意味着glColor3ub()调用(例如)将不被执行。它只是指定了一个颜色过滤/掩码,用于在写入颜色缓冲区之前过滤颜色。最初的想法是将颜色设置为对象ID,然后调用glColorMask()来忽略所有后续的glColorXXX()调用。但这种策略注定会失败,因为表示对象ID的颜色也将被屏蔽。

4)哪个路线是最好的/规范的? 我认为后备缓冲区颜色选择通常是最好的,因为它不需要在绘制之前/期间设置遮挡查询。


1
你好Pete,我有一个问题:在OpenGL 3及更高版本中,后备缓冲区也不再被使用了吗? - elect
@elect:我刚刚快速搜索了一下,看起来你是对的。 - PeteUK
哈哈,该死的,我也在尝试使用后备缓冲区来实现选择,就像你选择的那样。对我来说,这看起来基本上很容易和快速。由于我正在使用OpenGL 2.0,希望不会出现问题...也许将来当我想升级它时... - elect
@elect,我认为这个功能消失需要很长时间,所以你应该没问题。 - PeteUK
没错,你说得对,我刚刚完成了它的实现。太棒了,它非常好用 :) 相对来说还算简单快速,只是在设置精确颜色ID方面有些问题,但最终一切都很好。谢谢! - elect

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接