Opengl 如何找到与正交矩阵等效但在不在xy平面时提供透视的投影矩阵?

Opengl 如何找到与正交矩阵等效但在不在xy平面时提供透视的投影矩阵?,opengl,perspective,orthographic,Opengl,Perspective,Orthographic,我在一个程序中胡闹,该程序使用gluOrtho2D()设置的矩阵执行所有渲染。我想做的是围绕y轴(0,1,0)旋转一个特定的纹理,使其看起来像原始矩阵是由gluPerspective()提供的。我意识到这在正交投影矩阵中是不可能的,我必须建立一个新的透视投影矩阵。我希望我绘制的纹理看起来与使用正交矩阵绘制时完全相同,除非有时我绕y轴旋转纹理 总之: 当形状在xy平面上绘制时,如何找到与给定正交矩阵等效的透视投影矩阵,但当形状不在xy平面上时,如何找到与给定正交矩阵等效的透视投影矩阵?基本上我理解

我在一个程序中胡闹,该程序使用gluOrtho2D()设置的矩阵执行所有渲染。我想做的是围绕y轴(0,1,0)旋转一个特定的纹理,使其看起来像原始矩阵是由gluPerspective()提供的。我意识到这在正交投影矩阵中是不可能的,我必须建立一个新的透视投影矩阵。我希望我绘制的纹理看起来与使用正交矩阵绘制时完全相同,除非有时我绕y轴旋转纹理

总之:

当形状在xy平面上绘制时,如何找到与给定正交矩阵等效的透视投影矩阵,但当形状不在xy平面上时,如何找到与给定正交矩阵等效的透视投影矩阵?

基本上我理解的是:您希望有一个透视矩阵,该矩阵产生与正交投影相同的图像,当对象位于XY平面中时

因此,让我们开始: 您希望在XY平面中绘制平面,您有
gluOrtho2D(-w,w,-h,h)(不对称正交投影有点难,如果你需要,就说出来)。
您现在需要做的是:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(2 * atan(h / 2)  * 180.0 / PI, w / h, 1, 3);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -2);
我在这里所做的是匹配正投影中可见的XY平面截面上投影视锥台的中心

拿投影截锥的图形和一些数学,你可以自己做:)


作为提醒,我将把我对老问题的答案留在这里

要么是正交投影,要么是透视投影。你得选一个。 在任何轴上旋转都不会获得透视效果

为什么要改变整个程序才能改变投影模式

一种可能的解决办法: 我假设旧GL具有不同的矩阵模式等:

glMatrixMode(GL_PROJECTION); //switch to projection matrix mode
glPushMatrix(); //push the old matrix
glLoadIdentity();
//apply the perspective projection
//do your rendering
glPopMatrix(); //pop the old matrix

对于较新的GL方案,您必须自己完成大部分工作,但这应该很容易。

基本上我的理解是:当对象位于XY平面时,您希望有一个透视矩阵,该矩阵产生与正交投影相同的图像

因此,让我们开始: 您希望在XY平面中绘制平面,您有
gluOrtho2D(-w,w,-h,h)(不对称正交投影有点难,如果你需要,就说出来)。
您现在需要做的是:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(2 * atan(h / 2)  * 180.0 / PI, w / h, 1, 3);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -2);
我在这里所做的是匹配正投影中可见的XY平面截面上投影视锥台的中心

拿投影截锥的图形和一些数学,你可以自己做:)


作为提醒,我将把我对老问题的答案留在这里

要么是正交投影,要么是透视投影。你得选一个。 在任何轴上旋转都不会获得透视效果

为什么要改变整个程序才能改变投影模式

一种可能的解决办法: 我假设旧GL具有不同的矩阵模式等:

glMatrixMode(GL_PROJECTION); //switch to projection matrix mode
glPushMatrix(); //push the old matrix
glLoadIdentity();
//apply the perspective projection
//do your rendering
glPopMatrix(); //pop the old matrix
使用较新的GL方案,您必须自己完成大部分工作,但这应该很容易

这是否可以以某种简单的方式实现,而不必将所有程序转换为使用gluPerspective()

我已经厌倦了这样说,但是:

投影不是一次性定义然后在整个渲染过程中强制执行的。您可以随时切换它,对于任何高级渲染方案,都会在单个帧中多次切换

我认为大多数新手对此感到困惑:

reshape(width, height):
    glViewport(0,0,width,height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    projection_setup()
他们看到了整形功能中的投影,认为这是唯一可以实现的地方。 请跟我说: 投影矩阵只是用于绘图的某种状态,与其他任何状态一样。它可以像更改当前颜色或纹理一样轻松

只需在绘图之前,根据需要为特定序列的绘图命令设置所需的投影即可

这是否可以以某种简单的方式实现,而不必将所有程序转换为使用gluPerspective()

我已经厌倦了这样说,但是:

投影不是一次性定义然后在整个渲染过程中强制执行的。您可以随时切换它,对于任何高级渲染方案,都会在单个帧中多次切换

我认为大多数新手对此感到困惑:

reshape(width, height):
    glViewport(0,0,width,height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    projection_setup()
他们看到了整形功能中的投影,认为这是唯一可以实现的地方。 请跟我说: 投影矩阵只是用于绘图的某种状态,与其他任何状态一样。它可以像更改当前颜色或纹理一样轻松


在绘图之前,只需根据需要设置绘图命令序列所需的投影。

即使投影矩阵是正交的,也可以产生透视效果,即绕x或y轴旋转,诀窍是在任何其他视图转换之前/之后,将视图矩阵乘以此魔法矩阵:

// The matrix is
// -z,  0,  x,  0
//  0, -z,  y,  0
//  0,  0,  1,  0
//  0,  0,  1, -z
其中:

  • x
    是视口宽度的一半
  • y
    是视口高度的一半
  • z
    可以是除-0之外的任何负数
几点注意:

  • 如果u r调用glRotate*,该矩阵将首先执行,因为这些内置调用是右手乘法。如果你像教科书上建议的那样,用左手乘法来跟踪你自己的视图矩阵,这个矩阵就排在最后。无论采用哪种方式,该矩阵实际上都将与正交项目矩阵相乘,因此u也可以进行预计算
  • z实际上是模拟的z深度,因此其大小越大,对象越远,因此,旋转看起来更像正交。Z不能为正,因为这将使NDC中的w为负,OpenGL不允许这样,它将被剪裁为负