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

use*_*950 2 c opengl viewport aspect-ratio

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

int width = 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);
Run Code Online (Sandbox Code Playgroud)

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

然后我创建了一个四边形,-1,-1 to 1, 1以便它的原点位于中心.

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

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

例如,我现在的宽高比是宽度/高度.如何将其与投影矩阵和glviewport一起使用?

@Reto可能是正确的,我正在推翻这个但是opengl应用程序界面对我来说有点棘手.

编辑 我画了一张图片,希望有助于澄清事情.

假设我希望我的视口为320x480像素.我想要两种不同的缩放模式,我可以选择.保持一个固定的高度,宽度将增加,以显示更多的水平视图或固定的宽度,增加的高度,以显示更多的垂直.

这是图像在此输入图像描述

假设我设计了一个320x480左右的场景,我把所有东西都放在外面,我知道我想扩大宽度,但保持一个固定的高度.

如何使用我的纵横比的glViewport和正交投影矩阵实现这一目标?

der*_*ass 5

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

我们使用以下定义:

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)
Run Code Online (Sandbox Code Playgroud)

应用变换时,对象将O / P * V在屏幕上显示宽高比.

通常,"保持纵横比"的发言时,我们设置P == V以便V / P相互抵消在上式中,和对象会与它们究竟在眼空间中提取该长宽比.

这正是您使用代码所获得的.:

然后我创建了一个四边形,-1,-1 to 1, 1以便它的原点位于中心.

一个正方形,我想知道如果保留纵横比,你怎么能想到它会变成一个矩形.

从您的图像中可以清楚地看出,您感兴趣的对象是长宽比为2/3的矩形.因此,您还应将其绘制为具有此类宽高比的矩形.有多种方法可以实现这一目标.由于视口大小似乎是给定的,你可以门坎的调整O P 或两者.

但是,对我来说,似乎你完全过于复杂化.如果我找到了你,你有一些320x480像素的"设计空间",这是你感兴趣的"感兴趣的区域",无论视口大小是什么,你总是希望在屏幕上看到它.为此,您可以执行以下操作:

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, ...);
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以在像素的"设计范围"中工作.在该示例中,始终可见范围将从(-160, -240)(160,240)`开始,如果您使用该坐标精确绘制矩形,则它将匹配图像中的任何视口中的蓝色框.如果您不希望原点位于中心,您当然可以翻译它.