Opengl:2d HUD 超过 3D

Posted

技术标签:

【中文标题】Opengl:2d HUD 超过 3D【英文标题】:Opengl: 2d HUD over 3D 【发布时间】:2011-03-29 02:26:48 【问题描述】:

我查看了此处发布的有关此事的一些问题,但仍然无法弄清楚为什么我的 2d HUD 出现但让我的 3d 渲染世界消失了。

编辑:似乎 2d 场景正在控制整个屏幕,所以我不时可以看到 3d 场景在 2d 场景中出现故障。因此,即使我只需要渲染一个 10 x 10 像素的四边形,它也会渲染它,然后将屏幕的其余部分空白。

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0,(GLdouble)x/(GLdouble)y,0.5,20.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,x,y);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0,-0.5,-6.0);

glPushMatrix();

..Draw some 3d stuff...

glPopMatrix();
// Start 2d
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(0.0f, 255.0f, 1.0f);
glBegin(GL_QUADS);
    glVertex2f(0.0, 0.0);
    glVertex2f(10.0, 0.0);
    glVertex2f(10.0, 10.0);
    glVertex2f(0.0, 10.0);
glEnd();

然后我交换缓冲区

这是我的代码的顺序。就像它产生了 3d 空间,然后产生了 2d 空间,这反过来又抵消了 3d 空间。

【问题讨论】:

SCREEN_WIDTHx 有什么区别(用于glViewport)?如果您注释掉最后六行,但保留 2-D 设置,3-D 渲染是否仍然消失?你能把它缩小到干扰 3-D 部分的一行或命令吗? @Ben Voigt:如果我注释掉最后 6 行(从 glbegin() 开始),3d 渲染仍然不会出现。 SCREEN_WIDTH 和 X 是一样的,不知不觉做了两个 var 还没整理。 好的,继续注释 2-D 设置代码,直到 3-D 世界回来。一次一行或使用二进制搜索来分而治之。可能您正在更改 OpenGL 状态,假设 3-D 代码保持默认状态,例如纹理或着色器或类似的东西。 @Ben Voigt:如果我从第二个 glMatrixMode(GL_PROJECTION); 注释掉 3d 渲染显示 【参考方案1】:

花了一点时间才弄明白,所以以防万一其他人有同样的问题:

    ...After Drawing 3d Stuff...

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0, -1.0, 10.0);
glMatrixMode(GL_MODELVIEW);
//glPushMatrix();        ----Not sure if I need this
glLoadIdentity();
glDisable(GL_CULL_FACE);

glClear(GL_DEPTH_BUFFER_BIT);

glBegin(GL_QUADS);
    glColor3f(1.0f, 0.0f, 0.0);
    glVertex2f(0.0, 0.0);
    glVertex2f(10.0, 0.0);
    glVertex2f(10.0, 10.0);
    glVertex2f(0.0, 10.0);
glEnd();

// Making sure we can render 3d again
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
//glPopMatrix();        ----and this?

...Then swap buffers...

:)

【讨论】:

pop 逆向push-order。可能那些矩阵堆栈是分开的,但无论如何它不会受到伤害。我也认为pushMatrix 在这种情况下是不必要的。 @LumpN:我不确定你在pop 的逆向push-order 中提到了什么 我认为他的意思是注释掉的glPopMatrix() 应该在项目矩阵重置之前进行。 对于 2D HUD 使用 gluOrtho2D() 而不是 glOrtho() 可能会更好。 有人知道如何将 3D 照明转换为 2D 色彩吗?【参考方案2】:

如果您要在 3D 上叠加 2D 正射投影,您通常希望将深度缓冲区排除在等式之外:

glDepthMask(GL_FALSE);  // disable writes to Z-Buffer
glDisable(GL_DEPTH_TEST);  // disable depth-testing

当然,在进行下一个 3D 通道之前,您需要将它们重置为原始值。

【讨论】:

【参考方案3】:
glViewport(0, 0, x, y); //You need to do this only once on viewport resize

//Setup for 3D
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(40.0, (GLdouble)x/(GLdouble)y, 0.5, 20.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity;

glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BIT);

// ... Render 3D ...

//Setup for 2D
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity;

glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BIT);

// ... Render 2D ...

SwapBuffers;

请注意,如果您完全在 3D 之上渲染 2D,则无需处理矩阵的 Push/Pop。

【讨论】:

以上是关于Opengl:2d HUD 超过 3D的主要内容,如果未能解决你的问题,请参考以下文章

SDL 3d OpenGL:立方体上的纹理产生空白屏幕

Android - 使用 openGL ES 绘制 3D 然后 2D

opengl窗口超过分辨率

四边形OpenGL之间的碰撞检测

Qt 中是不是有任何形式的开发者HUD?

如何在我的 Scenekit.scene 之上创建 HUD