当前位置: 首页 > 知识库问答 >
问题:

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

微生耘豪
2023-03-14

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

int宽=320;int高=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到1,1的四边形,以便它的原点位于中心。

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

如何设置glViewport以及透视矩阵,以便我可以保持长宽比。

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

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

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

假设我希望我的视口是320x480像素。我想要两种不同的缩放模式供我选择。要么保持一个固定的高度,宽度会增长以显示更多的水平视图,要么保持一个固定的宽度,高度会增长以显示更多的垂直视图。

比方说,我设计了一个320x480左右的场景,我把一切都布置好了,我知道我想把宽度放大,但保持固定的高度。

如何从纵横比使用glViewport和正交投影矩阵实现这一点?

共有1个答案

艾文斌
2023-03-14

使用 onthogonal 投影时,可以简单地将正交矩阵视为在 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)

应用转换时,对象将以宽高比O / P * V出现在屏幕上。

通常,当谈到“保持纵横比”时,我们将<code>P==V

这已经是你从你的代码中得到的:

然后我创建一个从-1,-1到1,1的四边形,以便它的原点位于中心。

那是一个正方形,我想知道当长宽比保持不变时,你怎么能期望它变成一个矩形。

从您的图像中可以清楚地看到,您感兴趣的对象是一个纵横比为2/3的矩形。因此,您也应该将其绘制为具有这样纵横比的矩形。实现这一点有多种方法。由于视口大小似乎是给定的,因此可以调整OP,或两者。

然而,在我看来,你似乎完全把事情复杂化了。如果我没弄错的话,你有一些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, ...);
}

现在,您可以在以像素为单位的“设计范围”中工作。在该示例中,始终可见的范围将从 (-160, -240) 到 (160, 240)',如果与该坐标完全匹配矩形,则它将与图像中任何视口中的蓝色框匹配。如果你不想把原点放在中心,你当然可以翻译它。

 类似资料:
  • 举个简单的例子来说明正交投影与透视投影照相机的区别。使用透视投影照相机获得的结果是类似人眼在真实世界中看到的有“近大远小”的效果(如下图中的(a));而使用正交投影照相机获得的结果就像我们在数学几何学课上老师教我们画的效果,对于在三维空间内平行的线,投影到二维空间中也一定是平行的(如下图中的(b))。 (a)透视投影,(b)正交投影 那么,你的程序需要正交投影还是透视投影的照相机呢? 一般说来,对

  • 针对不同应用的三维场景需要使用不同的投影方式,比如机械、工业设计领域常常采用正投影(平行投影), 大型游戏场景往往采用透视投影(中心投影)。为了完成三维场景不同的投影方式,three.js封装WebGL API和相关算法,提供了正投影相机OrthographicCamera和透视投影相机PerspectiveCamera。 正投影和透视投影简单解释 下面对正投影相机和透视投影相机的投影算法进行简单

  • 问题内容: 我试图在OpenGL中使用gluUnProject,首先我需要获取projectoin,model_view和viewort矩阵。根据我在网上找到的例子 但是我收到错误消息“ ValueError:glGetFloatv需要1个参数(pname),收到2:(GL_PROJECTION_MATRIX,[])” 那么,我应该使用什么来获取这些矩阵? 问题答案: 也许: 之后在变量中应该是投

  • 我要直截了当地说。我已经做了一些研究,但仍然没有弄清楚这一点。 我有一个程序,用一种颜色画一个立方体的每个面。然后我在Y轴和X轴上旋转这个立方体(-分别为45°和45°)。 问题在于它没有像我预期的那样呈现,立方体在某个时候被剪切。 代码: 我定义的所有顶点都是用±0.25制作的。所以我认为,至少用我的这些zNear和zFar值,它们仍然适合体积,但当我改变线时 为 它工作得很好 但是它不能与 有

  • 本文向大家介绍OpenGL ES透视投影实现方法(四),包括了OpenGL ES透视投影实现方法(四)的使用技巧和注意事项,需要的朋友参考一下 在之前的学习中,我们知道了一个顶点要想显示到屏幕上,它的x、y、z分量都要在[-1,1]之间,我们回顾一下渲染管线的图元装配阶段,它实际上做了以下几件事:剪裁坐标、透视分割、视口变换。图元装配的输入是顶点着色器的输出,抓哟是物体坐标gl_Position,

  • MongoDB 中的投影即查询指定的字段,而不是直接查询文档的全部字段。比如说某个文档中有 5 个字段,而我们只需要其中的 3 个字段,那么就可以使用 MongoDB 中的投影来指定需要查询的 3 个字段。 在《 MongoDB查询文档》一节中我们介绍的 find() 方法,在使用 find() 方法时,如果不设置其中的第二个参数,那么在查询时将返回文档中的所有字段,想要限制要查询的字段,您就需要