OpenGL GL_SELECT还是手动碰撞检测?

Ash*_*iya 11 opengl 3d geometry collision-detection picking

如图所示

http://oi56.tinypic.com/ifu33k.jpg

我绘制了一组轮廓(多边形)作为GL_LINE_STRIP.现在我想选择鼠标下的曲线(多边形)来删除,在3D中移动..等.

我想知道使用哪种方法:

1.使用OpenGL挑选和选择.(glRenderMode(GL_SELECT))

2.使用拾取射线检查手动碰撞检测,并检查射线是否在每个多边形内.

Kos*_*Kos 17

我强烈建议不要使用GL_SELECT.这种方法很老,在新的GL版本中不存在,你可能会遇到现代图形卡的问题.不要指望硬件支持它 - 可能你会在许多GPU上遇到这种模式的软件(驱动程序)后备,前提是它可以工作.使用风险自负:)

让我为您提供另一种选择.

对于坚固的大型物体,有一种古老而好的选择方法:

  • 启用剪刀测试并将其设置为光标位置的1x1窗口
  • 绘制没有光照,纹理和多重采样的屏幕,为每个"重要"实体指定一个独特的纯色 - 这种颜色将成为拾取的对象ID
  • 调用glReadPixels并检索颜色,然后用于识别拾取的对象
  • 清除缓冲区,将剪刀重置为正常大小并正常绘制场景.

这为您提供了非常可靠的"每个对象"拣选方法.此外,只使用最少的每像素操作绘制和清除1个像素并不会真正损害您的性能,除非您缺少顶点处理能力(我认为不太可能)或者确实有很多对象并且可能会获得CPU-限制了绘制调用的次数(但是,我相信如果你可以按照像素数据传递颜色,可以将它优化为单个绘制调用).

RGB中的颜色是3个无符号字节,但应该可以另外使用帧缓冲区的alpha通道作为最后一个字节,因此你总共得到4个字节 - 足以存储任何32位指针作为对象颜色.

或者,您可以创建具有特定像素格式的专用帧缓冲对象(例如GL_R32UI,或者,即使GL_RG32UI您需要64位).

对于严格的几何方法,以上是一个很好的快速替代方案(在可靠性和实现时间方面).

  • 如果您希望能够通过单击其内部来选择曲线,只需在拾取阶段将几何体绘制为实心多边形(glPolygonMode),然后再将其更改为再次绘制线条.这应该够了吧.顺便说一下 - 你现在正在使用GL_LINE_STRIP模式吗?您可能一直使用GL_POLYGON,只需将glPolygonMode切换为GL_FILL进行拾取,将GL_LINE切换为绘图. (2认同)

Gia*_*awa 5

我发现在新的GPU上,GL_SELECT模式非常慢.我用几种不同的方法来解决这个问题.

第一个是做一个CPU碰撞测试,虽然有效,但没有我想象的那么快.当你将光线投射到屏幕上时(使用gluUnproject)然后试图找到鼠标正在碰撞的对象,它肯定会减慢速度.我获得满意速度的唯一方法是使用八叉树来减少碰撞测试的次数,然后进行边界框碰撞测试 - 但是,这导致了一种不是像素完美的方法.

我确定的方法是首先找到鼠标下的所有对象(使用gluUnproject和边界框碰撞测试),这通常非常快.然后,我将可能与后备缓冲器中的鼠标碰撞的每个对象渲染为不同的颜色.然后我使用glReadPixel获取鼠标下的颜色,并将其映射回对象.glReadPixel是一个慢速调用,因为它必须从帧缓冲区读取.但是,每帧执行一次,最终花费的时间可以忽略不计.如果您愿意,可以通过渲染到PBO来加快速度.

Giawa