Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 7 of 7

Thread: Another zoom to cursor thread

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    6

    Another zoom to cursor thread

    Hello,

    I have a 2D application which is an image viewer.
    I have the ability to pan around the image in the window and I have a basic zoom.
    Now I'd like to improve the zoom so it zoom to the point under the mouse.
    So far I've read everything possible on google and i've come close to something working,
    but still can't find something perfect, here is what I got:


    Code :
    glMatrixMode (GL_PROJECTION);
              glLoadIdentity();
     
             // w and h are respectivly the width  and height of the window      
            // newzoom_pos is the point in openGL coordinates  where the user requested the zoom
            // zoomFactor is between [0.1,10.0]  , 0.1 -> 1.0 means downscale, 1.0 -> 10.0 means upscale
            // transX and transY are used to pan around the image
            float left = (0.f+transX -newzoom_pos.x())/zoomFactor  +newzoom_pos.x();
            float right = (w+transX -newzoom_pos.x())/zoomFactor +newzoom_pos.x();
    	float bottom = (h-transY-newzoom_pos.y())/zoomFactor +newzoom_pos.y();
    	float top = (0.f-transY -newzoom_pos.y())/zoomFactor +newzoom_pos.y();
     
            glOrtho(left, right, top, bottom, -1, 1);
     
     
     
            glMatrixMode (GL_MODELVIEW);
    	glLoadIdentity ();

    it works well when the texture is filling all the window : i.e when the user zoom in a lot.
    But when the image is small and does not fit yet in the viewer entirely ( there's black around), well it is messy and does not work...

    btw, here is the code when the user zoom-in, in the mouse wheel event handler:

    Code :
    zoomFactor+=0.1;
    QPoint oglpos = openGLpos(new_zoomPoint.x(), new_zoomPoint.y());
     this->newzoom_pos = oglpos;

    the openGLpos function is the following:

    Code :
    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 = viewport[3]- y;
        if(winY == 0) winY =1.f;
        glReadPixels( x, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
        GLint b=gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
        if(b==GLU_FALSE) cout << "failed unprojection" << endl;
        return QPoint(posX,posY);
    }

    Could anybody help me through this?
    Thanks for your help !

    Alex

  2. #2
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    6
    Help, i'm still stuck on this !

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    well it is messy and does not work...
    What exactly is your problem?

  4. #4
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    6
    I can't get the zoom to point working, I think i'm not doing it right in the call to glOrtho, and I could use some advices

  5. #5
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    Try something like this

    lets say that when your zoom is 1:1 (ie no up-scale or down-scale) the width is W and height is H.
    then

    Code :
    glOrtho(-W/2,W/2,-H/2,H/2,-1,1);
    will centre you around the middle of the image

    If the new origin is say new_x,new_y
    Code :
    glOrtho(-W/2+new_x,W/2+new_x,-H/2+new_y,H/2+new_y,-1,1);
    will centre you around the new origin

    Now we change the zoom to Z (0.1->10);
    Code :
    new_W = W * Z;
    new_H = H * Z;
    glOrtho(-new_W/2+new_x,new_W/2+new_x,-new_H/2+new_y,new_H/2+new_y,-1,1);

    should place you centred around the new origin with the new scale

  6. #6
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    6
    oh thanks a lot ! And new_x, new_y are in openGL coordinates right?

  7. #7
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    Yes that's right

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •