I use OpenTK to play in C #, and it does not have project and non-project functions that convert between world and screen coordinates. Well, it is, but they are outdated, and I could not get them to work. I made an attempt to implement them myself based on the opengl spec (see Menu on the left, gluProject and gluUnProject and viewing in FF, not Chrome). See. These formulas, I try to compare them. My functions do not work at all, the points returned by Project are almost in the center of my screen and very close to each other, although I move my point of the world everywhere.
Note that OpenTK math lib does not include functions for multiplying a matrix by a vector, so I just made a matrix row of vector points for each record in the resulting vector (which is right, isn’t it?)
public static Vector3d Project(Vector4d point, Matrix4d projection, Matrix4d modelview, int[] view)
{
Matrix4d temp = Matrix4d.Mult(projection, modelview);
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);
return new Vector3d(
Vector4d.Dot(inv.Row0, vect),
Vector4d.Dot(inv.Row1, vect),
Vector4d.Dot(inv.Row2, vect)
);
}