Hi all, could anyone explain me how to use ray-picking and if possible give some source-code as an example.
I have an other question, is it true that the stack when using name picking is limited to 64 names?
Thanks y’all
C ya
Hi all, could anyone explain me how to use ray-picking and if possible give some source-code as an example.
I have an other question, is it true that the stack when using name picking is limited to 64 names?
Thanks y’all
C ya
Someone else here has shared a Picking utility that might help you.
As to the limits on the name stack, the actual max depth is dependent on your OpenGL implementation, but must be at least 64. You can use glGet( GL.GL_MAX_NAME_STACK_DEPTH ) to find out how far yours can go.
Nice, but I don’t use lw-jgl, I use Jogl so I don’t know what the methods clear etc are…
What I need is a jogl designed picking using ray-throwing.
Thanks for your answer, but according to Jogl api, the function glGet() does not even exist!
See ya
oops! Hadn’t spotted before that the picking utility is for LWJGL.
At any rate, the OpenGL calls are pretty much identical between JOGL and LWJGL, so it wouldn’t be too hard to do a mechanical translation between LWJGL’s glDoWhatever(… and JOGL’s gl.glDoWhatever(…
As to glGet(), I was being imprecise (again ::)), the exact call you need is
int[] array = new int[ 1 ];
gl.glGetIntegerv( GL.GL_MAX_NAME_STACK, array );
System.out.println( "Back off buddy! I got " + array[ 0 ] + " elements of namestack over here and I aint afraid to use em!" );
Other than that, there’s been a fair few threads on the JOGL forum about picking, you might want to peruse them for tips.
Thanks, according to your code, I can use 64 names which is not enough for me
What I want is getting the coordinates in the space by intersecting a ray with a plan :-\
Until now, I’ve failed in finding any example about that methode.
Thanks again.
C ya
Hi antoinelechacal,
As I understand it (which may be badly, I am a noob ;)), the 64 limit is on the name stack depth, not a limit on the total number of names. I get the impression from your posts that you want to pick from a very large number of objects, and I think you can. For example:
gl.glInitNames();
for (int i=0; i<1000; i++)
{
gl.glPushName(i);
drawObject(i); // Your code for drawing object i
gl.glPopName();
}
This example is picking from 1000 objects, but the depth of the name stack is never more than 1.
This excellent OpenGL tutorial might help: http://www.lighthouse3d.com/opengl/picking/
Beware: I haven’t tested this because I’m at work. I’ll try testing at home tonight if I get the chance, because I’m not 100% sure what I’m saying is correct.
[EDIT: I tried this out, picking seemed to work fine with a large number of names.]
Hope you’re right…
As you understood, I want to pick a big number of names (small areas on a map).
At first I just wanted to get the coordinates on the ground, but if I can pick a big number of names, I will divide the map into a big number of small pickable areas.
I’ll keep looking for a ray picking solution but it’s good too know that I can pick a big number of names.
Thanks again.
Hi,
What about an unprojection to retrieve a world coordinate…
Doens’t this fill your needs?
What I want is to transform the mouse coordinates into a 3D point but I don’t manage to do this, because the gluunproject doesn’t seem to work that’s why I’m looking for a working example.
See ya
I think you have to use gluUnproject…
It must work but maybe with some modifications if you have overlapping objects.
What is your pb exactly?
here’s my code:
double[] modelview = new double[16];
double[] projection = new double[16];
int[] viewport = new int[4];
this.gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, modelview);
this.gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projection);
this.gl.glGetIntegerv(GL.GL_VIEWPORT, viewport);
double winX; winX=xMouse;
double winY; winY=yMouse;
winY = (double)viewport[3] - (double)winY;
double winZ; winZ=0;
//winX=winX/viewport[2];
//winY=winY/viewport[3];
double[] objX = new double[1];
double[] objY = new double[1];
double[] objZ = new double[1];
System.out.print("mouse pos: "+winX +" "+winY+" "+winZ);
glu.gluUnProject(
winX, winY, winZ,
modelview,
projection,
viewport,
objX, objY, objZ
);
System.out.println(" 3Dclik: "+(int)objX[0] + " " + (int)objY[0] + " " + (int)objZ[0]);
double intersecX=objX[0]-(objY[0]/(lookY-camY))*(lookX-camX);
double intersecZ=objZ[0]-(objY[0]/(lookY-camY))*(lookZ-camZ);
System.out.println("intersecX: "+(int)intersecX+" intersecZ: "+(int)intersecZ);
Point pt=new Point((int)intersecX,(int)intersecZ);
the point is : this.gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, modelview); this.gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projection); this.gl.glGetIntegerv(GL.GL_VIEWPORT, viewport); always return the same result even when the click changes.
This is quite normal since these don’t change when you click the mouse… at least if you don’t offcenter or move the camera…
The point you are missing, I think, if that you have to fill winZ with a correct value instead of using 0. You can read the correct value from the Depth Buffer.
float[] winZ = new float[1];
gl.glReadPixels ( (int)winX, (int)winY, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, winZ );
I should work… at least I hope so!
I’ve tried to add your code, but it didn’t change anything: the problem is, gluLookAt always returns 0 for x y and z, and I don’t know why!
I’ve been stuck with picking for 3 weeks and I still don’t understand what’s wrong!
I don’t mange to find any opengl ray-picking example!
Are you sure that you call gluUnproject with a valid GL object (in the listener method?)
I don’t call it directly in the listener, I’ve read that there are some bugs when opengl routines are used in lesteners…
I call gluUnproject is called in my GlEventListener so the GL that call gluUnProject is the current one…
Any other idea?
I don’t know what to do!
Well, well, well…
Can you post again your corrected version of unprojection, I don’t see why it’s not working properly!
Well I’ve made a few progesses… The gluUnProject call return other values than 0, since we change winZ to anything else than 0 or 1.
That’s weird because the getPixel() call returns 0.
how can I get the correct value for winZ?
Thanks!
Hi antoinelechacal,
I think turquoise3232 knows what he’s talking about
I tried your code with his method of getting winZ (the “window space Z”) and it worked fine for me. In my display method:
// Draw something to unproject onto.
gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE, FLOOR_COLOUR);
gl.glBegin(GL.GL_POLYGON);
gl.glVertex3d(-2.0, -0.5, -2.0);
gl.glVertex3d(-2.0, -0.5, 2.0);
gl.glVertex3d(2.0, -0.5, 2.0);
gl.glVertex3d(2.0, -0.5, -2.0);
gl.glEnd();
double[] modelview = new double[16];
double[] projection = new double[16];
int[] viewport = new int[4];
gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, modelview);
gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projection);
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport);
// My mouse cursor is at a Point called “click”
int winX = click.x;
int winY = click.y;
winY = viewport[3] - winY;
float[] winZ = new float[1];
gl.glReadPixels ( (int)winX, (int)winY, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, winZ );
System.out.println("2D: " + winX + ", " + winY + ", " + winZ[0]);
double[] objX = new double[1];
double[] objY = new double[1];
double[] objZ = new double[1];
glu.gluUnProject(
winX, winY, winZ[0],
modelview,
projection,
viewport,
objX, objY, objZ
);
System.out.println("3D: " + objX[0] + ", " + objY[0] + ", " + objZ[0]);
// Draw a small sphere where the “unproject” lands
GLUT glut = new GLUT();
gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE, GLOBULE_COLOUR);
gl.glPushMatrix();
gl.glTranslated(objX[0], objY[0], objZ[0]);
glut.glutSolidSphere(glu, 0.05, 6, 6);
gl.glPopMatrix();
I draw some “landscape” - a single polygon in this case - which causes the “window space Z” information to be stored in the depth buffer, then do the unproject (as per your code and turquoise3232’s), and then draw a small sphere at the resulting co-ordinates (so I can see it). I have a MouseMotionListener setting the value of “click” every frame - I move my mouse around and, hey presto, a little sphere tracks the surface of the “landscape”.
Try it!
[EDIT: there’s a brief FAQ item on gluUnProject here: http://www.opengl.org/resources/faq/technical/glu.htm]
Ok, everything is ok, thanks for your help guys, that’s great to find feedback here!
See ya