PDA

View Full Version : How to use gluUnproject



Schlogenburg
12-07-2000, 06:18 PM
I got 3d vertices on screen that the user is supposed to be able to select with the mouse. Now they should click on a point and select it.

Ok. Actually I don't know how to use gluUnproject, so I was hoping someone would know how to use it in my specific situation.

Here's my situation:
I simply have these points projected, in 3d, and I want to know the 2d screen coordinates of these points as they are projected and see them on the screen. That way I simply compare the mouse cursor to the point.

I'm not yet fluent enough with GL and MS VC++ to start from scratch with a function like this, I could quickly get lost in any errors I make. Could somebody give me the most simple usage of the function? I know how to get the mouse coords.

This would be greaty appreciated.

Gabriel
12-07-2000, 07:55 PM
gluUnProject is use to know the world space prosition relative to a window coordinate...

Like x & y on my gl window is giving me x',y' & z' in 3d space...

If I would be you, I would use selection buffer for your case...

Schlogenburg
12-08-2000, 01:49 PM
Hm.
Ok. Here's what I got.By the way, I am using
gluProject instead of gluUnProject.

Somehow this doesn't give me anything back into wx, wy, wz.

double wx,wy,wz;
GLfloat xa,ya,za;

double modelMatrix[16];
double projMatrix[16];
GLint viewport[4];

RenderCamera();

glGetDoublev(GL_MODELVIEW_MATRIX,modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX,projMatrix);
glGetIntegerv(GL_VIEWPORT,viewport);


GLfloat cx,cy,cz;
cx=0;
cy=0;
cz=0;

gluProject(cx,cy,cz, modelMatrix, projMatrix, viewport, &wx, &wy, &wz);


I'd appreciate any kind of help because I've been working on this for many months.

Kilam Malik
12-09-2000, 01:09 AM
One thing could be, that you read out the matrices after rendering the objects. So in the modelview and projection matrix the rotations and translations you did are stored. So it's maybe not the matrices you painted the objects with you want to pick.
For me it worked to save the matrices when rendering the pickable objects and use this matrices later at picking time.
gluProject is in your case the right thing, if you want to compare the picking in 2D as you described.

Kilam.

Nyko
12-09-2000, 06:02 AM
Check out this post: http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/001494.html
It might be just what you are looking for.

Take Care,

Nyko

[This message has been edited by Nyko (edited 12-09-2000).]

jwlee
12-09-2000, 07:01 AM
You might consider coloring your vertices, drawing them to the back buffer, get your mouse coordinates, read the color from the back buffer using glReadPixels (don't forget to invert the Y coordinate), match your found color with the color you've assigned to your vertice and you've now found which one was picked.

Here's some useful notes: http://www.opengl.org/developers/faqs/technical/color.htm?picking#first_hit

best
James

Schlogenburg
12-09-2000, 04:59 PM
Thanks for the link to the thread.
However I it is abut gluUnProject not gluProject. I've been through all other methods of selection, believe me. GL selection buffer, checking color under mouse button, and using angles&gemoetry. They either didn't work or didn't suit my needs.

If anybody has any examples of how to use gluProject, I would very greatly appreciate it!

12-09-2000, 06:14 PM
I just did this in a project. Provided your projection and modelview matrices are still represent the coordinate system you want when you calculate this, it will work.

first do this (copied from _OpenGL_Programming_):

glGetIntegerv( GL_VIEWPORT, viewport );
glGetDoublev( GL_MODELVIEW_MATRIX, mvmatrix );
glGetDoublev( GL_PROJECTION_MATRIX, projmatrix );
realy = viewport[3] - (GLint) y - 1;
gluUnProject( (GLdouble) x, (GLdouble) realy, 0.0, mvmatrix,
projmatrix, viewport, &wx1, &wy1, &wz1 );
gluUnProject( (GLdouble) x, (GLdouble) realy, 1.0, mvmatrix,
projmatrix, viewport, &wx2, &wy2, &wz2 );

You then have the endpoints of a line that represents all 3D places that mouse click could have been. Then, for each point, calculate the distance between this line and the point. Find the minimum, and you're done. In the case where two points tie, or are both reasonably close to zero distance from the line, then simply find which of the
two are closest to (wx1, wy1, wz1), which represents the point on the hither plane (the closest one to the eye is probably the one you clicked on.)

This isn't probably the best way to do this, but I know that it works, and works reasonably well.

eric.

Schlogenburg
12-09-2000, 06:37 PM
Good stuff, but I'm not entirely clear on your useage of variables.

so your saying that variables wx1 and wy1 and wz1 are the 3d points that are sent to me that I have clicked on. (gldouble) x and (gldouble) y are the mouse coords in 2d screen.

Right? Ok if I'm right about that then I am wondering, if I have clicked on empty space what will happen? how will I know and what will it send back to me?

thanks.

Schlogenburg
12-09-2000, 06:40 PM
just a quick correction, I said (gldouble) y and it is not quite that, it is a result of the view or whatever the calculation is that you did there. I trust it will work whatever it is.
then it is (gldouble)realy.

but then I leave x alone in a range of 0-639 for the 2d screen point, and pass the mouse's y screen coord to

realy(realy = viewport[3] - (GLint) y - 1 http://www.opengl.org/discussion_boards/ubb/wink.gif

I should have this straight now yes?

Schlogenburg
12-09-2000, 06:42 PM
and what is that happy face doing there next to the formula

jwlee
12-10-2000, 11:26 AM
Ah yes, the ray intersection method using gluUnproject. http://www.opengl.org/developers/faqs/technical/selection.htm

You use gluUnProject to get two points in 3D space. One where the mouse hit on the near plane, and one where the mouse hit on the far plane. I haven't been successful using this method. Are you using gluPerspective? And are there any magical settings for this function?

James



Originally posted by ericwagner:
I just did this in a project. Provided your projection and modelview matrices are still represent the coordinate system you want when you calculate this, it will work.

first do this (copied from _OpenGL_Programming_):

glGetIntegerv( GL_VIEWPORT, viewport );
glGetDoublev( GL_MODELVIEW_MATRIX, mvmatrix );
glGetDoublev( GL_PROJECTION_MATRIX, projmatrix );
realy = viewport[3] - (GLint) y - 1;
gluUnProject( (GLdouble) x, (GLdouble) realy, 0.0, mvmatrix,
projmatrix, viewport, &wx1, &wy1, &wz1 );
gluUnProject( (GLdouble) x, (GLdouble) realy, 1.0, mvmatrix,
projmatrix, viewport, &wx2, &wy2, &wz2 );

You then have the endpoints of a line that represents all 3D places that mouse click could have been. Then, for each point, calculate the distance between this line and the point. Find the minimum, and you're done. In the case where two points tie, or are both reasonably close to zero distance from the line, then simply find which of the
two are closest to (wx1, wy1, wz1), which represents the point on the hither plane (the closest one to the eye is probably the one you clicked on.)

This isn't probably the best way to do this, but I know that it works, and works reasonably well.

eric.

Schlogenburg
12-10-2000, 12:31 PM
We're not talking about gluUnproject anymore, we're talking about gluProject. I think this one is easier to use.
I haven't yet implemented it but just so you know what it does, is it projects a 3d point into space, does not render it just 'projects' it and finds out where it would be on the screen in 2d. This is very usefull. I can cycle through all my points and just compare it with the mouse cursor.

I still need someone to answer my question . . what will it do if the 3d point is offscreen, I mean what will it give me.

Schlogenburg
12-10-2000, 02:36 PM
All I can say is . . .

YEAHH!!

it works!! months of work and it now works!@!!

fox
12-11-2000, 05:18 AM
how did you get it to work?

The Wolf
12-11-2000, 08:08 AM
Schlogenburg, I have the same implementation as you and it works ok for me. What is not working for you exaclty, how is it failing?
on thing I can see go wrong is if you do this:
1 - ClearBuffer
2 - LoadIdentity matrix
3- glpushmatrix
4- render camera
5- pop matrix
6- get 2d screen coord for (0,0,0) the problem is you'll be getting the modelview matrix for identity matrix
If that is not the problem, then lemme know exactly how it is failing. later -

[This message has been edited by The Wolf (edited 12-11-2000).]

Schlogenburg
12-11-2000, 09:47 AM
No problem anymore. I thought it was alot more hard then it was. It took me 3 or 4 months to settle on this function to do the selection routine for me. It is very accurate.

I think some one should make a tutorial about this, I've seen a lot of questions about this.

I tried these methods before:

- GL selection buffer
*didn't work for clicking & dragging
- Geometry angles, finding the angles you clicked at and casting a ray(just couldn't get that to work, I always got the axes mixed up)
- Making a function identicle(before I knew it was a glu function) to it myself, got too confusing

This new selection is short and simple. I recommend that it should be used.

Rather than going through other frustrations like I did.