我想移动一个方框跟随鼠标位置,但我不知道如何将我从sf :: Mouse :: getPosition()获得的位置转换为OpenGL中的坐标
答案 0 :(得分:2)
如果可以,请尝试使用GLU库中的gluUnproject
功能。否则,您需要通过计算模型视图和投影的逆矩阵来重新实现它,然后以相反的顺序(即反向投影然后反向模型视图)将它们应用到您的屏幕点。您可能需要添加额外的步骤才能将窗口画布坐标转换回投影屏幕坐标(该步骤取决于您的投影设置)。
我在that answer中使用SDL和gluUnproject
提供了示例程序。
请注意:
可以通过以相反的顺序连续应用对立变换来平凡地计算模型视图逆。
例如,如果您首先通过翻译设置模型视图,然后进行轮换,那么您需要做的就是将其设置为< -a,-b,-c>旋转,然后应用< -x,-y,-z>翻译以获得逆模型视图。
对于投影逆矩阵,the red book appendix F - that gamedev.net page的指针礼貌(尽管链接在那里被破坏) - 给出了解决方案。
这只会为您提供从齐次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>
鼠标坐标投影空间中的delta矢量。
答案 1 :(得分:1)
您知道窗口分辨率以及相对于窗口的鼠标位置。从那里你可以确定[0,1]中的标准化坐标。然后,您可以从此坐标将光线投影到场景中,并使用投影*视图矩阵的反转,将其转换为世界空间光线。
然后由您将世界空间光线与场景对象相交(通过碰撞检测)以确定“点击”对象(请注意,由于深度可能存在多个;通常您希望距离最近击中)。这一切都取决于你如何组织你的场景的空间信息,如果你有一些空间分区结构(例如八叉树或BSP)用于快速剔除和简化你的“场景对象”上的边界框(例如AABB或球体),这一切都会更快为了快速的广泛阶段。
我会说更多,但“OpenGL中的坐标”是非常不明确的。通常,您不仅对坐标感兴趣,还对它有意义的“场景对象”以及其他一系列属性感兴趣。