gluUnProject Translation Problem

Started by
13 comments, last by adam17 15 years, 1 month ago
I am having an issue with my gluUnProject function. I set it up so i can cast a ray from the near plane to the far plane and not have any problems. I have a point drawn at both ends of the line and they line up perfectly. now if i pan the camera left or right along the x axis there is no problem. if i pan vertically, up or down, along the y axis, i have an issue. the near and far points do not calculate properly. here are some images to prove it. the blue points at the top, bottom, left and right are markers for me. they are placed at x=10, x=-10, y=10, and y=-10. also the camera is at z=10. This is what i get with no movement at all This is if i pan up This is if pan down here is the code for the unproject

//OGLMouseCur, OGLMousePrev, nearPoint, and farPoint are all Vector3 classes
//which contain the normal x, y, and z.
		GLint view[4];
		GLdouble model[16];
		GLdouble proj[16];

		glGetDoublev(GL_MODELVIEW_MATRIX, model);
		glGetDoublev(GL_PROJECTION_MATRIX, proj);
		glGetIntegerv(GL_VIEWPORT, view);

		//Copy old position to previous
		mousePrev.x = mouseCur.x;
		mousePrev.y = mouseCur.y;
		OGLMousePrev.x = OGLMouseCur.x;
		OGLMousePrev.y = OGLMouseCur.y;
		OGLMousePrev.z = OGLMouseCur.z;

		//Get new position of cursor
		GetCursorPos(&mouseCur);
		ScreenToClient(mouseHWND, &mouseCur);
		CheckMouseButtons();

		//Project cursor coordinates into OGL coordinates
		gluUnProject((GLdouble)mouseCur.x-4.0, (GLdouble)(mouseCur.y-30.0), 0.5, model, proj, view,
					&OGLMouseCur.x, &OGLMouseCur.y, &OGLMouseCur.z);
		gluUnProject((GLdouble)mousePrev.x-4.0, (GLdouble)(mousePrev.y-30.0), 0.5, model, proj, view,
					&OGLMousePrev.x, &OGLMousePrev.y, &OGLMousePrev.z);
		//Near and far points for line-plane intersection
		gluUnProject((GLdouble)mouseCur.x-4.0, (GLdouble)(mouseCur.y-30.0), 1.0, model, proj, view,
					&nearPoint.x, &nearPoint.y, &nearPoint.z);
		gluUnProject((GLdouble)mouseCur.x-4.0, (GLdouble)(mouseCur.y-30.0), 0.0, model, proj, view,
					&farPoint.x, &farPoint.y, &farPoint.z);

		OGLMouseCur.y *= -1.0;
		OGLMousePrev.y *= -1.0;
		nearPoint.y *= -1.0f;
		farPoint.y *= -1.0f;


does anybody have an idea of why this is happening? thank you! [Edited by - adam17 on January 17, 2009 4:43:05 PM]
Advertisement
all the extra additions to the numbers youre doing seems a bit hacky

if u want a ray through the cursor pos u only need to unproject the following 2 points

gluUnProject((GLdouble)mouseCur.x, (GLdouble)(mouseCur.y), 0.0, model, proj, view,
&n.x, &n.y, &n.z);

gluUnProject((GLdouble)mouseCur.x, (GLdouble)(mouseCur.y), 1.0, model, proj, view,
&f.x, &f.y, &f.z);

what r u wanting to do with this ray?

though if u draw a line between these points u wont be able to see it (picture looking along a line)
Maybe those numbers are some sort of hot spot (i.e. the "click point" of the cursor), but that still would be better done in a less hardcoded way :)

Also, why do you first save OGLMouseCur to OGLMousePrev and then overwrite it by unprojecting the previous mouse position into OGLMousePrev? That operation should be unnecessary and would likely cause OGLMousePrev to change if the modelview matrix changed since the last frame.

Next, remember that z = 1.0 represents the far plane, not the near plane as indicated in your code. You should swap the 1.0 and 0.0 in those two lines (3rd and 4th gluUnproject().
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
Quote:Original post by zedz
all the extra additions to the numbers youre doing seems a bit hacky

if u want a ray through the cursor pos u only need to unproject the following 2 points

gluUnProject((GLdouble)mouseCur.x, (GLdouble)(mouseCur.y), 0.0, model, proj, view,
&n.x, &n.y, &n.z);

gluUnProject((GLdouble)mouseCur.x, (GLdouble)(mouseCur.y), 1.0, model, proj, view,
&f.x, &f.y, &f.z);

what r u wanting to do with this ray?

though if u draw a line between these points u wont be able to see it (picture looking along a line)


yeah my code is kinda hacky right now. there are a lot of extras and unneeded variables, but they will be filtered out once i get this solved.

im trying to build a 2d/3d world editor. i realize i will not be able to see the line, except for directly onto it. im only drawing the line to aid in figuring out where my 2 points are, even if one is out of sight. im using the line for ray tracing the scene and selecting objects, a WYSIWYG editor.



Quote:Original post by Lord_Evil
Maybe those numbers are some sort of hot spot (i.e. the "click point" of the cursor), but that still would be better done in a less hardcoded way :)

Also, why do you first save OGLMouseCur to OGLMousePrev and then overwrite it by unprojecting the previous mouse position into OGLMousePrev? That operation should be unnecessary and would likely cause OGLMousePrev to change if the modelview matrix changed since the last frame.

Next, remember that z = 1.0 represents the far plane, not the near plane as indicated in your code. You should swap the 1.0 and 0.0 in those two lines (3rd and 4th gluUnproject().


where are you talking about "click point" numbers? the -30 and the -4? i know there is a function that can get the coordinates of the window, but i cant remember it, nor find it.

i fixed the OGLMousePrev overwrite. i removed it.

im a little confused on how z=0 is the near plane and z=1 is the far plane. on screen, it shows the opposite. the color coded points are the give away. although, it may be a reason for my problem, but i cant figure it out.
The z-component represents the depth. 1.0 means full depth, i.e. farthest position, 0.0 means no depth/nearest position.

The pictures don't show up in my browser (firefox 3), so I can only guess (maybe you could also provide the links). Whether a fragment (pixel) overwrites another one depends on the depth and the depth function or - if depth testing is disabled - the rendering order. If you have depth testing enabled but changed your depth comparison to something like GL_GREATER, farther away fragments overwrite nearer ones.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
Lord_Evil you are completely and totally right about the depth values. i was confused at first and googled depth maps to figure out if white was near or far. well, i found a bunch of images with white on the near plane. come to find out, they are used in 3d images, not depth testing. i thank you for pointing the 1.0/0.0 issue out to me.

i have uploaded the images to flickr and now they should show up. to add on to my images, the mouse cursor is hanging on to the blue dot, which is the far point. what is going on?! my only guess is that the unproject function is somehow not taking into consideration the translation of the camera. the nearpoint jumps off of the screen quickly, due to the nearplane being stuck at the original position. therefore when i pan, it moves a lot quicker.

[Edited by - adam17 on January 20, 2009 6:58:13 PM]
i should also point out that i am using a perspective projection rather than an ortho projection. im also using gluLookAt. i could not find out whether or not gluLookAt modifies the ModelView matrix. any ideas?
With the information gathered from this topic, I tried to create a function that would give me a 3-float vector representing the direction of a ray from the camera to a point I was clicking on some geometry in-game. I was trying to get ray-picking done through this method.

I came up with this:

vec3f CalculatePickingRay2(unsigned int ScreenX, unsigned int ScreenY){	vec3d Point1;	vec3d Point2;	GLint view[4];	GLdouble model[16];	GLdouble proj[16];	glGetDoublev(GL_MODELVIEW_MATRIX, model);	glGetDoublev(GL_PROJECTION_MATRIX, proj);	glGetIntegerv(GL_VIEWPORT, view);	gluUnProject((GLdouble)ScreenX, (GLdouble)ScreenY, 0.0, model, proj, view, &(Point1.x), &(Point1.y), &(Point1.z));	gluUnProject((GLdouble)ScreenX, (GLdouble)ScreenY, 1.0, model, proj, view, &(Point2.x), &(Point2.y), &(Point2.z));	return vec3f((float)(Point1.x - Point2.x), (float)(Point1.y - Point2.y), (float)(Point1.z - Point2.z));}


I must be doing something wrong, though.... because the vector I get back is always (no matter if I rotate or translate the camera different ways) returns a vec3f that is (0.0f, 0.0f, 2.0f)

Any help getting back on the right track would be greatly appreciated.
This man made my day: http://www.gamedev.net/community/forums/topic.asp?topic_id=523021
Quote:Original post by ShinkaFudan
With the information gathered from this topic, I tried to create a function that would give me a 3-float vector representing the direction of a ray from the camera to a point I was clicking on some geometry in-game. I was trying to get ray-picking done through this method.

I came up with this:

vec3f CalculatePickingRay2(unsigned int ScreenX, unsigned int ScreenY){	vec3d Point1;	vec3d Point2;	GLint view[4];	GLdouble model[16];	GLdouble proj[16];	glGetDoublev(GL_MODELVIEW_MATRIX, model);	glGetDoublev(GL_PROJECTION_MATRIX, proj);	glGetIntegerv(GL_VIEWPORT, view);	gluUnProject((GLdouble)ScreenX, (GLdouble)ScreenY, 0.0, model, proj, view, &(Point1.x), &(Point1.y), &(Point1.z));	gluUnProject((GLdouble)ScreenX, (GLdouble)ScreenY, 1.0, model, proj, view, &(Point2.x), &(Point2.y), &(Point2.z));	return vec3f((float)(Point1.x - Point2.x), (float)(Point1.y - Point2.y), (float)(Point1.z - Point2.z));}


I must be doing something wrong, though.... because the vector I get back is always (no matter if I rotate or translate the camera different ways) returns a vec3f that is (0.0f, 0.0f, 2.0f)

Any help getting back on the right track would be greatly appreciated.


At a glance your code looks fine to me. Very similar to my method. But I also had problems getting it to work initially. Do just check if you should be taking near from far, or far from near. I don't have my code in-front of me and I cannot remember to be honest. But you may have that swapped.

One problem I didn't have, but read about in my travels solving my problems was that you need to make sure that your GL matrices are valid when you retrieve them. I do that in a known location in my code and then reference them from there for everything.

Another is to make sure the orientation of your screen coordinates run from the correct origin.
Some systems y is swapped.

The problem I had was that the zfar at 1.0 gave me a lot of failures. I moved it in a bit, and that solved it. I still don't know why. Which niggles me. But it's solved for now. Eventually I will re-write gluUnProject as part of my own libraries.

Make your code give you some feedback on whether one of the gluUnProject calls fails.
They return a bool.
When I did that the second one was failing 50% of the time with the above problem.
Feel free to 'rate me down', especially when I prove you wrong, because it will make you feel better for a second....
I agree with scratt. Make sure the GL and GLU functions work properly (check return values and error states) and check your matrices (the modelview matrix should change when moving the camera, perspectiveand viewport should not - in the normal case).
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!

This topic is closed to new replies.

Advertisement