0
votes

I'm working on a 2D image viewer, I want to retrieve openGL mouse position on texture but I can't get it to work if glTranslatef() or glScalef() calls are made on the modelview matrix. I'm using a QGLWidget , of the famous Qt library.

Here are the important calls : Resize function :

void ViewerGL::resizeGL(int width, int height){

     glViewport (0, 0, width, height); 

Display function :

void ViewerGL::paintGL()
{        int w = width();
         int h = height();

        glMatrixMode (GL_PROJECTION);
        glLoadIdentity();

        //transX,transY are for panning around the image in the viewer
        float left = (0.f+transX) ; 
        float right = (w+transX) ; 
        float bottom = (h-transY);
        float top = (0.f-transY) ;        
        glOrtho(left, right, top, bottom, -1, 1);

... later in paintGL:

        glMatrixMode (GL_MODELVIEW);
        glLoadIdentity ();

        //padx,pady are used to translate the image from the bottom left corner 
        // to the center of the viewer
        float padx,pady;
        padx= ((float)width() - _dw.w()*zoomFactor)/2.f; // _dw.w is the width of the texture
        pady =((float)height() - _dw.h()*zoomFactor)/2.f ;// _dw.h is the height of the texture
        glTranslatef( padx , pady, 0);

        //zoomX,zoomY are the position at which the user required a zoom
        glTranslatef(-zoomX,-zoomY, 0.f);
        glScalef(zoomFactor, zoomFactor,0.f); 
        glTranslatef(zoomX ,zoomY, 0.f);

Now here is my function to retrieve the openGL coordinates :

QPoint ViewerGL::openGLpos(int x,int y){
   GLint viewport[4];
   GLdouble modelview[16];
   GLdouble projection[16];
   GLfloat winX=0, winY=0, winZ=0;
   GLdouble posX=0, posY=0, posZ=0;
   glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
   glGetDoublev( GL_PROJECTION_MATRIX, projection );
   glGetIntegerv( GL_VIEWPORT, viewport );
   winX = (float)x;
   winY = height()- y;
   if(winY == 0) winY =1.f;
   glReadPixels( x, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
   gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
   return QPoint(posX,posY);

}

So far , here is what I noticed: The code like this returns always (0,0) and GLU_FALSE is returned from gluUnproject. I read somewhere on a forum that it could be because of the modelview matrix, so I put the identity matrix instead, but,if I do it, I get exactly the coordinates of the mouse in the window...

Before , I dealt with the zoom using the orthographic projection, but I couldn't make it work perfectly, so to make it simpler I decided to retrieve openGL position, and use glTranslatef/glScalef instead .

If I remove all the translating / scaling stuff in the paintGL function, everything is working...but the zoom doesn't work :x)

I'm requesting your help to make this damned zoom to point working, using the gluUnProject solution;)

1

1 Answers

1
votes

Aigth , nevermind, I found the solution : I was zeroing out the z in glScalef(x,y,z) so it made the matrix non-invertible...