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

了解OpenGL中窗口坐标的解释

郭和硕
2023-03-14

我试图更深入地理解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.02613436891909)
  • (403.24386530741430,238.03076912806583,0.99456100555566640)
  • (403.24386530741430,241.96923087193414,0.99456100555566640)
  • (400.17224205479812,237.96825386229017,1.02613436891909)

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

    < li>(403,238) <李>(499,113) < li>(499,366) < li>(403,241)

我已经提到了图像上看到的CW方向的坐标。

我在这里迷路了。有人能帮忙理解第二个案例中发生了什么以及为什么会发生吗??为什么我在屏幕上看到一个点(499,113 ),而它在计算的窗口坐标中并不存在?

我使用 gluProject() 来表示窗口坐标。

注意:我正在使用OpenGL 2.0。我只是试图理解这里的概念,所以请不要建议使用版本

编辑

这是derhass发布的答案的更新

第二种情况下投影矩阵后的齐次坐标如下:

  • (-0.027128123630699719, -0.53333336114883423, -66.292930483818054, -63.0000000000000000000)
  • (0.52712811245482882, -0.53333336114883423, 64.292930722236633, 65.00000000000000000000000)
  • (0.52712811245482882, 0.53333336114883423, 64.292930722236633, 65.000000000000000000000000)
  • (-0.027128123630699719, 0.53333336114883423, -66.292930483818054, 63.00000000000000000000000000000)

所以这里是z的顶点

共有1个答案

孙成化
2023-03-14

这里缺少的是剪辑。

之后

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所做的。它将点转换为剪辑空间,将图元与视见截头体的所有6个边相交,最后将剪裁图元投影到窗口空间进行光栅化。

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

 类似资料:
  • 我目前正在做一个libgdx项目。这就是我要遵循的结构: 单个游戏-几个屏幕-每个屏幕有一个舞台-每个舞台有一些组-每个组有一些演员-每个演员有一个精灵。 我正在玩在组之间拖动演员,但是当我将演员添加到组中时,即使我指定了其他人,坐标也始终为0,0。 我读过一些关于局部坐标和舞台坐标的内容。 问题是...如何在组的中间添加一个Actor(及其精灵)?

  • 所以我有一个java JFrame,我把画布放进去,它出现在错误的坐标上,好像它把0,0作为左下角,而不是左上角。这是我的密码。 为什么不使用常规窗口坐标(如0,0为左上角)?

  • 从我的阅读中,我了解到LibGdx使用左下角表示0、0和yup。好吧。我看到,如果我愿意,很容易将其改为y,但我不明白接下来创建的代码。 对于创建的默认精灵,位置设置如下。 当我运行这个基本程序时,我看到我添加的标志图像在屏幕上居中。我想要理解的是,为什么设置位置的值是负值,为什么使用sprite width和height而不是视图端口的w、h?如果我更改为屏幕宽度和高度,那么图像将绘制在屏幕右下

  • 我正在尝试学习windows上的opengl编程,虽然我最初是从SDL开始的,但我已经决定放弃它,以便学习如何使用WGL自己启动OpenGL上下文。 我使用nanovg作为一个快速的图形绘制库,用SDL渲染一切都很好,但是,现在我已经移除了SDL,创建了我自己的窗口和OpenGL上下文,我发现窗口的标题栏与渲染区域重叠了。好像渲染区域的原点(0,0)在整个窗口的左上方,而不是标题栏的正下方,如果这

  • 我通过GLX在Linux中编写了一个OpenGL应用程序。它使用双缓冲与glXSwapBuffers和同步到VBlank设置通过NVIDIA X服务器设置设置。我正在使用Compiz,并且可以平滑地移动窗口并且没有撕裂(在Compiz设置中启用了同步到VBlank)。但当我 > 尝试移动 OpenGL 窗口或调整其大小,或 通过OpenGL窗口占用的区域移动其他窗口 系统断断续续,停顿3-4秒。将