【发布时间】:2010-08-20 04:03:52
【问题描述】:
我将 OpenTK 用于 C# 中的游戏,它不附带项目和取消项目功能,它们可以在世界坐标和屏幕坐标之间转换。嗯,确实如此,但它们已被弃用,我无法让它们工作。我根据opengl spec(见左侧菜单、gluProject 和 gluUnProject,并在 FF 中查看,而不是 Chrome)自己尝试实现它们。看到那些公式,我正在尝试匹配它们。我的函数根本不起作用,Project 返回的点都在我的屏幕中心附近,而且非常靠近,即使我正在到处移动我的世界点。
请注意,OpenTK 的数学库不包含用于将矩阵乘以向量的函数,因此我只是对结果向量中的每个条目进行矩阵行向量点积(这是正确的,不是吗?)
public static Vector3d Project(Vector4d point, Matrix4d projection, Matrix4d modelview, int[] view)
{
Matrix4d temp = Matrix4d.Mult(projection, modelview);
// multiply matrix by vector
Vector4d v_prime = new Vector4d(
Vector4d.Dot(temp.Row0, point),
Vector4d.Dot(temp.Row1, point),
Vector4d.Dot(temp.Row2, point),
Vector4d.Dot(temp.Row3, point)
);
v_prime = Vector4d.Divide(v_prime, v_prime.W);
return new Vector3d(
view[0] + view[2] * (v_prime.X + 1) / 2,
view[1] + view[3] * (v_prime.Y + 1) / 2,
(v_prime.Z + 1) / 2
);
}
public static Vector3d UnProject(Vector3d window, Matrix4d modelview, Matrix4d projection, int[] view)
{
Matrix4d inv = Matrix4d.Mult(projection, modelview);
inv.Invert();
double vx = (2 * (window.X - view[0])) / view[2] - 1;
double vy = (2 * (window.Y - view[1])) / view[3] - 1;
double vz = (2 * window.Z) - 1;
Vector4d vect = new Vector4d(vx, vy, vz, 1);
// now multiply matrix times vector, which is really row (dot) vector for each value
// correct, the bottom row of the inv matrix is unused
return new Vector3d(
Vector4d.Dot(inv.Row0, vect),
Vector4d.Dot(inv.Row1, vect),
Vector4d.Dot(inv.Row2, vect)
);
}
【问题讨论】:
-
OpenTK 确实有一个内置的 Matrix-times-Vector 函数。请参见 Vector4.Transform(ref vec, ref mat, out result)。它将矩阵 mat 应用于(乘)向量 vec 并将答案存储在结果中。
标签: c# opengl math matrix opentk