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 4 of 4

Thread: zooming to mouse position using glOrtho

Hybrid View

  1. #1
    Newbie Newbie
    Join Date
    Feb 2013
    Posts
    2

    zooming to mouse position using glOrtho

    Hi guys

    Currently I am using glOrtho to zoom and pan around a 2D graph I am rendering.

    I have setup up the viewport to the standard width and height. Then I set the glOrtho so that my frustrum makes screen coordinates match world coordinates.


    ////////////////////////////////////////////////////////////////////
    glViewport(0, 0, window_width,window_height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, window_width,window_height,0 , 100, -100);
    ///////////////////////////////////////////////////////////////////



    When I do my zoom function in my mouse callback, I multiply the frustrum edges by a zoom factor....

    glOrtho( 0 * zoomOut,
    window_width * zoomOut,
    window_height * zoomOut,
    0 * zoomOut,
    100, -100);

    My question is.... how do I zoom using mouse position as a centre?

    I have tried this... (where mouseStoreX and mouseStoreY are the position stored at the first click)

    glOrtho( (0 -mouseStoreX )* zoomOut + mouseStoreX,
    (window_width - mouseStoreX) * zoomOut + mouseStoreX,
    (window_height - mouseStoreY) * zoomOut + mouseStoreY,
    (0 - mouseStoreY) * zoomOut + mouseStoreY,
    100, -100);

    It seems to work but the frustrum jumps around when I do a new click. I think somewhere I'm not taking into account the zoomOut factor when doing the mouse position storing.

    Any help is much appreciated.

    Thanks
    Dan

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,101
    It seems to work but the frustrum jumps around when I do a new click
    Do you want to zoom with the click position moved to the centre of the view? If so you will jump about.

    You code look wrong for this

    eg if your window was 100 units wide and you clicked at 25 with a zoom of 2
    left = (0-25) * 2 + 25 = -25
    right = (100-25) * 2 + 25 = 175

    making your centre 75 not 25

  3. #3
    Newbie Newbie
    Join Date
    Feb 2013
    Posts
    2
    Quote Originally Posted by tonyo_au View Post
    Do you want to zoom with the click position moved to the centre of the view? If so you will jump about.
    No I want to zoom with the point underneath the mouse as the pivot and everything else scale around it. I have tried various ways of getting around the offet but not yet come up with a solution.

    I am getting the mouse world position when I click down......

    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );
    //flip Y for opengl reasons
    winY = (float)viewport[3] - winY;
    //get world mouse coordinate
    gluUnProject( mouseStoreX, mouseStoreY , 0.0, modelview, projection, viewport, &posX, &posY, &pos);


    Then I am calcing the difference from that click position from the current centre....

    dx = posX - FS.xOffset;
    dy = posY - FS.yOffset;

    which I then use to do my scaling around the point in my mouse move function......

    FS.left = ((FS.xOffset - dx - (window_width/2.0))*zoomFactor) +dx;
    FS.right = ((FS.xOffset -dx + (window_width/2.0))*zoomFactor)+dx ;
    FS.bottom = ((FS.yOffset -dy + (window_width/2.0))*zoomFactor)+dy;
    FS.top = ((FS.yOffset -dy - (window_width/2.0))*zoomFactor) +dy;


    before recentering on mouse release...

    FS.xOffset = (FS.left-FS.right)/2.0;


    I think somewhere I am not concatenating transforms correctly.

  4. #4
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,101
    Have you tried this

    F = mouse_x / window_width - fractional distance of mouse click
    W = window_width * zoomFactor - new window width in world units

    mouse_x_in_world = F * W_old + left_old; - mouse in world units
    left_new = mouse_x_in_world - F * W
    right_new = mouse_x_in_world + (1-F) * W

    similar code for top and bottom

    gluUnProject is probably less accurate than this.

Posting Permissions

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