Sign in to follow this  
EndIsForever

OpenGL gluUnProject woes

Recommended Posts

Hi, I am trying to develop a really simple map editor. I am trying to use openGL, so that when the user clicks the mouse in a 3d viewport an object is placed at the 3d point under the mouse. I am trying to use gluUnProject, but it doesn't quite seem to do the trick. It gets near to the point under the mouse but it only is under when the mouse is over the world 0. I have had a little search around here for gluUnProject but I still haven't been able to find a soloution :(. I put together this little example with GLUT, but hopefully I will be using MFC for the final thing. Would anyone be kind enough to give an example of where to go from here with regards to getting the point under the mouse. Also, in the example the camera has been moved -100 units back to view the scene. If this is changed the whole thing no longer works, which is errr... problematic since I was hoping the user could move around a little. Any help much appreciated. Thanks, David.
#include <iostream>
#include <GL/glut.h>

using namespace std;

GLdouble wx=0, wy=0, wz=0;
GLint pointX, pointY;
float ez;

int width = 800;
int height = 600;

void display(void)
{
   glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   
   glTranslatef(0.0, 0.0, -100);
   glRotatef(60.0, 1, 0, 0);
   glRotatef(60.0, 0, 1, 0);
   
   glColor3f(1.0f, 0.0f, 0.0f);
   glPushMatrix();
      glTranslatef(wx, 0.0, wz);
      glBegin(GL_QUADS);
         glVertex3f(-1.0, 0.0, 1.0);
         glVertex3f(1.0, 0.0, 1.0);
         glVertex3f(1.0, 0.0, -1.0);
         glVertex3f(-1.0, 0.0, -1.0);
      glEnd();
   glPopMatrix();
         
   glFlush();
   glutPostRedisplay();
   glutSwapBuffers();
   
}
void init()
{
   glClearColor(0.6, 0.6, 0.6, 1.0);
   glShadeModel(GL_FLAT);
}

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45.0, (GLfloat) w / (GLfloat) h, 1.0, 100.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

void mouse(int button, int state, int x, int y)
{
   GLint viewport[4];
   GLdouble mvmatrix[16], projmatrix[16];
   GLint realy;
   
   switch(button)
   {
      case GLUT_LEFT_BUTTON:
         if(state == GLUT_DOWN)
         {
            glGetIntegerv(GL_VIEWPORT, viewport);
            glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
            glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
            
            realy = viewport[3] - (GLint) y -1;
            
            glReadPixels( x, realy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &ez );
            
            gluUnProject( (GLdouble) x,(GLdouble) realy , ez, mvmatrix, projmatrix, viewport, &wx,&wy, &wz);
            
            //cout << "X:" << wx << " Y:" << wy << " Z:" << wz << endl;
         } 
         break;
      case GLUT_RIGHT_BUTTON:
         if(state == GLUT_DOWN)
            exit(0);
         break;
      default:
         break;
   }
   pointX = x;
   pointY = y;
   
   glutPostRedisplay();
   
}

int main(int argc, char *argv[])
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_DEPTH|GLUT_RGBA|GLUT_DOUBLE);
   glEnable(GL_DEPTH_TEST);
   glutInitWindowSize(width, height);
   glutInitWindowPosition(100, 100);
   glutCreateWindow(argv[0]);
   init();
   glutDisplayFunc(display);
   glutReshapeFunc(reshape);
   glutMouseFunc(mouse);
   glutIdleFunc(display);
   glutMainLoop();
return 0;
}






Share this post


Link to post
Share on other sites
I've had problems with glReadpixels and unproject. I found out that I had called the funtions with wrong datatypes (doubles instead of floats iirc). I couldn't see any wrong in your code though, but maybe I oversaw something.

Share this post


Link to post
Share on other sites
Hi, look at the following code, it works ok:


BOOL GeMouseXYZ ( HWND hWindow, GLfloat* pX, GLfloat* pY, GLfloat* pZ )
{
GLint vViewPort[4];
GLdouble vModelView[16];
GLdouble vProjection[16];

POINT sMousePos;
GetCursorPos( &sMousePos );
ScreenToClient( nWindow, &sMousePos );

GLfloat fWinX = (GLfloat)sMousePos.x;
GLfloat fWinY = (GLfloat)sMousePos.y;
GLfloat fWinZ;

glGetDoublev( GL_MODELVIEW_MATRIX, vModelView );
glGetDoublev( GL_PROJECTION_MATRIX, vProjection );
glGetIntegerv( GL_VIEWPORT, vViewPort );

fWinY = (GLfloat)vViewPort[3] - (GLfloat)sMousePos.y;
glReadPixels( sMousePos.x, (GLint)fWinY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fWinZ );

GLdouble dPosX;
GLdouble dPosY;
GLdouble dPosZ;

GLint iResult = gluUnProject( fWinX, fWinY, fWinZ, vModelView, vProjection,
vViewPort, &dPosX, &dPosY, &dPosZ );

if ( iResult )
{
*pX = (GLfloat)dPosX;
*pY = (GLfloat)dPosY;
*pZ = (GLfloat)dPosZ;

return TRUE;
}

return FALSE;

} // GeMouseXYZ()

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this