gluUnProject

I am using gluUnProject to get a 3d coordinate from the mouse position, well what else are you going to use it for. And to sum it up it doesn’t work! I use glReadPixels to get the depth. I think this works, I get values ranging from 0-1 (that should be correct) with numbers closer to 0 being nearer. I also think I am seeing the affects of the depth buffer not being linear becuase when I click a far away object I gvet a value of about 0.951 if I click somewhere a lot further away it only goes up to about 0.952 etc. so I think this is working. I pass this to gluUnproject with the mouse x and y coordinates (the y is inverted at the start) What I get back are coordinates that must be wrong, for example I click at the origion and it will return -10,-10,-11 (when rounded to int). The numbers don’t seem to change correctly along the axis ( for example I test the origion and tehn text 10 units to the right along the x-axis and it isn’t changed by anything like 10 units. Here is my code:

 
GLfloat pixel;
GLdouble obx,oby,obz;
GLint viewport[4];
GLdouble mvmatrix[16];
GLdouble projmatrix[16];
glGetIntegerv (GL_VIEWPORT,viewport);
glGetDoublev (GL_MODELVIEW_MATRIX,mvmatrix);
glGetDoublev (GL_PROJECTION_MATRIX,projmatrix);
    
     y = viewport[3] - y;
    glReadPixels(x,y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&pixel);
 
    
    gluUnProject(x,y,pixel,mvmatrix,projmatrix,viewport,&obx,&oby,&obz);

I have also been haveing problems with the selection buffer in that it always gives the wrong results in my MFC level editor, this might have something to do with it(well probably not). But I can’t find anything wrong with the code.

sounds pretty ok what you are writing, but you have to consider that the z-window coordinate lies within your viewing volume, that means z=0 gives you your near clipping plane and z= 1.0 gives you your far clipping plane.

So its pretty hard to get the correct 3d coordinates…

Sorry that I can’t help you more

Chris

I found out just now that if you take into acount your position the results are a little better, although very strange. If I go up close to the origon and click at the origon then I get -10,-10,-10 returned.I have a large cube (100^3) surrounding the level and if I then click on it looking down the positive x-axis (from the origon) then something close to -10,-10,-60 is returned. This is interesting because it should be 50 units away on the x-axis, however what is returned is 50 units away on the z-axis. The exact (well not exact but very similar) same results are returned when clicking down the + X-axis which is also strange, the same happens when looking down the + and - z axis (sp?) but something completely different happens when looking down the + and - y axis. Similarly if you go to the edge of the giant cube and then look back to the oposite side you can get a z value returned of about -110 which is correct for the length of the cue when taking into acount the value when looking at the origon (i.e it is offset by -10). Also in this situation when pointing at the middle of the oposite face the x returned values are about -+5 and so this roughly makes sense. I don’t know if any of this helps but it seems very bizare. I will try it in someother prog. and see if it works there. Thanks for the reply DaViper.

I know this isn’t considered the most technicaly correct method of selection but I have made a couple of modeling programmes now and find that using the selection buffer is very easy and requires rather minimal amount of extra code.

A lot of people would argue that it requires that the scene be redrawn which is slow. I have found that normally with modeling programmes you have 4 views so at most your only drawing to a quarter of the screen. Plus when you redraw the scene you aren’t texturing, or using lighting, in fact you can draw in wire frame and selection will still work.

Well thats my 2 cents anyway, if you want a copy of my modeler I could email you it if you want and you could see how smoothly selection works and how accurate it is compared with other more complicated methods. I’m not saying it is the best method for a fps or similar type of game but for a modeling programme it’s great.

Thanks for the reply I have just to day managed to get the selection buffer working and I do think it is good, however, I want gluUnProject so I get a 3d coordinate. With this I can select the nearest vertex or say add a light/sound/object at that location, there are also a few other uses for it. The selction buffer is being used to select faces (and will soon also be used to select objects/brushes which is an advantage of the selection buffer) A few things I have noted is that it returns all objects that are in the gluPickMatrix (obviously) and not at a specific point and so sorting out which object is selected can be hard and sometimes doesn’t work. I sort the returned hits by distance and get the closest but sometimes if you try to select a small face that is on a large face then it will also pick up the big face which might have a smaller minimum z value and so is selected. I made the gluPickMatrix volume smaller but I don’t know how small it should be (is there a limit or an optimum?)
I would be interested in your modeler if it isn’t to big. My level editor is coming along; my dad thought it was a commercial game when I showed of my first level I made (in about 10 minutes). That felt good.

Originally posted by Tim Stirling:
Thanks for the reply I have just to day managed to get the selection buffer working and I do think it is good, however, I want gluUnProject so I get a 3d coordinate. With this I can select the nearest vertex or say add a light/sound/object at that location, there are also a few other uses for it. The selction buffer is being used to select faces (and will soon also be used to select objects/brushes which is an advantage of the selection buffer) A few things I have noted is that it returns all objects that are in the gluPickMatrix (obviously) and not at a specific point and so sorting out which object is selected can be hard and sometimes doesn’t work. I sort the returned hits by distance and get the closest but sometimes if you try to select a small face that is on a large face then it will also pick up the big face which might have a smaller minimum z value and so is selected. I made the gluPickMatrix volume smaller but I don’t know how small it should be (is there a limit or an optimum?)
I would be interested in your modeler if it isn’t to big. My level editor is coming along; my dad thought it was a commercial game when I showed of my first level I made (in about 10 minutes). That felt good.

Hi, i too am using gluUnproject to return the coordinates of a point clicked on a 3d map. I thought maybe you might have some idea were i am going wrong. it seems to work ok and draws a tree at that pos but keeps drawing the tree on that same pos unless i click and drag the tree to a different pos even then it doesn’t place the tree at exactly that point but its off by 5. The tree also seems to disappear every second click of the mouse. My code is below to give you an idea.


case WM_LBUTTONDOWN:
hdc = GetDC(hWnd);
draw = true;
winx = LOWORD(lParam);
winy = HIWORD(lParam);
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
realy = viewport[3] - (GLint)winy - 1;
glReadPixels(winx,realy,1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
gluUnProject((GLdouble)winx, (GLdouble)realy, depth, modelmatrix,projmatrix,viewport,&objx, &objy, &objz);
SwapBuffers(hDC);
ReleaseDC(hWnd, hdc);
return 0;
case WM_MOUSEMOVE:
hdc = GetDC(hWnd);
if (draw == true)
{
winx = LOWORD(lParam);
winy = HIWORD(lParam);
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
realy = viewport[3] - (GLint)winy - 1;
glReadPixels(winx,realy,1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
gluUnProject((GLdouble)winx, (GLdouble)realy, depth, modelmatrix,projmatrix,viewport,&objx, &objy, &objz);
}
ReleaseDC(hWnd, hdc);
return 0;

case WM_LBUTTONUP:
draw = false;
return 0;

In DrawGlscene
glTranslated(objx,objy,objz);
DrawTree();

Originally posted by Tim Stirling:
Thanks for the reply I have just to day managed to get the selection buffer working and I do think it is good, however, I want gluUnProject so I get a 3d coordinate. With this I can select the nearest vertex or say add a light/sound/object at that location, there are also a few other uses for it. The selction buffer is being used to select faces (and will soon also be used to select objects/brushes which is an advantage of the selection buffer) A few things I have noted is that it returns all objects that are in the gluPickMatrix (obviously) and not at a specific point and so sorting out which object is selected can be hard and sometimes doesn’t work. I sort the returned hits by distance and get the closest but sometimes if you try to select a small face that is on a large face then it will also pick up the big face which might have a smaller minimum z value and so is selected. I made the gluPickMatrix volume smaller but I don’t know how small it should be (is there a limit or an optimum?)
I would be interested in your modeler if it isn’t to big. My level editor is coming along; my dad thought it was a commercial game when I showed of my first level I made (in about 10 minutes). That felt good.

Hi, i too am using gluUnproject to return the coordinates of a point clicked on a 3d map. I thought maybe you might have some idea were i am going wrong. it seems to work ok and draws a tree at that pos but keeps drawing the tree on that same pos unless i click and drag the tree to a different pos even then it doesn’t place the tree at exactly that point but its off by 5. The tree also seems to disappear every second click of the mouse. My code is below to give you an idea.


case WM_LBUTTONDOWN:
hdc = GetDC(hWnd);
draw = true;
winx = LOWORD(lParam);
winy = HIWORD(lParam);
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
realy = viewport[3] - (GLint)winy - 1;
glReadPixels(winx,realy,1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
gluUnProject((GLdouble)winx, (GLdouble)realy, depth, modelmatrix,projmatrix,viewport,&objx, &objy, &objz);
SwapBuffers(hDC);
ReleaseDC(hWnd, hdc);
return 0;
case WM_MOUSEMOVE:
hdc = GetDC(hWnd);
if (draw == true)
{
winx = LOWORD(lParam);
winy = HIWORD(lParam);
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
realy = viewport[3] - (GLint)winy - 1;
glReadPixels(winx,realy,1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
gluUnProject((GLdouble)winx, (GLdouble)realy, depth, modelmatrix,projmatrix,viewport,&objx, &objy, &objz);
}
ReleaseDC(hWnd, hdc);
return 0;

case WM_LBUTTONUP:
draw = false;
return 0;

In DrawGlscene
glTranslated(objx,objy,objz);
DrawTree();