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
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:
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?
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?.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With