4

我正在使用 glDrawElements 绘制三角形网格,并且希望能够使用鼠标单击来选择/选择三角形。三角形的网格可以非常大。

在固定功能的 OpenGL 中,有可能使用 GL_SELECT: http ://content.gpwiki.org/index.php/OpenGL:Tutorials:Picking .. 但是我只对使用 OpenGL 核心配置文件感兴趣。

另一种可能性是使用“颜色编码”:

http://www.lighthouse3d.com/opengl/picking/index.php?color1

http://www.opengl.org/resources/faq/technical/selection.htm

..但据我所知,在使用 glDrawElements 时还不能指示每个三角形的信息?

最后,我可以通过鼠标位置拍摄拾取射线来进行基于 CPU 的拾取,但这会很慢,因为我想我必须在 CPU 上转换三角形,所以我更喜欢基于 GPU 的解决方案。

有没有人建议在 OpenGL 核心配置文件中使用 glDrawElements 时最好的选择方法是什么?

4

3 回答 3

5

关于“颜色编码”方法,您可以使用gl_PrimitiveID使用适当的片段着色器填充颜色编码的缓冲区,这基本上会给您绘制三角形的索引。

关于基于 CPU 的拾取,您可以使用现有的库来处理加速结构和光线网格相交,例如BulletOpcode

您的“最佳”选项取决于您的用例,很难说。

于 2012-01-31T12:45:49.843 回答
3

试着从这个角度来看待它:OpenGL 只用于绘图。采摘应该以另一种方式进行。如果您坚持使用 OpenGL(并非不合理),请使用带有整数 16 位单通道颜色缓冲区附件的 FBO,将对象 ID 渲染到其中。拾取减少读取 ID 的一个像素。

最后,我可以通过鼠标位置拍摄拾取射线来进行基于 CPU 的拾取,但这会很慢,因为我想我必须在 CPU 上转换三角形,所以我更喜欢基于 GPU 的解决方案。

我推荐这个。然而,不要变换所有的三角形,只需反向变换你的一个拾取射线。无论如何,您应该在某些空间细分结构中管理您的场景,因此对此进行测试应该是微不足道的。

于 2012-01-31T15:38:10.670 回答
2

好吧,您确实可以在 DrawElements 调用中提供每个三角形的信息。然后您必须提供相应的数组(以前的 COLOR_ARRAY、TEXTURE_COORD_ARRAY 等,现在通常称为 VertexAttribArrays)。如果您坚持使用 GPU,这可能是最简单的解决方案。

但是,通常的方法是从点击点向场景发射光线。因此,您要做的不是变换每个三角形,而是计算射线和三角形之间的相交测试。如果射线相交,则您击中它,否则您没有。如果你用蛮力做这件事,这确实会付出相当大的代价。

但是,通常您会将三角形包含在一些空间数据结构中(即您的场景图将/可以/应该有一些表示形式),例如八叉树(http://en.wikipedia.org/wiki/Octree)。这将允许在相当多的测试中产生碰撞响应。此外,您可以考虑三角形将在屏幕上占据的最终大小(因此在大多数情况下选择亚像素三角形毫无意义)。

如果你真的想变得花哨,你也可以把整个过程放到 GPU 上(一个听起来很有趣的例子是http://blog.xeolabs.com/ray-picking-in-scenejs,但是会有当你使用谷歌时会出现更多)。

我个人认为最容易实现的是解决方案 b) 软件光线拾取,然后是 a) 最后是 GPU 拾取。从最简单的开始,如果您认为它不够快,请改进。不要被太多过早的优化所困扰(例如,光线投射拾取在我的 iPhone 上运行得非常好;)。用你的采摘算法玩得开心,祝你好运。

于 2012-01-31T12:41:15.737 回答