gluUnProject/gluLookAt help

For my first project using jogl I decided to make just a simple 3d checkers game, but I have been having trouble with gluUnProject

Here is the view I am using

Here is the code I am currently using:


        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
        gl.glLoadIdentity();
        
        glu.gluLookAt(-150.0f, 150.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

        int viewport[] = new int[4];
        double mvmatrix[] = new double[16];
        double projmatrix[] = new double[16];
        int realy = 0;// GL y coord pos
        double wcoordN[] = new double[4];
        double wcoordF[] = new double[4];
        
        if (mouse != null){
        	int x = mouse.getX(), y = mouse.getY();
        	gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
        	gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, mvmatrix, 0);
        	gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projmatrix, 0);
        	
        	// note viewport[3] is height of window in pixels
        	realy = viewport[3] - (int) y - 1;

        	glu.gluUnProject((double) x, (double) realy, 0.4, mvmatrix, 0, projmatrix, 0, viewport, 0, wcoordN, 0);
        	glu.gluUnProject((double) x, (double) realy, 0.9, mvmatrix, 0, projmatrix, 0, viewport, 0, wcoordF, 0);
        }

The problem is I can’t seem to figure out what to actually do with the results of gluUnProject… or even if I am getting the right results. Any help would be appreciated

Hi, I think it depends on what you want to make with gluUnproject…

If it’s about getting world coordinates from screen coordinates I suggest you look at the following thread : http://www.java-gaming.org/forums/index.php?topic=11437.

What I would really like to do is get the coordinates of the mouse at the location of the checkerboard, I’m not really sure how exactly to go about this as I just starting working with jogl and openGL a day or two ago.

I assume you want to have the world coordinates under the mouse.

So you have to get the correct z value before calling gluUnpoject.

gl.glReadPixels ( clickX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, winZ );

The link I gave you should cover all in details if i remember well.

I always get this error when trying to use readPixels:


Exception in thread "Thread-2" javax.media.opengl.GLException: javax.media.opengl.GLException: Required extensions not available to call this function
	at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:271)
	at javax.media.opengl.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:256)
	at javax.media.opengl.GLCanvas.display(GLCanvas.java:130)
	at com.sun.opengl.util.Animator.display(Animator.java:144)
	at com.sun.opengl.util.Animator$MainLoop.run(Animator.java:181)
	at java.lang.Thread.run(Unknown Source)
Caused by: javax.media.opengl.GLException: Required extensions not available to call this function
	at com.sun.opengl.impl.GLImpl.checkBufferObject(GLImpl.java:28012)
	at com.sun.opengl.impl.GLImpl.checkPackPBOEnabled(GLImpl.java:28055)
	at com.sun.opengl.impl.GLImpl.glReadPixels(GLImpl.java:15962)
	at CheckersRenderer.display(CheckersRenderer.java:146)
	at com.sun.opengl.impl.GLDrawableHelper.display(GLDrawableHelper.java:78)
	at javax.media.opengl.GLCanvas$DisplayAction.run(GLCanvas.java:281)
	at com.sun.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:194)
	at javax.media.opengl.GLCanvas$DisplayOnEventDispatchThreadAction.run(GLCanvas.java:298)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

You’re calling the wrong version of glReadPixels. You need to call the version taking a Buffer as the last argument, and assuming the call arguments above you should pass in a FloatBuffer allocated from BufferUtil.newFloatBuffer().


                realy = viewport[3] - (int) y - 1;

                FloatBuffer winZ = BufferUtil.newFloatBuffer(BufferUtil.SIZEOF_FLOAT);
        	float[] theZ = new float[1];
        	
        	gl.glReadPixels (x, (int)realy, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, winZ );

        	winZ.rewind();
        	
        	winZ.get(theZ);
        	System.out.println(theZ[0]);

This just returns 1.0, is it suppose to or am I doing something wrong?

Hi, If you don’t have any object under the mouse the value 1 seems correct.
I suppose that you are calling the glReadPixel with a valid GlContext ?

I appreciate the help, but I couldn’t seem to get readpixel to work, so instead I used vectors


        if (mouse != null){
        	int x = mouse.getX(), y = mouse.getY();
        	gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
        	gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, mvmatrix, 0);
        	gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projmatrix, 0);
        	
        	realy = viewport[3] - (int) y - 1;
        	
        	glu.gluUnProject((double) x, (double) realy, 0.0, mvmatrix, 0, projmatrix, 0, viewport, 0, wcoordN, 0);
        	glu.gluUnProject((double) x, (double) realy, 1.0, mvmatrix, 0, projmatrix, 0, viewport, 0, wcoordF, 0);
        
        	double[] myVec = new double[3];
        	
        	for(int ind = 0; ind < 3; ind++){
        		myVec[ind] = wcoordF[ind] - wcoordN[ind];
        	}
        	
        	double length = Math.sqrt(myVec[0]*myVec[0] + myVec[1]*myVec[1] + myVec[2]*myVec[2]);
        	
        	for(int ind = 0; ind < 3; ind++){
        		myVec[ind] = myVec[ind]/length;
        	}
        	
        	while(wcoordN[1] > 0){
        		wcoordN[0] += myVec[0];
        		wcoordN[1] += myVec[1];
        		wcoordN[2] += myVec[2];
        	}
        }

Seems to be working pretty nicely

Well if it works for you…
It is far less elegant than with glReadPixel :wink:
By the way you weren’t doing this code in the MouseListener were you?

Heh, yeah, but this is just a little project to help me learn, so its good enough

I was running the code in my display method