opengl 视图、投影和正交纵横比

opengl view, projections and orthographic aspect ratio

有很多关于 3D 的 opengl 投影矩阵的很棒的教程,但我不是在做 3D。我真的很难按照自己的喜好设置正交投影。

int宽度=320; int height = 480;

我使用这些设置创建了一个视图投影矩阵。

//eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz//
matrix view = (0, 0, -20, 0, 0, -1, 0, 1, 0);

matrix projection = (0, width, 0, height, 1, 100);
glViewport(0, width, 0, -height);

创建此视图和投影矩阵并将它们传递给 gpu 后。

然后我创建一个从 -1,-1 to 1, 1 开始的四边形,这样它的原点就在中心。

然后我为四边形制作一个比例矩阵,以便我可以在屏幕上实际看到它。它呈现为一个完美的正方形,但 glViewport 或透视矩阵当然不应该是正方形。它应该是矩形的。

如何设置 glViewport 以及透视矩阵,以便保持纵横比。

例如,我现在的宽高比是 width/height。我如何将它与投影矩阵和 glviewport 一起使用?

@Reto 可能是正确的,我想多了,但 opengl 应用程序界面对我来说有点棘手。

编辑 我画了一张图希望能帮助澄清事情。

假设我希望视口为 320x480 像素。我想要两种不同的缩放模式可供选择。要么保持固定的高度 其中宽度会增加以显示更多水平视图或固定宽度和增加高度以显示更多垂直视图。

这是图片

假设我设计了一个大约 320x480 的场景并布置了所有内容并且我知道我想将宽度缩放得更大但保持固定高度。

如何使用 glViewport 和正交投影矩阵从我的宽高比实现这一点?

使用正交投影时,您可以简单地将正交矩阵视为在 xy 平面中定义一些轴对齐的二维矩形,它描述了 场景的区域映射到视口。如果该矩形的纵横比与视口的纵横比不匹配,图像将相应地变形。

让我们使用以下定义:

V: aspect of the viewport:
  V = viewport_width / viewport_height
P: aspect of the ortho projection:
  P = (right - left) / (top - bottom)
O: aspect of some axis-aligned rectangle which is drawn
  O = (x_max - x_min) / (y_max - y_min)

应用转换后,对象将以 O / P * V 的纵横比出现在屏幕上。

通常,当谈到"keeping aspect ratio"时,我们设置P == V,以便V / P在上面的公式中相互抵消,并且对象以与绘制的纵横比完全相同的比例出现在眼里 space.

这正是您使用代码得到的结果。:

Then I create a quad going from -1,-1 to 1, 1 so that it's origin is at the center.

一个正方形,我想知道在保持纵横比不变的情况下,您怎么能期望它显示为矩形。

从您的图像中可以清楚地看出,您感兴趣的对象是一个纵横比为 2/3 的矩形。所以你也应该把它画成一个这样长宽比的矩形。有多种方法可以实现这一目标。由于视口大小似乎是给定的,您仍然可以调整 O P 或两者

但是,在我看来,您似乎完全把事情复杂化了。如果我没看错,你有一些 "design space" 的 320x480 像素,这是你总是希望在屏幕上可见的 "region of interest",无论视口大小是多少。为此,您可以执行以下操作:

float target_width = 320.f;
float target_height = 480.f;
float A = target_width / target_height; // target aspect ratio 
// ... calculate V as above
if (V >= A) {
    // wide viewport, use full height
    ortho(-V/A * target_width/2.0f, V/A * target_width/2.0f, -target_height/2.0f, target_height/2.0f, ...);
} else {
    // tall viewport, use full width
    ortho(-target_width/2.0f, target_width/2.0f, -A/V*target_height/2.0f, A/V*target_height/2.0f, ...);
}

现在,您可以在 "design range" 像素中工作。在该示例中,始终可见的范围将从 (-160, -240) 到 (160, 240)`,如果您使用该坐标精确绘制矩形,它将与图像中任何视口中的蓝色框相匹配.如果你不想原点居中,当然可以翻译一下。