理解OpenGL中窗口坐标的解释

时间:2014-10-21 12:19:42

标签: opengl

我试图更深入地理解OpenGL,我遇到了以下问题。

此段描述了我的理解,输出是假定的。

glViewport(0, 0 ,800, 480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-400.0, 400.0, -240.0, 240.0, 1.0, 100.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -1);
glRotatef(0, 0, 0, 1);

glBegin(GL_QUADS);
    glVertex3f(-128, -128,  0.0f); 
    glVertex3f(128, -128,  0.0f);
    glVertex3f(128,  128,  0.0f);
    glVertex3f(-128,  128,  0.0f);
glEnd();

上述代码段的窗口坐标(Wx,Wy,Wz)为

  • (272.00000286102295,111.99999332427979,5.9604644775390625e-008)
  • (527.99999713897705,111.99999332427979,5.9604644775390625e-008)
  • (527.99999713897705,368.00000667572021,5.9604644775390625e-008)
  • (272.00000286102295,368.00000667572021,5.9604644775390625e-008)

我做了glReadPixels()并转储到bmp文件。在图像中,我得到了上面提到的(Wx,Wy)预期的四边形(因为图像的来源,原点位于左上角,同时验证bmp图像我负责减去窗口高度,即480)。根据我的理解输出 - (Wx,Wy)将用作2D坐标,Wz将用于深度目的。

现在问题来了。我尝试了下面的代码片段。

glViewport(0, 0 ,800, 480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-400.0, 400.0, -240.0, 240.0, 1.0, 100.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(100, 0, -1);
glRotatef(30, 0, 1, 0);

glBegin(GL_QUADS);
    glVertex3f(-128, -128,  0.0f); 
    glVertex3f(128, -128,  0.0f);
    glVertex3f(128,  128,  0.0f);
    glVertex3f(-128,  128,  0.0f);
glEnd()

上述代码段的窗口坐标为

  • (400.17224205479812,242.03174613770986,1.0261343689191909)
  • (403.24386530741430,238.03076912806583,0.99456100555566640)
  • (403.24386530741430,241.96923087193414,0.9956100555566640)
  • (400.17224205479812,237.96825386229017,1.0261343689191909)

当我将输出转储到bmp文件时,我希望有一个非常小的平行四边形(大约像4 x 4平方转换为平行四边形)基于上面的(Wx,Wy)。但事实并非如此。图像具有不同的坐标集,如下所示

  • (403,238)
  • (499,113)
  • (499,366)
  • (403,241)

我已经提到了CW方向上的坐标,如图所示。

我迷路了。任何人都可以帮助理解第二种情况发生的原因和原因? 当计算出的窗口坐标中没有位置时,我怎么在屏幕上得到一个点(499,113)?

我使用了gluProject()到窗口坐标。

注意:我使用的是OpenGL 2.0。我只是想了解这里的概念,所以请不要建议使用版本> OpenGL 3.0。


修改

这是derhass发布的答案的更新

第二种情况的投影矩阵之后的同质坐标如下

  • ( - 0.027128123630699719,-0.53333336114883423,-66.292930483818054,-63.000000000000000)
  • (0.52712811245482882,-0.53333336114883423,64.292930722236633,65.00000000000000)
  • (0.52712811245482882,0.53333336114883423,64.292930722236633,6500.000000000000000)
  • ( - 0.027128123630699719,0.53333336114883423,-66.292930483818054,63.000000000000000)

所以这里的顶点是z> -1,顶点将在近平面处被剪裁。在这种情况下,不应该使用投影点在z = -1平面?

1 个答案:

答案 0 :(得分:0)

你在这里缺少的是剪辑

在此之后

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-400.0, 400.0, -240.0, 240.0, 1.0, 100.0);

你基本上有一个相机在原点,沿着-z方向和z=-1处的近平面,z=-100处的远平面。现在你绘制一个128x128的正方形,以y(向上)轴旋转30度,沿着z向前移动-1(沿着x向100移动,但这不是关键点这里)。由于您围绕其中心点旋转了方形,因此两个点的z值将在近平面之前,而其他两个应该落入平截头体。 (你也可以看到这两点符合你的期望)。

现在直接将所有4个点投射到窗口空间不是GL所做的。它将点转换为clip space,将基元与视锥体的所有6个边相交,最后将剪切的图元投影到窗口空间中进行光栅化。

你所做的投射实际上只对位于平截头体内的点有意义。你的两个点位于 camrea后面,相机后面的投影点会在相机前面创建这些点的镜像。