PDA

View Full Version : unable to translate from screen coords to world coords



etiennecouturie
04-28-2014, 12:03 AM
Hi everyone,

My problem is a very common one, still I cannot figure it out:
I have screen coords and want to get the world coordinates (for one pixel).
I am trying to use glReadPixels to get the depth value required in the gluUnProject method.

I usually get 1 or .0999 something from the readPixel method but even if I enter a depth value manually into
the unProject method, I get about the same value for when I click "near" or "far". Also I do not understand why my y
coordinate changes when I click in different location, I have a plane.

Maybe it's best if I post some code so you can see what is going on.


my init method:



public void init(GLAutoDrawable d) {
GL2 gl = d.getGL().getGL2();
glu = new GLU();
renderer = new TextRenderer(new Font("sansserif", Font.BOLD, 64));
gl.glClearColor(0, 0, 0, 0);
gl.glClearDepth(1);
gl.glDepthFunc(GL_LEQUAL);
gl.glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
gl.glShadeModel(GLLightingFunc.GL_SMOOTH);
gl.glEnable(GL2.GL_TEXTURE_2D);
gl.glEnable( GL_DEPTH_TEST );
gl.glDepthMask(true);
gl.glDepthFunc( GL_LEQUAL );
gl.glMatrixMode(GL_MODELVIEW);
}




my display method:



public void display(GLAutoDrawable drawable) {
// some initialization
GL2 gl = getGL().getGL2();
glu = new GLU();

// clearing buffers
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();

// needed for the gluUnProject, initialized below
int viewport[] = new int[4];
double mvmatrix[] = new double[16];
double projmatrix[] = new double[16];
int realy = 0;// GL y coord pos
double wcoord[] = new double[4];

// setting camera position
glu.gluLookAt(0, 50, -40, 0, 0, -90, 0, 1, 0);

// translation of the object
gl.glTranslatef(-50.0f, -25.0f, -80.0f);

// drawing of the object, a 32x32square consisting of smaller squares (1024 precisely)
for (int i = 0; i < GROUND_HEIGHT; ++i) {
for (int j = 0; j < GROUND_WIDTH; ++j) {
try {
drawGround(gl, i, j);
} catch (Exception e) {
e.printStackTrace();
}
}
}


renderer.beginRendering(drawable.getWidth(), drawable.getHeight());
renderer.setColor(1.0f, 0.0f, 0.0f, 0.8f);

if (Main.killed > 0)
renderer.draw(Main.killed + "x killed", 1000, 650);

renderer.endRendering();

// if a mouse event occures...
if (mouse != null){
System.out.println(mouse.getX() + " " + mouse.getY());
// get its position
int x = mouse.getX();
int y = mouse.getY();

// initialize stuff for gluUnProject
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;
System.out.println("Coordinates at cursor are (" + x + ", " + realy + ")");

FloatBuffer floatBuffer = FloatBuffer.allocate(1);
// read pixel depth
gl.glReadPixels( x, y, 1, 1, gl.GL_DEPTH_COMPONENT, gl.GL_FLOAT, floatBuffer);
float z = floatBuffer.get();

// translating the coordinates
glu.gluUnProject((double) x, (double) realy, z
, //
mvmatrix, 0,
projmatrix, 0,
viewport, 0,
wcoord, 0);

System.out.println("World coords at z=1.0 are ( " //
+ wcoord[0] + ", " + wcoord[1] + ", " + wcoord[2]
+ ")");
}
}




my reshape method:



public void reshape(GLAutoDrawable d, int x, int y, int width,
int height) {
GL2 gl = getGL().getGL2();

if (height == 0) {
height = 1;
}

float aspect = (float) width / height;

gl.glViewport(0, 0, width, height);
// this is the lens of the camera
gl.glMatrixMode(GL_PROJECTION);
glu.gluPerspective(45, aspect, 0.1, 200);
// this is the position of the camera
gl.glMatrixMode(GL_MODELVIEW);
gl.glLoadIdentity();
}

Dark Photon
04-28-2014, 05:04 AM
Try drawing something barely in front of the near clip plane, and then read that back and look at the unprojected depth values.

For a perspective projection, the transformation from linear eye-space Z to window-space Z is very non-linear, causing most of your Z precision to cluster up toward the near clip plane where you typically want it. The consequence is that when moving from near to far, your Z values move pretty quickly up to very near 1.0. So it's not unusual to do a readback and the window-space Z values are 0.9...something...