Dan

04-18-2000, 06:24 AM

Is there a way to use the feedback buffer to get the (x,y,z) world space location of a (x,y) screen coordinate?

View Full Version : Screen Coords?

Dan

04-18-2000, 06:24 AM

Is there a way to use the feedback buffer to get the (x,y,z) world space location of a (x,y) screen coordinate?

Bob

04-18-2000, 06:58 AM

You can use a function called gluUnProject().

int gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *objx, GLdouble *objy, GLdouble *objz)

It should work by passing the windowcoordinate of the point you want to unproject, modelview and projectionmatrices, viewport and pointers to where you want the worldcoordinate to be stored, like this.

GLint viewport[4];

GLdouble mvmatrix[16], projmatrix[16];

GLdouble wx, wy, wz;

glGetIntegerv(GL_VIEWPORT, viewport);

glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);

glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);

gluUnProject((GLdouble)x, (GLdouble)y, (GLdouble)z, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

Since the point on screen appears on a 2D plane in 3D space, you cannot pass x and y coordinates and get x, y and z back. You must pass a z-coordinate too, and that coordinate is the distance from the plane (screen) to the point, or rather the value you find in the depthbuffer at <x,y>.

int gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *objx, GLdouble *objy, GLdouble *objz)

It should work by passing the windowcoordinate of the point you want to unproject, modelview and projectionmatrices, viewport and pointers to where you want the worldcoordinate to be stored, like this.

GLint viewport[4];

GLdouble mvmatrix[16], projmatrix[16];

GLdouble wx, wy, wz;

glGetIntegerv(GL_VIEWPORT, viewport);

glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);

glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);

gluUnProject((GLdouble)x, (GLdouble)y, (GLdouble)z, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

Since the point on screen appears on a 2D plane in 3D space, you cannot pass x and y coordinates and get x, y and z back. You must pass a z-coordinate too, and that coordinate is the distance from the plane (screen) to the point, or rather the value you find in the depthbuffer at <x,y>.

Antoche

04-18-2000, 09:29 AM

And what is the good way to read in the depth buffer. Can't gluUnProject() or sthg like that read itself into the z-buffer to know the z coordinate ?

Bob

04-19-2000, 01:51 AM

Sorry, was wrong about one thing in my post. It's about the winz-coordinate. This is what the Red Book is saying:

There are inherent difficulties in trying to reverse the transformation process. A two-dimensional screen location could have originated from anywhere on an entire line in three-dimensional space. To disambiguate the result, gluUnProject() requires that a window depth coordinate (winz) be provided and that winz be specified in terms of glDepthRange(). For the default values of glDepthRange(), winz at 0.0 will request the world coordinates of the transformed point at the near clipping plane, while winz at 1.0 will request the point at the far clipping plane.

Bob

There are inherent difficulties in trying to reverse the transformation process. A two-dimensional screen location could have originated from anywhere on an entire line in three-dimensional space. To disambiguate the result, gluUnProject() requires that a window depth coordinate (winz) be provided and that winz be specified in terms of glDepthRange(). For the default values of glDepthRange(), winz at 0.0 will request the world coordinates of the transformed point at the near clipping plane, while winz at 1.0 will request the point at the far clipping plane.

Bob

Dan

04-19-2000, 09:40 AM

Wow! thanks a lot Bob, that was exactly what i was looking for.

Dan

04-19-2000, 12:07 PM

Ok, this is definitly the function i want to use, but i have looked all over and cant seem to find any documentation on it? I want to find the exact x,y,z that the mouse is over...so if the mouse location is MouseX, and MouseY, how could i set this up, here is what i have can you tell me if it is correct or if i should change anything:

GLint Viewport[4];

GLdouble MVMatrix[16], ProjMatrix[16];

GLdouble wx, wy, wz;

glGetIntegerv(GL_VIEWPORT, Viewport);

glGetDoublev(GL_MODELVIEW_MATRIX, MVMatrix);

glGetDoublev (GL_PROJECTION_MATRIX, ProjMatrix);

gluUnProject((GLdouble)MouseX, (GLdouble)MouseY, (GLdouble)1.0, MVMatrix, ProjMatrix, Viewport, &wx, &wy, &wz);

Thanks

GLint Viewport[4];

GLdouble MVMatrix[16], ProjMatrix[16];

GLdouble wx, wy, wz;

glGetIntegerv(GL_VIEWPORT, Viewport);

glGetDoublev(GL_MODELVIEW_MATRIX, MVMatrix);

glGetDoublev (GL_PROJECTION_MATRIX, ProjMatrix);

gluUnProject((GLdouble)MouseX, (GLdouble)MouseY, (GLdouble)1.0, MVMatrix, ProjMatrix, Viewport, &wx, &wy, &wz);

Thanks

Bob

04-20-2000, 01:20 AM

The problem with unproject is that you HAVE to pass a specific z-coord in order to get a specific point in 3D space. If you pass 1.0 as z-coord, you will get the point in worldcoord that lies on the far clipping plane (0.0 will return the point on the near clipping plane).

However, you can use the point on the far clipping plane to calculate a line, on which all point lies that will be projected on the screen at <x,y>.

You can also see the screen as the near clipping plane (well, any plane will do), and therefore, if you click on <x,y>, you click somewhere on the plane. Then use gluUnProject to obtain that point on the plane.

Bob

P.S. Hmm, maybe this was a bit too messy...

However, you can use the point on the far clipping plane to calculate a line, on which all point lies that will be projected on the screen at <x,y>.

You can also see the screen as the near clipping plane (well, any plane will do), and therefore, if you click on <x,y>, you click somewhere on the plane. Then use gluUnProject to obtain that point on the plane.

Bob

P.S. Hmm, maybe this was a bit too messy...

Antoche

04-20-2000, 01:41 AM

Mmmhh... The best way to get the screen coordinates still seems to do the transformations ourselves.

But if you use gluUnproject, be careful about the MouseY coordinate, because the Y axis for the mouse is waying down the screen (is it english ?). For exemple, when i use gluPickMatrix, if must pass MouseX as x coordinate, and Viewport[3]-MouseY as Y coordinate (where Viewport is the array you retrieve with glGetIntegerv(GL_VIEWPORT)).

But if you use gluUnproject, be careful about the MouseY coordinate, because the Y axis for the mouse is waying down the screen (is it english ?). For exemple, when i use gluPickMatrix, if must pass MouseX as x coordinate, and Viewport[3]-MouseY as Y coordinate (where Viewport is the array you retrieve with glGetIntegerv(GL_VIEWPORT)).

Dan

04-20-2000, 06:58 AM

How could i calculate that line?

Bob

04-21-2000, 11:40 AM

Hmm, will try to give it a shot and describe how to calculate the line. Was a while since I read about linear algebra http://www.opengl.org/discussion_boards/ubb/tongue.gif .

c = cameraposition

p = point projected on far clippingplane

v.x = p.x - c.x

v.y = p.y - c.y

v.z = p.z - c.z

| x = c.x + t * v.x

| y = c.y + t * v.y

| z = c.z + t * v.z

x, y and z is the point in space you get

t is a constant

t=0 gives you the camerapoint

t=1 gives you the point on far clipping plane

t=0.5 gives you the point halfway from camera to far clippingplane

Hope that was correct.

c = cameraposition

p = point projected on far clippingplane

v.x = p.x - c.x

v.y = p.y - c.y

v.z = p.z - c.z

| x = c.x + t * v.x

| y = c.y + t * v.y

| z = c.z + t * v.z

x, y and z is the point in space you get

t is a constant

t=0 gives you the camerapoint

t=1 gives you the point on far clipping plane

t=0.5 gives you the point halfway from camera to far clippingplane

Hope that was correct.

Relic

04-25-2000, 12:40 PM

You can do a glReadPixel(x,y,1,1,GL_DEPTH_COMPONENT,GL_UNSIGNED _INT,*pixels) to get the depth under the mouse pointer.

Preferred destination values are ULONG (0 - 2**32-1). Scale the result to lie in the proper depth range 0.0 to 1.0 afterwards.

Originally posted by Antoche:

And what is the good way to read in the depth buffer. Can't gluUnProject() or sthg like that read itself into the z-buffer to know the z coordinate ?

Preferred destination values are ULONG (0 - 2**32-1). Scale the result to lie in the proper depth range 0.0 to 1.0 afterwards.

Originally posted by Antoche:

And what is the good way to read in the depth buffer. Can't gluUnProject() or sthg like that read itself into the z-buffer to know the z coordinate ?

Powered by vBulletin® Version 4.2.2 Copyright © 2014 vBulletin Solutions, Inc. All rights reserved.