How can I convert screen coordinatess to world coordinates in OpenTK?

I'm making a windows forms application with opengl view. I need to get the mouse coords converted to the opengl world coords. Well, my Y coord gets converted wrong. It's hard to explain, so here is the video: http://tinypic.com/r/23sal8k/6. I'm constantly pressing left mouse button and the red dot should be where the mouse is(but it isn't). Here is the code:

``````    private void glview_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point worldCoords = convertScreenToWorldCoords(e.X, e.Y);
shitx = worldCoords.X;
shity = worldCoords.Y;
}
}

// functions:
public static Point convertScreenToWorldCoords(int x, int y)
{
int[] viewport = new int[4];
Matrix4 modelViewMatrix, projectionMatrix;
GL.GetFloat(GetPName.ModelviewMatrix, out modelViewMatrix);
GL.GetFloat(GetPName.ProjectionMatrix, out projectionMatrix);
GL.GetInteger(GetPName.Viewport, viewport);
Vector2 mouse;
mouse.X = x;
mouse.Y = viewport[3] - y;
Vector4 vector = UnProject(ref projectionMatrix, modelViewMatrix, new Size(viewport[2], viewport[3]), mouse);
Point coords = new Point((int)vector.X, (int)vector.Y);
return coords;
}
public static Vector4 UnProject(ref Matrix4 projection, Matrix4 view, Size viewport, Vector2 mouse)
{
Vector4 vec;

vec.X = 2.0f * mouse.X / (float)viewport.Width - 1;
vec.Y = -(2.0f * mouse.Y / (float)viewport.Height - 1);
vec.Z = 0;
vec.W = 1.0f;

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;
}
``````
-

I changed

``````-(vec.Y = 2.0f * mouse.Y / (float)viewport.Height) - 1;
``````

to

``````-(vec.Y = 2.0f * mouse.Y / (float)viewport.Height) + 1;
``````

and it works.

-

I have exactly the same problem and have used your code. I think I fixed it fully now.

``````in ConvertScreenToWorld()
change
mouse.Y = viewport[3] - y;
to
mouse.Y = y;

in UnProject()
change
vec.Y = -(2.0f * mouse.Y / (float)viewport.Height - 1);
to
vec.Y = 2.0f * mouse.Y / (float)viewport.Height - 1;
``````

then call it like convertScreenToWorldCoords(e.X,ClientRectangle.Height - e.Y);

it's very precise too bye!

-

Finally, I got this fixed. I just changed

``````mouse.Y = viewport[3] - y;
``````

to

``````mouse.Y = y + (ClientRectangle.Height - glview.Size.Height);
``````

still not very accurate but not very bad.

-