我尝试使用 OpenGL 绘制校园的原始地图。

谁能向我解释一下平移、缩放和旋转通常是如何实现的?

例如,通过平移和缩放,这只是我调整我的视口吗?因此,我绘制并绘制组成地图的所有线条,然后当用户单击并拖动时调整我的视口?

对于平移,它是否会改变我的视口的 x/y 值,而对于缩放,它是否会增加/减少我的视口一定量?对于轮换呢?

对于旋转,我是否必须对代表校园地图的每条折线进行仿射变换?在大小合适的地图上即时执行此操作会不会很昂贵?

或者,视口是否保持不变并以其他方式完成平移/缩放/旋转?


例如,如果您转到此 关联 你会看到他通过修改视口来描述平移和缩放,就像我上面描述的那样。

这不正确吗?

有帮助吗?

解决方案

他们通过施加一系列glTranslate的,glRotate命令(表示摄像机位置和方向)绘制场景之前实现。 (技术上,你转动整个场景!)

有像gluLookAt效用函数,其几分抽象有关此的一些细节。

要simplyify东西,假设有表示相机两个向量:位置和方向。

gluLookAt取位置,目的地,和向上矢量。

如果要实现一个向量类,destinaion = position + direction应该给你的目的地点。

再次使事情简单,可以假设向上矢量总是为(0,1,0)

然后,在你的场景渲染任何东西之前,加载单位矩阵,并调用gluLookAt

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( source.x, source.y, source.z, destination.x, destination.y, destination.z, 0, 1, 0 );

然后开始绘制你的对象

可以通过稍微改变的位置向右或向左让用户跨度。轮换是一个比较复杂一点你一定要旋转的方向向量。假设你正在旋转的是摄像头,在现场没有一些对象。

一个问题是,如果你只拥有“前进”你怎么移动它的方向向量?其中是右和左?

我在这种情况下的方法是只取“方向”和(0,1,0)的叉积。

现在您可以将相机移动到左边,并使用类似的权利:

position = position + right * amount; //amount < 0 moves to the left

您可以向前使用“方向矢量”,但国际海事组织它更好地限制运动水平面,因此得到正向矢量,我们有正确的矢量以同样的方式:

forward = cross( up, right )

要实话,这是多少有些一个hackish的方法。

在合适的方法是使用一个更“复杂的”数据结构来表示摄像机的“方向”,不只是前进方向。不过,既然你是刚刚起步,这是很好的拿东西,在一步一个脚印。

其他提示

所有这些“动作”的可利用模型视图矩阵变换函数来实现。你应该了解的glTranslatef(平移),glScalef(放大),glRotatef(旋转)。你也应该需要阅读有关OpenGL的一些基本教程,你可能会发现此链接有用。

通常,每当您在 opengl 中引用 3d 空间中的任何点时,都会应用三个步骤。

给定一个局部点

  • 本地 -> 世界变换
  • 世界 -> 相机变换
  • 相机 -> 屏幕变换(通常是投影。取决于您使用的是透视还是正交)

这些变换中的每一个都采用您的 3d 点,并乘以矩阵。

当您旋转相机时,通常会通过将变换矩阵乘以旋转/平移/缩放仿射变换来更改世界 -> 相机变换。由于每帧都会重新渲染所有点,因此新矩阵将应用于您的点,并给出旋转的外观。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top