我想实现场景拾取(用于鼠标点击,移动等)。什么是最好,最快的方式?我曾经使用glSelectBuffer
和glRenderMode
与GL_SELECT
一起使用,然后再次渲染整个场景(当然还有提升,没有纹理,重型着色器等)。
在每次鼠标单击,移动和拖动时递归渲染一个数字(几何ID)的所有节点和几何图形太慢。有人知道更好的方法吗?
修改 具有读取深度缓冲区的解决方案似乎很费劲,但如果我不想选择一些几何形状并且它们已经被淹没到缓冲区呢?包含点的查找框可能不精确,因为点可以在多个框中。
是否可以在一次绘制中写入两个帧缓冲区,深度缓冲区?然后我可以通过着色器将几何id写入一个缓冲区。速度怎么样?
答案 0 :(得分:5)
由于我是新来的,我无法直接回答Joe,所以我会在这里做。 我从来没有试过这样做,所以我不确定它是否适合你。 希望它会,如果不是:我会给你我的版本。 有很多方法可以做到。 再次渲染整个场景似乎有点矫枉过正。
我这样做是OBB-Ray交叉测试。您可以考虑几何体周围的面向对象的边界框,并检测它们是否与来自鼠标点击的光线发生碰撞。如果你需要较低的精度,我会说去AABB甚至是Sphere。更精确:凸壳。请注意,您要求的精度越低,算法越快。 如果您不想自己实现算法,可考虑使用物理库加速计算,如Bullet或PhysX,这可能是一种矫枉过正。 另一种方式是我以前没用过的OpenGL黑客。
所有这些方法都在这里解释: http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/
答案 1 :(得分:3)
过去我曾使用glReadPixels( xf, yf, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zf);
来读取屏幕空间中某个点(xf,yf)的深度缓冲区的值。
然后,您可以将此点反投影回世界坐标(乘以模型视图和投影矩阵的倒数)。
如果您对应用程序中的GLU库感到满意,可以使用gluUnProject
来完成此操作。
这为您提供了一个坐标,然后您需要搜索对象以找到一个具有包含此坐标的边界框的对象。这个对象是选中的。
如果您想了解更多相关信息,我建议您搜索有关Unprojecting的信息,https://www.opengl.org/archives/resources/faq/technical/selection.htm也很有用(并建议您可以使用其他技术)。