title: Zooming to mouse position using glOrtho
body: <p>Currently I am using glOrtho to zoom and pan around a 2D graph I am rendering.</p>
  <p>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.</p>
  <pre><code>glViewport(0, 0, window_width,window_height);
  
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, window_width,window_height,0 , 100, -100);
  </code></pre>
  <p>When I do my zoom function in my mouse callback, I multiply the frustrum edges by a zoom factor....</p>
  <pre><code>glOrtho( 0 * zoomOut,
  window_width * zoomOut,
  window_height * zoomOut,
  0 * zoomOut, 
  100, -100);
  </code></pre>
  <p>My question is.... how do I zoom using mouse position as a centre?</p>
  <p>I have tried this... (where mouseStoreX and mouseStoreY are the position stored at the first click)</p>
  <pre><code>glOrtho( (0 -mouseStoreX )* zoomOut + mouseStoreX,
  (window_width - mouseStoreX) * zoomOut + mouseStoreX,
  (window_height - mouseStoreY) * zoomOut + mouseStoreY,
  (0 - mouseStoreY) * zoomOut + mouseStoreY, 
  100, -100);
  </code></pre>
  <p>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.</p>
  <p>EDIT: here is my latest code which I am still struggling with...</p>
  <pre><code>void ZoomOrtho(){ //ON MOUSE CLICK.....
  
  if (zooming == false){
  keyStore.LMx = keyStore.Mx;   //store mouse pos for next comparison
  keyStore.LMy = keyStore.My;
  //get mouse pos
  mouseStoreX = keyStore.Mx;//mouse pos at this moment
  mouseStoreY = keyStore.My;
  
  //get current projection matrices
  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, &amp;posX_,&amp;posY_, &amp;posZ_);
  
  // calc difference between mouse world pos and centre of 'camera'
  dx = posX_ - FS.centerX;
  dy = posY_ - FS.centerY;
  
  }
  //ON DRAG......
  zooming = true;
  
  //do mouse movement detection and increment zoomOut
  //#################################################
  int xDiff = keyStore.Mx - keyStore.LMx;  //mouse drag difference in screen space just  for incrementing zoom
  int yDiff = keyStore.My - keyStore.LMy;  //
  
  if (xDiff &gt; 0 &amp;&amp; (zoomFactor &gt;= 0.5 ) )   {
  zoomFactor -= zoomInc;
  if  (zoomFactor &lt; 0.5 ) {zoomFactor = 0.5;}
  }
  else if (xDiff &lt; 0 &amp;&amp; (zoomFactor &lt;= 2.0 ))  {
  zoomFactor += zoomInc;
  if (zoomFactor &gt; 2.0){zoomFactor = 2.0;}
  }
  //#################################################
  
  
  //fill structure with clipping plane values. zooms ortho projection and keeps mouse pos anchored.
  FS.left =  ((FS.centerX - dx - (window_width/2.0))*zoomFactor) +dx;
  FS.right = ((FS.centerX -dx + (window_width/2.0))*zoomFactor)+dx ;
  FS.bottom = ((FS.centerY -dy + (window_width/2.0))*zoomFactor)+dy;
  FS.top =    ((FS.centerY -dy  - (window_width/2.0))*zoomFactor) +dy;
  
  // store last mouse pos for next comparison.
  keyStore.LMx = keyStore.Mx;
  keyStore.LMy = keyStore.My;
  
  }
  
  void zoomRelease(){
  
  cout &lt;&lt; &quot; releasing&quot; &lt;&lt; std::endl;
  //set zoom to false so we know we are not draggin mouse anymore.
  zooming = false;
  keyStore.LMx = 0;
  keyStore.LMy = 0;
  
  // recenter by taking midpoint between new left and right clipping planes so dx has a reference point
  FS.centreX = (FS.right-FS.left)/2.0;
  
  }
  
  void DrawGui(){
  
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(FS.left, FS.right,FS.bottom, FS.top, 1, -1);
  
  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity();
  //do drawing
  
  } 
  </code></pre>