PDA

View Full Version : world coords problemo



vurentjie
03-11-2008, 09:32 AM
hi,

i am having some difficulty conceptualising 3d world coords in an experimental applications that i am building, i am still very much a beginner i can't fully grasp some things that involve gluUnproject, even unsure whether this is what I should be using....

i am going to have to give a somewhat lengthy explanation of my scenario as there is no easy way for me to explain myself....

first off i started to build what i though might be a good experimental environment for a 3d graphics editor(like blender), i actually would like to learn alot of opengl to be able to contribute to blender project,but that is still a long way off, but this is why i am interested in opengl, not really for making games.....

i am using the sdl library....

so i started by creating a perspective viewport with the following(i don't know how to post code properly on this forum!):



glClearColor(0.3,0.3,0.3,1.0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glViewport(0,0,wide,high);

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();

gluPerspective(45.0, (float)(wide/high), 1.0, 200.0);

this gives a nice perspective view with near clip of 1.0, which i notice falls on the same z-value of a point that has coordinats(x,y,<u>z=-1.0</u>) which means that the z-ray runs toward the negative the deeper it goes into perspective,

but then how come is near clip of 1.0 not -1.0? i will get back to this as i explain, because it affects my attempts with gluUnproject.


next i drew the grid to the screen,(also included here is where i grab my viewport projection matrix and viewport matrix):

glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();

glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
glGetIntegerv (GL_VIEWPORT, viewport);

glEnable(GL_DEPTH_TEST);

//i add this dynamic variable that get inputted by mouse to translate/rotate the camera view


glTranslatef(transx,transy,-zoom);
glRotatef(rotx,1,0,0);
glRotatef(roty,0,1,0);


here is where i draw the grid.....

int i
for(i = -10; i <= 10; i++)
{
glVertex3f(i,0,-10);
glVertex3f(i,0,10);

glVertex3f(10,0,i);
glVertex3f(-10,0,i);
}


that pretty much sets up the scene,
the grid has its center-origin at (0,0,0)

which means the following:
if initial zoom equal to zero, the camera position will be directly inline(perpendicular) with z-position of -1.0 which also corresponds to the near clip plane.

if the initial zoom is a negative value of say -15.00 then the view will be exactly 15 units back from the previous position and the grid will seem to be 15 more units in the distance.

this seem basically straightforward, but what i am i say now might sound incorrect, but seems to be affecting the way gluUnproject is working.

next i set up a mouse function. i will only mention the right-click that uses gluUnproject....btw i declare my vars at the top of my code as global....

here is my mouse func

case SDL_BUTTON_RIGHT:

realy = viewport[3] - (GLint) event.button.y - 1;
fprintf (stdout,"Coordinates at cursor are (%4d, %4d)\n", event.button.x, realy);

gluUnProject ((GLdouble) event.button.x, (GLdouble) realy, 0.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

fprintf (stdout,"World coords at z=0.0 are (%f, %f, %f)\n", wx, wy, wz);

gluUnProject ((GLdouble) event.button.x, (GLdouble) realy, 1.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

fprintf (stdout,"World coords at z=1.0 are (%f, %f, %f)\n", wx, wy, wz);

break;

this seems to give me the correct world coordinates from evidence

at z=0(near clip plane) the wz world coordinate is -1.0 which corresponds to near clip,

at z=1(far clip) the wz world coordinate is -199.99999 an approx of -200.f which corresponds to far clip,

BUT NOW MY REAL MISUNDERSTANDING BEGINS---

after drawing my grid i render a GL_POINT within the world space to test these, i am testing the z-value as this where i have a problem

so i give wz an initial value of -5.0 knowing that once i click the mouse it will get a new value
then i draw the point with a z-coord of wz

glBegin(GL_POINTS);
glColor3f(1.0,1.0,1.0);
glVertex3f(5.0,5.0,wz);
glEnd();

i understand that eventually i will using both near and far-clip to utilise the ray but for now i just test the following in my mouse function

gluUnProject ((GLdouble) event.button.x, (GLdouble) realy, 0.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

which is the near clip,

so here is my problem, when i click my mouse this returns a wz value corresponding to the near clip which is -1.0, so my point moves to -1.0 on the z-axis,

there is an obvious problem with this....what about the rest of the grid that does not lie behind -1.0, the point will never be able to get to that portion of the grid(remember the grid is at 0,0,0 which means half lies in positive region and half in negative region)...........

also i thought of doing

gluUnProject ((GLdouble) event.button.x, (GLdouble) realy, 0.5, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

to a halfway mark between 0.0 and 1.0 but that doesnt work and confuses me even more.

so i guess this where my problem lies, i have thought of possible solutions which i need to test and get a succesful answer before i move onto working with the actual near-far ray....i need some advice as these might be completely off the mark, as i already feel lost.....

the solutions might be to translate the grid deeper down the z-axis therefore moving its origin,
or change the glPerspective so that it has a
negative near clip of -200.0 and a positive far clip 200.0
so that the origin is somewhere in the middle.

and that is about that, this is very long i don't know what else to do....

-NiCo-
03-11-2008, 10:09 AM
but then how come is near clip of 1.0 not -1.0? i will get back to this as i explain, because it affects my attempts with gluUnproject.

That's because OpenGL uses a right handed coordinate system. The origin is at the bottom left of the screen. The X axis points to the right, the Y axis points up and the z-axis points towards the viewer. So moving 1.0 units (near plane) into the screen, you arrive at a z-position of -1.0

I think the main problem is your understanding of the 3rd parameter to gluUnproject. This parameter is the window screen depth stored in the depth buffer. Not only does a perspective projection cause a non-linear relation between world space depth and window space depth (it's a non-linear mapping of the [nearplane,farplane] range to the [-1.0,1.0] range), but the viewport transformation also transforms this [-1.0,1.0] range to the [0,1] range of your depth buffer.

So basically you need to read the depth value from your depth buffer at the pixel position you want to unproject and provide that value as the third parameter to gluUnproject.

vurentjie
03-11-2008, 11:01 AM
hi will keep this brief...i did a google on window screen depth and managed to find the following,.....on this very site, i believe this has been part of my misunderstanding, not knowing about what i ought to know,

"You can obtain a single pixel's depth value by reading it back from the depth buffer with a call to glReadPixels(). This returns the screen space depth value.

It could be useful to have this value in object coordinate space. If so, you'll need to pass the window X and Y values, along with the screen space depth value to gluUnProject(). "

How do I obtain the Z value for a rendered primitive?

You can obtain a single pixel's depth value by reading it back from the depth buffer with a call to glReadPixels(). This returns the screen space depth value."


will have to fiddle...

-NiCo-
03-11-2008, 11:13 AM
float depth;
glReadPixels(x,y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&depth);

pass this depth to gluUnproject ( with identity modelview matrix for camera-space Z coord / or full modelview matrix for object space coords) and extract Z value...

vurentjie
03-12-2008, 11:03 AM
ok thank you so much!!! i managed to actually get it working, i have a little bug, something that i think i can sort out, but if any advice i will check up again, i had glGetintergv calls at the wrong place so i moved them further down to directly after the camera /modelview translations, and after following advice with glReadpixels i get it to work, so when i click with my mouse the point moves to the exact spot in the 3-d world, however as soon as i move my mouse the point disappears off the screen, it is obviously something to do with drawing order or pushing and popping matrices, so i will try figure out first by myself, at least that way i fiddle so much that i learn stuff i wouldn't otherwise.....but jeez thanks i was stumped on this last one for quite some time.

vurentjie
03-12-2008, 11:19 AM
ok i realize some of my problem i will attempt on my own for a while, use glReadPixel is giving me the near-clip camera-space z-coord, so it is positioning closest to camera as it can, the point doesnt disappear but if my camera is zoomed out the point will be far off from the grid, i will need to now do some serious math homework.....and research. thanks again