I have this view set:
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
and I get a screen position (sx, sy) from a mouse click.
Given a value of z, how can I calculate x and y in 3d-space from sx and sy?
OpenGL: OpenGL is a cross-language, cross-platform API for rendering 2D and 3D Vector Graphics. It will make a lot of design as well as animations using this. Create a circle anywhere on the console using a single left mouse click and the coordinates of the center of the circle created depends on the position of your click.
Approach: The idea is to use the below inbuilt function to draw the circle using single click in OpenGL: glMatrixMode (GL_PROJECTION): This function sets the current matrix to projection.
Overview It can be useful to click on, or "pick" a 3d object in our scene using the mouse cursor. One way of doing thisis to project a 3d ray from the mouse, through the camera, into the scene, and then check if that ray intersects with any objects. This is usually called ray casting.
This is usually called ray casting. This is an entirely mathematical exercise - we don't use any OpenGL code or draw any graphics- this means that it will apply to any 3d application the same way. The mathematical subject is usually called geometric intersection testing.
You should use gluUnProject
:
First, compute the "unprojection" to the near plane:
GLdouble modelMatrix[16];
GLdouble projMatrix[16];
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
GLdouble x, y, z;
gluUnProject(sx, viewport[1] + viewport[3] - sy, 0, modelMatrix, projMatrix, viewport, &x, &y, &z);
and then to the far plane:
// replace the above gluUnProject call with
gluUnProject(sx, viewport[1] + viewport[3] - sy, 1, modelMatrix, projMatrix, viewport, &x, &y, &z);
Now you've got a line in world coordinates that traces out all possible points you could have been clicking on. So now you just need to interpolate: suppose you're given the z-coordinate:
GLfloat nearv[3], farv[3]; // already computed as above
if(nearv[2] == farv[2]) // this means we have no solutions
return;
GLfloat t = (nearv[2] - z) / (nearv[2] - farv[2]);
// so here are the desired (x, y) coordinates
GLfloat x = nearv[0] + (farv[0] - nearv[0]) * t,
y = nearv[1] + (farv[1] - nearv[1]) * t;
This is best answered by the most authoritative source, OpenGL's web site.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With