I need an OpenTK equivalent of gluUnproject in order to get 3D coordinates at the mouse position. I have cobbled this together (adapted from a couple of sources):
Vector3 v = GetOGLPos(e.X, e.Y);
Vector3 GetOGLPos(int x, int y)
{
Matrix4 projection = new Matrix4(); Matrix4 modelview = new Matrix4(); Size viewport = new Size(glControl1.Width, glControl1.Height); float winX=0, winY=0, winZ=0;
GL.GetFloat(GetPName.ModelviewMatrix, out modelview); GL.GetFloat(GetPName.ProjectionMatrix, out projection);
winX = (float)x; winY = viewport.Height - (float)y; GL.ReadPixels(x, (int)winY, 1, 1,PixelFormat.DepthComponent, PixelType.Float, ref winZ);
Vector4 vec = UnProject(ref modelview, ref projection, ref viewport, new Vector3(winX,winY,winZ)); return new Vector3(vec.X, vec.Y, vec.Z); }
private static Vector4 UnProject(ref Matrix4 projection, ref Matrix4 view, ref Size viewport, Vector3 mouse)
{
Vector4 vec;
vec.X = 2f * mouse.X / (float)viewport.Width - 1; vec.Y = -(2f * mouse.Y / (float)viewport.Height - 1); vec.Z = 2f * mouse.Z - 1f; vec.W = 1f;
Matrix4 viewInv = Matrix4.Invert(view); Matrix4 projInv = Matrix4.Invert(projection);
Vector4.Transform(ref vec, ref projInv, out vec); Vector4.Transform(ref vec, ref viewInv, out vec);
if (vec.W > float.Epsilon || vec.W < float.Epsilon) { vec.X /= vec.W; vec.Y /= vec.W; vec.Z /= vec.W; }
return vec; }
It’s not working. It does something, but z is always 1. Can anyone help?