Opengl 使用选择框选择三维曲面(以两种不同的方式)
我正在创建一个建模软件。我的模型都是由平面多边形组成的,这些多边形只是我用OpenGL显示的一组有序的顶点。我已经做了相当多的搜索,但令我惊讶的是,我还没有找到很多关于我正在寻找的应用程序的信息 我试图使用一个矩形框来选择曲面。这听起来很简单,但我希望它的工作方式与此方法在许多程序中的工作方式相同。以下是我正在寻找的要求:Opengl 使用选择框选择三维曲面(以两种不同的方式),opengl,3d,mouse-picking,Opengl,3d,Mouse Picking,我正在创建一个建模软件。我的模型都是由平面多边形组成的,这些多边形只是我用OpenGL显示的一组有序的顶点。我已经做了相当多的搜索,但令我惊讶的是,我还没有找到很多关于我正在寻找的应用程序的信息 我试图使用一个矩形框来选择曲面。这听起来很简单,但我希望它的工作方式与此方法在许多程序中的工作方式相同。以下是我正在寻找的要求: 我想要一个从左边开始到右边的矩形,只选择那些完全包含在框中的对象 从右开始向左的矩形应选择任何接触的曲面(不必完全封闭) 应选择矩形中/与矩形接触的所有对象。换句话说,我希望
算法的伪代码将受到赞赏,但不是必需的。至少我正在寻找一种方法,我可以自己研究并找到一些示例;我只是不知道应该在哪里查找。我可以直截了当地告诉您,颜色拾取将不起作用;您必须对每个对象执行一次才能满足要求要求(3),因为只有一个像素进入帧缓冲区 至于光线投射,它确实只测试一个点,但实际上可以通过取消投影选择矩形的四个角来创建测试体积。可以在世界空间中的近平面(
Win_Z=0
)和远平面(Win_Z=1
)找到坐标并使用此选项从二维选择区域构造三维体积
从中得到的体积称为平截体(假设透视投影),它看起来像一个顶部被切掉的金字塔。平截体相交测试有很好的文档记录,任何讨论“平截体剔除”的内容应该为您提供足够的背景来实现这一点。如果您可以使用轴对齐的边界框和/或球体来近似这些对象的边界,您的生活会轻松得多
下面的示例很好地说明了此测试卷:
在CPU上执行自己的交点计算当然是一种选择。但基于我对您的需求的理解,我认为您也可以让OpenGL来完成这项工作,这应该会更简单、更高效 方法概述 想到的机制是遮挡查询。它们允许您计算已渲染的像素数。如果您将此与使用剪刀测试相结合,则可以计算在选择矩形内渲染的像素数 用例的应用 用例2是这种方法中比较简单的一个。您将选择矩形设置为剪刀形矩形,并使用每个曲面的遮挡查询渲染所有曲面。然后检查查询结果,查询结果大于0的所有曲面在选择矩形内都有像素 用例1有点棘手。要知道曲面是否完全包含在矩形中,需要两次过程。在启用剪刀测试的情况下,使用遮挡查询进行渲染,如上一次。然后在禁用剪刀测试的情况下第二次执行相同的操作。如果曲面对这两次都具有相同的查询结果通过时,它完全位于矩形内 实施 我不打算为此提供完整的代码。这应该非常简单。但这里有一些指针和代码片段。这些调用是用C绑定显示的。我希望很明显,Python绑定的情况也是如此 首先,由于要在选择中包括隐藏曲面,因此需要禁用深度测试:
glDisable(GL_DEPTH_TEST);
由于您实际上不需要生成输出,并且可能不想干扰视觉渲染输出,因此您可能还需要禁用颜色输出:
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
如果启用了背面剔除,则可能还需要禁用该选项:
glDisable(GL_CULL_FACE);
然后,对于上面提到的只想计算选择矩形内像素数的过程,设置剪刀矩形并启用剪刀测试:
glScissor(selectionLeft, selectionBottom, selectionWidth, selectionHeight);
glEnable(GL_SCISSOR_TEST);
对于使用遮挡查询的渲染,每个曲面都需要一个查询对象:
GLuint queryIds[surfaceCount];
glGenQueries(surfaceCount, queryIds);
然后,对于每个曲面,使用k
作为循环索引:
glBeginQuery(GL_SAMPLES_PASSED, queryIds[k]);
// render surface k
glEndQuery(GL_SAMPLES_PASSED);
渲染所有曲面后,可以获得查询结果:
GLint pixelCounts[surfaceCount];
// for all surfaces k
glGetQueryObjectiv(queryIds[k], GL_QUERY_RESULT, &pixelCounts[k]);
然后评估像素计数,以决定应选择哪些曲面,如前一节中针对每个用例所述
完成后,不要忘记重置所有状态以准备再次渲染。深度测试、颜色遮罩、剪刀测试等。我知道我迟到了,但实际上颜色拾取可以用于选择深层对象,同时通过解决方法执行:按下shift+鼠标滚动时进行选择剥离 或者换句话说,当你做第一个矩形t时