我想跟随鼠标位置移动一个框,但我不知道如何将从 sf::Mouse::getPosition() 获得的位置转换为 OpenGL 中的坐标
2 回答
如果可以,请尝试使用gluUnproject
GLU 库中的函数。否则,您将需要通过计算模型视图和投影的逆矩阵来重新实现它,然后以相反的顺序(即反向投影然后反向模型视图)将它们应用到您的屏幕点。您可能需要添加一个额外的步骤来将窗口画布坐标转换回投影屏幕坐标(该步骤取决于您的投影设置)。
gluUnproject
我在那个答案中提供了一个使用 SDL 的示例程序。
注意:
通过以相反的顺序依次应用相反的变换,可以简单地计算模型视图的逆。
例如,如果您首先通过平移设置模型视图,然后是旋转,您需要做的就是将其设置为 <-a,-b,-c> 旋转,然后应用 <-x, -y,-z> 翻译以获得逆模型视图。
对于投影逆矩阵,红皮书附录 F -该 gamedev.net 页面的指针礼貌(尽管链接在那里断开) - 给出了解决方案。
这只会为您提供从齐次 opengl 投影空间中取消投影点的矩阵。您首先需要从该空间中选择一个点。可以使用首先转换回投影空间的屏幕坐标来选择该点。在我的示例中,这涉及到相对于画布尺寸翻转坐标(但使用另一种投影设置可能会有所不同),然后通过添加精心挑选的 z 分量将它们扩展到 3D。
也就是说,在另一个问题的示例程序中,目标是将穿过投影像素的光线投射到场景中,并计算出从该线到场景中点的距离,然后选择最近的那个。通过注意到鼠标总是在相机投影计划中移动,您可能可以避免整个非投影业务。因此,物体的平移向量必须由相机的X和Y单位向量组成(我假设Z是垂直于屏幕的轴,就像在 OpenGL 中一样),两者都根据距离进行缩放对象到相机。
你会得到类似的东西:
+--------+ object translation plane
| /
| /
| /
| /
+----+ screen plane
| /
| /
| /
| /
+ camera eye position
您可以从Intercept theorem获得缩放因子,并从模型视图矩阵的第一列和第二列获得X和Y相机向量。
最终的翻译向量应该是这样的:
T = f * (dx * X + dy * Y)
其中f
是缩放因子、X
相机Y
向量和<dx,dy>
鼠标坐标在投影空间中的增量向量。
你知道你的窗口分辨率,以及鼠标相对于窗口的位置。从那里您可以确定 [0,1] 中的归一化坐标。然后,您可以从该坐标将光线投影到场景中,并使用投影*视图矩阵的逆矩阵,将其转换为世界空间光线。
然后由您决定将世界空间光线与场景对象相交(通过碰撞检测)以确定“点击”对象(请注意,由于深度的原因可能不止一个;通常您想要最近的命中)。这一切都取决于您如何组织场景的空间信息,如果您在“场景对象”上有一些空间分区结构(例如八叉树或 BSP)用于快速剔除和简化边界框(例如 AABB 或球体),这一切都会变得更快一个快速的广泛阶段。
我想说的更多,但是“OpenGL 中的坐标”是高度未指定的。通常,您不仅对坐标感兴趣,而且对它有意义所属的“场景对象”以及一大堆其他属性感兴趣。