如何将鼠标位置从SFML转换为OpenGL坐标

How can I convert mouse Position from SFML to OpenGL coordinate?

本文关键字:转换 OpenGL 坐标 SFML 鼠标 位置      更新时间:2023-10-16

我想在鼠标位置后面移动一个框,但我不知道如何将从sf::mouse::getPosition()获得的位置转换为OpenGL 中的坐标

如果可以,请尝试使用GLU库中的gluUnproject函数。否则,您需要通过计算模型视图和投影的逆矩阵来重新实现它,然后将它们按相反的顺序(即逆投影,然后逆模型视图)应用到屏幕点。您可能需要添加一个额外的步骤来将窗口画布坐标转换回投影屏幕坐标(该步骤取决于您的投影设置)。

我在回答中提供了一个使用SDL和gluUnproject的示例程序。

注意:

  • 通过以相反的顺序成功地应用相反的变换,可以简单地计算模型视图的逆。

    例如,如果您首先通过平移,然后通过旋转将模型视图从身份设置为&lt-a、 -b,-c>旋转,然后应用&lt-x、 -y,-z>平移以获得反向模型视图。

  • 对于投影逆矩阵,红皮书附录F——gamedev.net页面的指针礼貌(尽管链接在那里断了)——给出了一个解决方案。

这只会为您提供矩阵,以便从同质opengl投影空间取消投影一个点。你需要先从这个空间中选择一个点。这一点可以使用首先转换回投影空间的屏幕来选择。在我的例子中,这涉及到翻转关于画布维度的坐标(但另一种投影设置可能会有所不同),然后通过添加精心选择的z分量将其扩展到3D。

也就是说,在另一个问题的示例程序中,目标是将穿过投影像素的光线投射到场景中,计算出从该线到场景中的点的距离,并选择最近的一个。注意到鼠标总是在相机投影平面中移动,您可能可以避免整个不投影的业务。因此,对象的平移矢量必须由相机的XY单位矢量组成(我假设Z是垂直于屏幕的轴,就像OpenGL中常见的那样),两者都按因子缩放,具体取决于对象到相机的距离。

你会得到这样的东西:

    +--------+   object translation plane
    |        /
    |       /
    |      /
    |     /
    +----+  screen plane
    |    /
    |   /
    |  /
    | /
    + camera eye position

您可以从Intercept定理获得缩放因子,并从模型视图矩阵的第一列和第二列获得XY相机向量。

最终的翻译矢量应该是如下的东西:

T = f * (dx * X + dy * Y)

其中f是缩放因子,XY是相机矢量,<dx,dy>是投影空间中的鼠标坐标delta矢量。

您知道窗口的分辨率,以及鼠标相对于窗口的位置。从中可以确定[0,1]中的归一化坐标。从该坐标,可以将光线投影到场景中,并使用投影*视图矩阵的倒数,可以将其转化为世界空间光线。

然后,由您将世界空间光线与场景对象相交(通过碰撞检测),以确定"单击"的对象(请注意,由于深度的原因,可能会有多个对象;通常您想要最接近的对象)。这一切都取决于你如何组织场景的空间信息,如果你有一些空间划分结构(例如八叉树或BSP)用于快速剔除,并在"场景对象"上简化边界框(例如AABB或球体)用于快速宽阶段,这一切都会更快。

我想说更多,但"OpenGL中的坐标"是高度未指定的。通常,你不仅对坐标感兴趣,还对它有意义地属于的"场景对象"以及一大堆其他属性感兴趣。