Cant get gluUnProject to work

Hi, I have a probelm getting gluUnproject to work to translate mouse screen coordinates to world coordinates.

I’ve read the positings related but the code dosen’t give me the values I expect.

gl.glGetIntegerv( GL.GL_VIEWPORT, viewport );
gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, model);
gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, proj);
double[] objX = new double[]{-1};
double[] objY = new double[]{-1};
double[] objZ = new double[]{-1};
glu.gluUnProject(sx, vp[3]-sy, 1, model, proj, viewport, objX, objY, objZ);

I don’t know what I’m missing.

Can anybody help.

Thanks.

Random guess: You’re trying to unproject mouse location back into 3d space, and you’re attempting to do it in mousePressed() or similar AWT event. This won’t work since all calls to the OpenGL canvas have to be made from a single thread (the one that is driven by the Animator typically).

No. In the mouse handler I set a flag and call the canvas.display() function, during which call the unproject code since the flag is set.

The code seems right. What kind of values are you getting?

In that case, check you’re calling it after you’ve set your projection and camera matrices.

Ok. I get x values in the correct range but reversed. That is for mouseX near zero I get world coordinates slightly larger than worldRight, and for mouseX near viewport width then I get values near (but not equal to) worldLeft. The y values are somewhat different as they are in the correct range amd scale ok from mouseY near zero to mouse near viewport height, however the actual numbers are off maybe 10%.

Also I’ve just noticed that as I zoom in to my view using the glu.lookat function the values returned by unproject are the same. However I am using the projection nd modelview matrices after the lookat fuction has been called and this I would expect that nay change would be reflected in the matrices.

I’m not a 3D graphics programmer so it seems I’m missing a lot of stuff here.

Any thought of what I can try.

John

hmm, now that is slightly odd behaviour. For the x, I’d check if you’re setting up your projection correctly, like accidentally swapping the left & right args to glOrtho or similar. For the y, are you perhaps getting the coords for the entire window (title bar and all) and not just the canvas?

Edit: When you say you’re using the matrices after setting up the view, do you mean you get them, set up view then unproject? Or set up view, get matrices then unproject? If you do the first it won’t work because you’ve actually got a copy of the matrices at that particular point. That or I’m reading your post wrong…

Ok. Some code.

In the display method:

display()
{



// PositionCamera
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(fov_y, aspect, near_z, far_z);

gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(eye[0], eye[1], eye[2],lookat[0], lookat[1], lookat[2], 0.0f, 1.0f, 0.0f);

/* Save projection and modelview matrices for later use */
gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, model);
gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, proj);




if (mousepressed)
{
call unproject()
}


int worldLeft = (int)camera.worldLeft;
int worldRight = (int)camera.worldRight;
int worldBottom = (int)camera.worldBottom;
int worldTop = (int)camera.worldTop;

gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glBindTexture(GL.GL_TEXTURE_2D, terrainTextureId[0]);
gl.glDisable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_ALWAYS);
gl.glEnable(GL.GL_ALPHA_TEST);
gl.glAlphaFunc(GL.GL_GREATER, 0.0f);
gl.glBegin(GL.GL_QUADS);
gl.glTexCoord2f(0f, 0f);gl.glVertex3f(worldLeft, 1f, worldBottom);
gl.glTexCoord2f(0f,1f);gl.glVertex3f(worldLeft, 1f, worldTop);
gl.glTexCoord2f(1f,1f);gl.glVertex3f(worldRight, 1f, worldTop);
gl.glTexCoord2f(1f,0f);gl.glVertex3f(worldRight, 1f, worldBottom);
gl.glEnd();
gl.glDisable(GL.GL_TEXTURE_2D);

}

Now to zoom in I change the eye[] values and call canvas.display(). This seems to work although I get some unexpected results sometimes, but that’s another matter.

Can anybody see what I’m doing wrong

Just a thought. Does it matter that I’m using the gluLookAt function to set the view.

Also the z values for input 0 or 1. Which one do I use or do I use both and do some computation on the values returned to arrive at the answer.

Another thought. Do I have to be in SELECT mode or RENDER mode for UnProject to work, or is it irrelant?

Thanks in advance for any thoughts, I’m stumped. Even another way fr me to tell the boundaries in world coordinates of my scene.

gluLookAt just sets the projection matrix for you, after that its no different to setting it yourself. SELECT or RENDER shouldn’t matter since the matrices will be the same for both.

For the depth, the usual way is to unproject with two different depths and form a line between the two - this then represents all the possible click locations (since you’re going 2D->3D you have to add an extra dimension somehow). Then you can use that line to figure out on the world where you actually clicked (like testing where it intersects with a ground plane or similar). Perhaps this is your problem?

Ok. How would I do this intersection checking. Can you point me to stuff that I can readup on or any code that does this.

John

Depends on what kind of testing you need - David Eberly, being the nice bloke he is, has a whole bunch of handy source code to go with his books which you can look at for intersection testing:

http://www.magic-software.com/SourceCode.html

Thanks. I’ll try it.