Question

I want to get the mouse click position in 3D. Below is my code, its simple, What wrong in it. where I am doing wrong.. ? Why I am not getting the exact values of x and y ? any idea ?

void glPerspective()
{
    glViewport(0, 0, WINDOW_SIZE_W, WINDOW_SIZE_H);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, (GLdouble)WINDOW_SIZE_W / (GLdouble)WINDOW_SIZE_H, 0.1, 100000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, m_zoom,   0.0, 0.0, 0.0,   0.0, 1.0, 0.0);
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();    
      glPerspective();     // perspective view
      Some_rotation_and_translation();
      glGetDoublev( GL_PROJECTION_MATRIX, OGLMprojection );
      glGetDoublev( GL_MODELVIEW_MATRIX, OGLMmodelview );
      glGetIntegerv( GL_VIEWPORT, OGLMviewport );
      Render_Triangular_model();
    glPopMatrix();
    swapbuffer();
}
    GLpoint GetOGLMousePos(GLint x, GLint y)
    {
        GLdouble winX = 0.0, winY = 0.0, winZ = 0.0;
        GLdouble posX = 0.0, posY = 0.0, posZ = 0.0;
        winX = (float)x;
        winY = (float)OGLMviewport[3] - (float)y;           // invert winY so that down lowers value
        glReadPixels( x, GLint(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
        gluUnProject( winX, winY, winZ, OGLMmodelview, OGLMprojection, OGLMviewport, &posX, &posY, &posZ);
        return GLpoint(posX, posY, posZ);
    }
Was it helpful?

Solution 2

Thanks for your precious time. Now its solved. I mention the problem below. Usually we used to ignore (float or double) variables during programming, I think we should not.

GLpoint GetOGLMousePos(GLint x, GLint y)
{
GLfloat winX = 0.0, winY = 0.0, winZ = 0.0;       **// never ever make a mistake between float and double.
I wasted my 4 days to solve this and the problem was, I was using GLdouble here instead of GLfloat.
Try GLdouble here you will see a hell difference in output values.**


GLdouble posX = 0.0, posY = 0.0, posZ = 0.0;
winX = (float)x;
winY = (float)OGLMviewport[3] - (float)y;   // invert winY so that down lowers value
glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject( winX, winY, winZ, OGLMmodelview, OGLMprojection, OGLMviewport, &posX, &posY, &posZ);
return GLpoint(posX, posY, -posZ); // invert z value
}

OTHER TIPS

I think you're getting the world transform matrix for the "triangular model", when you call glGetDoublev( GL_MODELVIEW_MATRIX, OGLMmodelview ). That matrix represents a transform from local object coordinates to world coordinates.

I'm pretty sure that gluUnProject assumes that it's operating with a view transform matrix, which maps from world coordinates to camera space coordinates.

So, I think that's the mismatch, and one that can probably be fixed by moving your glGet* calls out of the glPushMatrix - glPopMatrix block.

Actually, I think getting GL_PROJECTION_MATRIX and GL_VIEWPORT is something that can, and should be done in the mouse function, as demonstrated in this example (by Tomas Hamala):

/*
    gcc -Wall -lglut -lGLU -lGL unproject.c -o unproject
 */
#include <GL/glut.h>

void Display();
void Reshape(int w,int h);
void Mouse(int button,int state,int x,int y);

int main(int argc,char **argv) {
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(Display);
    glutReshapeFunc(Reshape);
    glutMouseFunc(Mouse);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);

    glutMainLoop();
    return 0;
}

GLdouble ox=0.0,oy=0.0,oz=0.0;
void Display() {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(10.0,0.0,20.0,0.0,0.0,0.0,0.0,1.0,0.0);

    glPushMatrix();
    glRotatef(45,1.0,0.0,0.0);
    glutSolidTorus(4.0,5.0,20,20);
    glPopMatrix();

    glPushMatrix();
    glDepthMask(GL_FALSE);
    glTranslated(ox,oy,oz);
    glutSolidSphere(0.5,15,15);
    glDepthMask(GL_TRUE);
    glPopMatrix();

    glFlush();
}

void Reshape(int w,int h) {
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0,(float)w/(float)h,5.0,30.0);
    glMatrixMode(GL_MODELVIEW);
}

void Mouse(int button,int state,int x,int y) {
    GLint viewport[4];
    GLdouble modelview[16],projection[16];
    GLfloat wx=x,wy,wz;

    if(state!=GLUT_DOWN)
        return;
    if(button==GLUT_RIGHT_BUTTON)
        exit(0);
    glGetIntegerv(GL_VIEWPORT,viewport);
    y=viewport[3]-y;
    wy=y;
    glGetDoublev(GL_MODELVIEW_MATRIX,modelview);
    glGetDoublev(GL_PROJECTION_MATRIX,projection);
    glReadPixels(x,y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&wz);
    gluUnProject(wx,wy,wz,modelview,projection,viewport,&ox,&oy,&oz);
    glutPostRedisplay();
}

This is a complete, working example, so it's something you can work from, even if you're not able to fix your existing code.

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top