Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zooming in on mouse position in OpenGl

I wish to implement a zoom-to-mouse-position-with-scrollwheel-algorithm for a CAD application I work on.

Similar question have been asked (This one for example), but all the solutions i found used the

  1. Translate to origin
  2. Scale to zoom
  3. Translate back

approach. While this works in principle, it leads to objects being clipped away on high zoom levels since they become bigger then the viewing volume is. A more elegant solution would be to modify the projection matrix for the zooming.

I tried to implement this, but only got a zoom to the center of the window working.

 glGetIntegerv(GL_VIEWPORT, @fViewport);
 //convert window coordinates of the mouse to gl's coordinates
 zoomtoxgl := mouse.zoomtox;
 zoomtoygl := (fviewport[3] - (mouse.zoomtoy));
//set up projection matrix
 glMatrixMode(GL_PROJECTION);
 glLoadidentiy;
 left   := -width  / 2 * scale;
 right  :=  width  / 2 * scale;
 top    :=  height / 2 * scale;
 bottom := -height / 2 * scale;
 glOrtho(left, right, bottom, top, near, far);

My questions are: Is it possible to perform a zoom on an arbitrary point using the projection matrix alone in an orthographic view, and if so, How can the zoom target position be factored into the projection matrix?

Update I changed my code to

zoomtoxgl := camera.zoomtox;
zoomtoygl := (fviewport[3] - camera.zoomtoy);
dx := zoomtoxgl-width/2;
dy := zoomtoygl-height/2;
a := width  * 0.5 * scale;
b := width  * 0.5 * scale;
c := height * 0.5 * scale;
d := height * 0.5 * scale;

left   := - a - dx * scale;
right  := +b - dx * scale;
bottom := -c - dy * scale;
top    :=  d - dy * scale;
glOrtho(left, right, bottom, top, -10000.5, Camera.viewdepth);

which gave this result:

Zooming issues

Instead of scaling around the cursor position, i can know shift the world origin to any screen location i wish. Nice to have, but not what i want.

Since i am stuck on this for quite some time now, I wonder : Can a zoom relative to an arbitrary screen position be generated just by modifying the projection matrix? Or will I have to modify my Modelview matrix after all?

like image 559
sum1stolemyname Avatar asked Nov 14 '22 06:11

sum1stolemyname


1 Answers

What about changing your values for left/right/top/bottom to reflect where the mouse is?

Something like:

 left   := zoomtoxgl - width  / 2 * scale;
 right  := zoomtoxgl + width  / 2 * scale;
 top    := zoomtoygl + height / 2 * scale;
 bottom := zoomtoygl - height / 2 * scale;
 glOrtho(left, right, bottom, top, near, far);

You'll probably need to adjust the scale for this usage.

Btw have you seen 8.070 How can I automatically calculate a view that displays my entire model? (I know the bounding sphere and up vector.) I'm following their example in this answer, along with 8.040 How do I implement a zoom operation?.

like image 182
LarsH Avatar answered Nov 16 '22 23:11

LarsH