Skip to main content
GameDev.net gamedev.net
🔒 Locked

about gluUnProject

Started by xiongyouyi Mar 22, 2009 at 4:03 AM 4 replies 1.3k views
Original Post
xiongyouyi
xiongyouyi
I draw a point, then click it, use gluUnProject to convert screen coordinates to world coordinates, this is the code here: void display() { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity (); glTranslatef(0.0f, 0.0f, -2.0f); glColor3f( 1.0f, 1.0f, 1.0f ); glPointSize( 3.0f ); // draw a point glBegin( GL_POINTS ); glVertex3f( 0.0f, 0.0f, 0.0f ); glEnd(); // Click the point, get its world coordinates if ( MOUSE_BUTTON == GLUT_LEFT_BUTTON ) { double posX,posY,posZ; screen2world( MOUSE_POS_X, MOUSE_POS_Y, &posX, &posY, &posZ ); MOUSE_BUTTON = -1; } } void screen2world( int x, int y, double * posX, double * posY, double * posZ ) { GLint viewport[ 4 ]; GLdouble projection[ 16 ]; GLdouble modelview[ 16 ]; GLfloat winX,winY,winZ; glGetIntegerv( GL_VIEWPORT, viewport ); glGetDoublev( GL_PROJECTION_MATRIX, projection ); glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); winX = (GLfloat)x; winY = (GLfloat)( viewport[3] - y ); glReadBuffer(GL_BACK); glReadPixels( winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ ); gluUnProject( winX, winY, winZ, modelview, projection, viewport, posX, posY, posZ ); printf( "screen = %f,%f,%f\n", winX, winY, winZ ); printf( "world = %f,%f,%f\n", *posX, *posY, *posZ ); } When i click the point, the posZ is alway zero, I think it will be -2.0, before i draw it, it was translated -2.0, why the result is zero? Thanks!
knighty
knighty
That's the expected behaviour of gluUnProject().
It returns 0.0 z-coordinate because the modelview matrix is used to transforme the model from the model-space to the camera-space. So gluUnProject() uses the inverse of the modelview-matrix to transform back to the model-space. So you end up where you begin: (0.0,0.0,0.0).

In your case, if you send an identity-matrix as modelview-matrix to gluUnProjet() you will get what you expect (I think (0.0,0.0,-2.0) ).

In OpenGL there is no model-matrix nor view-matrix. There is only a modelview-matrix. OpenGL does not discern world-space and camera-space. They are packed together. It's up to the programmer to split the transformation process into model-space->world-space and world-space->camera-space. (by "space" I mean coordinates system)

There are many question (In this forum and others) that are related to this fact.

It's also a good practice to add a glFlush() (or glFinsh()) after the draw calls.
xiongyouyi
xiongyouyi
Thanks for your reply!
In screen2world(), I print the modelview_matrix, the result is
1.0, 0.0, 0.0, 0.0
0.0, 1.0, 0.0, 0.0
0.0, 0.0, 1.0, 0.0
0.0, 0.0, -2.0, 1.0

but i got z value as zero,
so if I write code like this:

{
......
glTranslatef(0.0f, 0.0f, -2.0f); //M1

glPushMatrix();
{
glTranslatef(0.0f, 0.0f, -1.0f);//M2

// draw a point
glBegin( GL_POINTS );
glVertex3f( 0.0f, 0.0f, 0.0f );
glEnd();
}
glPopMatrix();

//screen to world
//M3
.......
}

print M3(modelview_matrix):
1.0, 0.0, 0.0, 0.0
0.0, 1.0, 0.0, 0.0
0.0, 0.0, 1.0, 0.0
0.0, 0.0, -2.0, 1.0

It's same as above, but i got z -1.0.
In the two different ways, I give the same value(modelview_matrix, projection_matrix, viewport) to gluUnProject,
why i get the different z value?
thanks!

knighty
knighty
First: the modelview matrix is actually the transpose of what is printed by your function.

Second: well! you did right! the output is correct.

Think of what is the result of
glPushMatrix();{glTranslatef(0.0f, 0.0f, -1.0f);//M2// draw a pointglBegin( GL_POINTS ); glVertex3f( 0.0f, 0.0f, 0.0f ); glEnd(); }

the point wich initial coordinates were (0,0,0) have after translation the coordinates (0,0,-1). you can replace this section of code by:
// draw a pointglBegin( GL_POINTS ); glVertex3f( 0.0f, 0.0f, -1.0f ); glEnd(); 

and obtain exactly the same result.

Assume (in your code not the ones above) the first transform (M1) gives the view matrix (transforming coordinates from world space to camera space) and the second (M2) the model matrix (transforming the coordinates from model space to world space). You pass the view matrix to gluUnProject() so it returns the coordinates in world space.

Forget of what is called GL_MODELVIEW_MATRIX by OpenGL. call it just transformation-matrix and give it the meaning you want.
xiongyouyi
xiongyouyi
It's hard to understand the gluUnProject.
I know how to get the result what i want,
I wondered why i give the different matrix value to gluUnProject,
but it always return z value of zero,

glTranslatef(0.0f, 0.0f, z_value);

// draw a point
glBegin( GL_POINTS );
glVertex3f( 0.0f, 0.0f, 0.0f );
glEnd();

//screen to world
if i change the z_value, the modelview_matirx is chenged too,
but gluUnProject always return z as zero.

Maybe my mind run into dead ends.
Thanks for your patient answers!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.