在 OpenGL 中放大鼠标位置

发布于 2024-09-29 20:55:23 字数 1565 浏览 4 评论 0原文

我希望为我正在开发的 CAD 应用程序实现一种使用滚轮缩放到鼠标位置的算法。

已经提出了类似的问题(例如这个),但是我找到的所有解决方案使用

  1. “平移到原点
  2. 缩放”来缩放
  3. “平移回”

方法。虽然这在原则上是有效的,但它会导致对象在高缩放级别上被剪掉,因为它们变得比观看体积更大。一个更优雅的解决方案是修改缩放的投影矩阵。

我尝试实现这一点,但只能缩放到窗口的中心。

 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);

我的问题是:是否可以在正交视图中单独使用投影矩阵对任意点执行缩放,如果可以,如何将缩放目标位置考虑到投影矩阵中?

更新 我将代码更改为

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);

以下结果:

Zooming issues

我可以知道改变世界,而不是围绕光标位置缩放原点到我希望的任何屏幕位置。很高兴拥有,但不是我想要的。

由于我已经在这个问题上停留了相当长的一段时间,我想知道:是否可以仅通过修改投影矩阵来生成相对于任意屏幕位置的缩放?或者我最终必须修改我的模型视图矩阵吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

说好的呢 2024-10-06 20:55:23

如何更改左/右/上/下的值以反映鼠标的位置?

例如:

 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);

您可能需要调整此用法的比例。

顺便说一句,您是否看过 8.070 如何自动计算显示整个模型的视图? (我知道边界球体和向上向量。)我在这个答案中遵循他们的示例,以及8.040 如何实现缩放操作?

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?.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文