使用OpenGL交互式鼠标拾取/选择曲线



这不是关于如何创建和渲染曲线(例如Bezeier、NURBS等(,而是关于当鼠标光标悬停在曲线的任何部分时,如何通过鼠标点击交互式地"拾取"曲线。

在完成所需的计算后,我通过将曲线细分为许多单独的较小线段来渲染2D或3D曲线。这样的线段越多,曲线看起来就越平滑、越逼真。

我有意将这些GL_LINE段中的每一个创建为单独的实体(每个实体都被分配了自己唯一的ID号(。这些线段属于曲线"对象"(它也有自己的唯一ID(。然后,使用光线投射,我可以启用鼠标线条碰撞检测,并知道单个线段何时被"击中",并高亮显示(例如,暂时更改其颜色(。但同时也要高亮显示属于曲线的所有其他线段,从而使整个曲线看起来像是被选中的。

问题是,由于每条曲线不仅由有效定义曲线的"核心"控制点组成,还由数千个有效绘制曲线的点组成,因此图形性能很快就会显著下降。

我知道我可以更有效地计算所有细分点,并使用LINE_STRIP将曲线渲染为一个图形对象?但这将不允许我使用所描述的光线投射技术,即能够将鼠标光标悬停在曲线的任何部分上并"选择"曲线对象。

所以。。。。如何在OpenGL中更有效地"拾取"曲线?

您有两个明显的选项:

  1. 使用ID缓冲区

    渲染曲线时,将颜色指定给RGBA帧缓冲区。因此,只需将渲染曲线的ID指定给单独的缓冲区(与视图的分辨率相同(,然后只需从该缓冲区中拾取鼠标下的像素位置,即可准确地查看您选择的曲线或对象。

    这是像素完美和O(1)超快速。。。但是,如果您的对象太薄,您可能会在使用它从单个像素拾取鼠标时遇到问题,因此测试距离鼠标一定距离(您可以在鼠标周围glReadPixels矩形(的末端,返回所有存在的ID,或者只返回最常见的ID。

    请参阅:

    • 具有高多边形网格的OpenGL三维光线拾取

    渲染前不要忘记清除ID缓冲区,如果有太多对象无法放入8位模具,请使用不同的缓冲区。。。在2D的情况下,您可以使用深度缓冲区,或者您可以在2次传递中渲染到RGBA帧缓冲区,首先将ID读取到CPU侧内存中,然后进行10次正常渲染。您也可以渲染到纹理。。。

  2. 计算到曲线的距离

    它是可行的,例如:

    • 是否可以从三次贝塞尔曲线方程中表达"t"变量

    正如你所看到的,它也可以用于渲染本身(没有线近似,只有"完美"曲线(,甚至可以快速。。。

    所以,只需计算鼠标到每条曲线的距离,并记住最近的一条。如果距离大于某个阈值/距离,则不进行选择。

最新更新