2

我在一个使用 gluOrtho2D() 设置的矩阵执行所有渲染的程序中乱七八糟。我想做的是围绕 y 轴 (0,1,0) 旋转特定纹理,以便看起来原始矩阵是由 gluPerspective() 提供的。我意识到这对于正交投影矩阵是不可能的,我将不得不设置一个新的透视投影矩阵。我希望我绘制的纹理看起来与使用正交矩阵绘制时完全相同,除非有时我将它们围绕 y 轴旋转。

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

4

3 回答 3

4

基本上我的理解是:当对象位于 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 方案,您将不得不自己完成大部分工作,但这应该很容易。

于 2012-03-06T16:36:34.097 回答
0

即使您的投影矩阵是正交的,也可能具有透视效果,即围绕 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 之外的任何负数。

几个注意事项:

  1. 如果你调用 glRotate*,这个矩阵首先出现,因为这些内置调用是右手乘法。如果您按照教科书上的建议使用左手乘法跟踪您自己的视图矩阵,则该矩阵排在最后。无论哪种方式,这个矩阵实际上都会乘以你的正交项目矩阵,所以你也可以预先计算
  2. z 实际上是模拟的 z 深度,所以它的大小越大,对象越远,因此,旋转看起来更像是正交的。Z 不能为正,因为这会使 NDC 中的 w 为负,OpenGL 不允许这样做,它会被剪裁,所以什么都不会绘制
  3. 最后,没有魔法,这个矩阵只是一个补偿,在你做: M(ortho) XM(magic) 之后,你得到一个透视矩阵
  4. 如果您的代码的 99% 用于正交但只有一两个地方需要透视效果,则此技巧至关重要,那么您无需在两种模式之间切换,如果您使用固定管道,则 GL_PROJECTION_MATRIX 将保持不变
  5. 这个矩阵取自 Android Open Source Project 所以希望这会给你很大的信心
于 2013-07-08T09:45:11.940 回答
0

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

我已经厌倦了告诉这个,但是:

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

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

reshape(width, height):
    glViewport(0,0,width,height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    projection_setup()

他们看到在 reshape 函数中完成了投影,并认为这是唯一可以这样做的地方。请与我交谈: 投影矩阵只是用于绘图的某种状态。它可以像当前颜色或纹理一样轻松更改。

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

于 2012-03-06T18:29:07.837 回答