c - opengl View 、投影和正交纵横比

标签 c opengl viewport aspect-ratio

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

整数宽度 = 320;
整数高度 = 480;

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

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

在创建此 View 和投影矩阵并将它们传递给 gpu 之后。

然后我从 -1,-1 to 1, 1 创建一个四边形。所以它的原点在中心。

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

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

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

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

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

假设我希望我的视口(viewport)为 320x480 像素。我想要两种不同的缩放模式可供选择。要么保持固定高度
宽度将增长以显示更多水平 View 或固定宽度随着高度增长以显示更多垂直。

这是图片enter image description here

假设我设计了一个 320x480 左右的场景,我把所有东西都布置好了,我知道我想扩大宽度但保持一个固定的高度。

如何通过我的纵横比使用 glViewport 和正交投影矩阵来实现这一点?

最佳答案

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

让我们使用以下定义:

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 出现屏幕上。

通常,当谈到“保持纵横比”时,我们设置P == V这样V / P在上面的公式中相互抵消,并且对象以它们在眼睛空间中绘制的纵横比出现。

这已经正是您使用代码所得到的。:

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



那是一个正方形,我想知道在保留纵横比的情况下,你怎么能期望它变成一个矩形。

从您的图像中,很明显您感兴趣的对象是一个长宽比为 2/3 的矩形。因此,您还应该将其绘制为具有这种纵横比的矩形。有多种方法可以实现这一目标。由于视口(viewport)大小似乎是给定的,您可以调整OP或两者。

但是,对我来说,您似乎完全使事情复杂化了。如果我猜对了,您就有一些 320x480 像素的“设计空间”,这是您始终希望在屏幕上可见的“感兴趣区域”,无论视口(viewport)大小如何。为此,您可以执行以下操作:
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, ...);
}

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

关于c - opengl View 、投影和正交纵横比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35810782/

相关文章:

java - 在 JOGL 中调整图形窗口大小和视口(viewport)转换

c - 所有结构类型都应该包含在同一个头文件中吗?

C 复制到从 malloc 创建的字符串

c - 如何让数组的输入函数根据特定的输入和大小终止?

opengl - 选择性 nvidia #pragma optionNV(全部展开)

c++ - 使用 glDrawElementsInstanced 进行实例渲染时行为不一致,有时没有渲染也没有错误

html - Div 在 iOS 窗口外拉伸(stretch)

c - C 中的 Strcat 两个无符号字符

c++ - Gtk 3 - 在哪里以及如何指定主循环的内容?

javascript - Three.js 中心 3d 模型