【问题标题】:Opengl: 2d HUD over 3DOpengl:2d HUD 超过 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 渲染显示

标签: c++ opengl


【解决方案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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多