Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用OpenGL交互式鼠标拾取/选择曲线_C++_Opengl_Mouse_Raycasting_Picking - Fatal编程技术网

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

C++ 使用OpenGL交互式鼠标拾取/选择曲线,c++,opengl,mouse,raycasting,picking,C++,Opengl,Mouse,Raycasting,Picking,这不是关于如何创建和渲染曲线(例如Bezeier、NURBS等),而是关于当鼠标光标悬停在此类曲线的任何部分上时,如何通过鼠标单击以交互方式“拾取”此类曲线 在完成所需的计算后,我通过将曲线细分为许多单独的较小线段,以2D或3D方式渲染曲线。这样的线段越多,曲线看起来就越平滑和真实 我特意将每个GL_线段创建为单独的实体(每个都指定了自己的唯一ID号)。这些线段属于曲线“对象”(也有自己的唯一ID)。然后,使用光线投射,我可以启用鼠标线冲突检测,并知道单个线段何时被“击中”——并高亮显示(例如,

这不是关于如何创建和渲染曲线(例如Bezeier、NURBS等),而是关于当鼠标光标悬停在此类曲线的任何部分上时,如何通过鼠标单击以交互方式“拾取”此类曲线

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

我特意将每个GL_线段创建为单独的实体(每个都指定了自己的唯一ID号)。这些线段属于曲线“对象”(也有自己的唯一ID)。然后,使用光线投射,我可以启用鼠标线冲突检测,并知道单个线段何时被“击中”——并高亮显示(例如,临时更改其颜色)。 但同时也高亮显示属于该曲线的所有其他线段,从而显示选定的整个曲线的外观

问题在于,由于每条曲线不仅由有效定义曲线的“核心”控制点组成,而且还由有效绘制曲线的数千个点组成,因此图形性能很快会显著降低

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


那么……如何在OpenGL中更有效地“拾取”曲线呢?

您有两个明显的选择:

  • 使用ID缓冲区

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

    这是像素级的完美,而且
    O(1)
    super-fast。。。但是,如果对象太薄,则使用它从单个像素进行鼠标拾取时可能会遇到问题,因此请在距离鼠标一定距离的范围内进行测试(您可以
    glReadPixels
    rectangle-around-mouse)end返回当前的所有ID或最常返回的ID

    见此:

    不要忘记在渲染之前清除ID缓冲区,如果有太多的对象无法放入8位模具,请使用不同的缓冲区。。。在2D的情况下,您可以使用深度缓冲区,或者您可以在两次过程中渲染到RGBA framebufer,首先将ID读取到CPU端内存,然后进行十次普通渲染。您还可以渲染到纹理

  • 计算到曲线的距离

    它是可行的,例如见:

    正如您所看到的,它也可以用于渲染本身(没有直线近似,只有“完美”曲线),甚至可以使用速度

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


  • 谢谢Spektre。但是,为了清楚起见,您是说,对于建议的选项(1),绘制的每条曲线都应该特意指定一种稍微不同的颜色?这对我不起作用,因为我需要所有曲线都呈现相同的颜色。@DavidH不,你通常有
    RGBA
    Depth
    缓冲区,只需再添加一个…所以当你渲染任何像素时,它会将颜色设置为
    RGBA
    缓冲区,深度设置为
    Depth
    缓冲区和曲线ID(可以是数组中的订单号或任何内容)在第三个缓冲区。如果使用模具进行此操作,则OpenGL 1.0可以自行完成此操作,但是较新的gfx驱动程序仅适用于8位模具,限制为255个唯一ID和1个空空间,因此如果这还不够,则需要使用着色器或在2个过程中渲染(在这种情况下,您可以在第一次通过时为曲线设置不同的ID/颜色)。。。