如何将2D显示坐标映射到3D OpenGL空间

我正在开发一款移植到Android上的3D游戏,我希望在3D游戏过程中使用触摸事件。 我需要3D空间中的点,就在靠近剪裁平面上,但我能得到的只是来自Android显示器的2D坐标。 那么,有没有办法将这些(x,y)坐标映射到3D空间中的(x,y,z)坐标?

编辑

好吧,我正在制作一个赛车游戏,我想在课程中插入一些项目,具体取决于我点击的位置。 我有这个function:

void racing_mouse_cb(int button, int state, int x, int y) { //parameters (x,y) are coords of a display set_ill_fish(get_player_data( local_player())->view); } 

但是现在我在一个距离的玩家面前插入物品:

 void set_ill_fish(view_t view) { item_locs[num_items].ray.pt.x = view.plyr_pos.x; item_locs[num_items].ray.pt.z = view.plyr_pos.z - 5; item_locs[num_items].ray.pt.y = find_y_coord(view.plyr_pos.x, view.plyr_pos.z - 5) + 0.2; item_locs[num_items].ray.vec = make_vector(0, 1, 0); . . . } 

,但如何将其转化为显示表面,我无能为力。

要将2D显示坐标(display_x, display_y)重新映射到3D对象坐标(x,y,z)您需要知道

  1. (display_x, display_y)处像素的深度display_z
  2. 转换T将剪辑空间坐标(clip_x, clip_y, clip_z)为显示坐标
  3. 将对象坐标转换为剪辑空间坐标的转换M (通常将相机和透视图组合在一起)

显示坐标计算如下

 M.transform(x, y, z, 1) --> (clip_x, clip_y, clip_z, clip_w) T.transform(clip_x / clip_w, clip_y / clip_w, clip_z / clip_w) --> (display_x, display_y, display_z) 

M.transform是一个可逆矩阵乘法,而T.transform是任何可逆变换。

您可以按如下方式从(display_x, display_y, display_z)恢复(x,y,z)

 T.inverse_transform(display_x, display_y, display_z) --> (a, b, c) M.inverse_transform(a, b, c, 1) --> (X, Y, Z, W) (X/W, Y/W, Z/W) --> (x, y, z) 

以下给出了上述计算导致正确解决方案的直觉

 T.inverse_transform(display_x, display_y, display_z) --> (clip_x / clip_w, clip_y / clip_w, clip_z / clip_w) (clip_x / clip_w, clip_y / clip_w, clip_z / clip_w, clip_w / clip_w) == (clip_x, clip_y, clip_z, clip_w) / clip_w M.inverse_transform((clip_x, clip_y, clip_z, clip_w) / clip_w) == M.inverse_transform(clip_x, clip_y, clip_z, clip_w) / clip_w M.inverse_transform(clip_x, clip_y, clip_z, clip_w) / clip_w --> (x, y, z, 1) / clip_w (x, y, z, 1) / clip_w == (x / clip_w, y / clip_w, z / clip_w, 1 / clip_w) (x / clip_w, y / clip_w, z / clip_w, 1 / clip_w) == (X, Y, Z, W) 

以上使用了以下矩阵( M )向量( v )标量( a == 1 / clip_w )属性:

 M * (a * v) == a * (M * v)