The Z co-ordinate usually comes from a picking render or some kind of hit test. In order to correctly unproject a point, you need to know its distance in the scene.
As for getting model and projection matrices, see below. The method below takes mouse co-ordinates (from windows) and unprojects them. The `vertex’ parameter contains the x, y mouse co-ordinates and the z co-ordinate given by the picking render.
// Unproject the given mouse point back into the scene.
void CSelectionBuffer :: UnProjectMouse ( CVertex3D& Point, CVertex3D& Out )
// Finally, we need to reverse transform the values we have back into the world to get correct world x, y, z.
GLdouble Projection , Model ;
GLint Viewport ;
// Now get the matrices and viewport.
glGetDoublev ( GL_PROJECTION_MATRIX, Projection );
glGetDoublev ( GL_MODELVIEW_MATRIX, Model );
glGetIntegerv( GL_VIEWPORT, Viewport );
// We will need to invert mouse y (because its top left whereas our window is bottom left origin).
double Invert_m_y = static_cast<double> ( Viewport  ) - static_cast<double> ( Point.v  );
HITRECORD h1, h2;
// Inverse transform the given point - note its important that the viewing transforms are setup as they were rendered.
gluUnProject ( static_cast<double> ( Point.v  ), // Mouse x.
Invert_m_y, // Inverted mouse y.
0.0, // The z depth result we got from selection.
Model, // Model view matrix.
Projection, // Projection matrix.
Viewport, // Viewport co-ordinates.
&h1.x, // Final result x.
&h1.y, // Final result y.
&h1.z ); // Final result z.
// Copy results across ( from double to float ).
Out.v  = static_cast<float> ( h1.x );
Out.v  = static_cast<float> ( h1.y );
Out.v  = static_cast<float> ( h1.z );
[This message has been edited by Robbo (edited 05-24-2002).]
Well, some source-code would be nice - we need to see how you get your z and what your screen x, y are. Also, how you unproject. Don’t forget that your transform (model) matrix must be the same when you unproject as it was when you rendered the scene in the first place. ie: