绘制HUD但OpenGL 3D场景消失

时间:2014-05-07 00:29:34

标签: c++ opengl 3d render hud

我已经完成了许多教程,但仍然没有掌握如何使用 3D场景绘制2D HUD ,而不会发生某种灾难。我收集了herehere的一些示例代码,并计算出必须以某种方式处理矩阵的顺序(请参阅here)以实现我的目标出发去。我已经制定了一个渲染代码,如下所示:

void render()
{
    //Clear screen
    glClearColor(0.2f, 0.0f, 0.2f, 1.0f); // Clear the background of our window to red  
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
    glLoadIdentity(); //Reset the drawing perspective

    // Movement as response to input:
    glTranslatef( cam.getEye().getX(), cam.getEye().getY(), cam.getEye().getZ() ); // Translate our object along the y axis  
    glRotatef( cam.getTheta(), 0.0f, 1.0f, 0.0f ); // Rotate our object around the y axis 
    // No pushing/popping a matrix and no gluLookAt() used here.

    // ==================== Drawing scene here: ======================
    // ...
    // =================================== HUD: ==================================

    glMatrixMode(GL_PROJECTION);

    glPushMatrix();
    //glPopMatrix();

    glLoadIdentity();
    gluOrtho2D(0, winW, 0, winH); //left,right,bottom,top
    glMatrixMode(GL_MODELVIEW);

    //glPushMatrix();
    glPopMatrix();
    glLoadIdentity();

    // drawing the HUD rect here:
    glBegin(GL_QUADS);
        // ...
    glEnd();

    glPopMatrix();
    glPopMatrix();
    //glPushMatrix();
    //glPushMatrix();

    // ===============================================================================
    glutSwapBuffers(); //Send scene to the screen to be shown
}

...但由于某种原因,它只显示我的深蓝色HUD,3D场景就消失了。我究竟做错了什么?我错过了什么?我知道我应该推动投影矩阵,然后是模型视图矩阵,然后执行glOrtho2D(),然后将两个矩阵从堆栈中弹出。那没用。我厌倦了以随机顺序摆弄和弹出矩阵。

1 个答案:

答案 0 :(得分:3)

如果您的HUD是通常的叠加层,您可能需要禁用深度测试&在绘制HUD内容之前可能进行深度写入:

glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);

这样,HUD的Z值无关紧要。在绘制场景之前不要忘记重新启用。

正如其他人所观察到的那样,您也存在矩阵堆栈问题。单独的堆栈与投影和放大器相关联。 modelview矩阵。现在你正在推动投影矩阵和弹出模型视图矩阵,所以你会溢出一个并使另一个下溢。你需要推动&对称地以相同的模式弹出。鉴于您在每种模式下都以glLoadIdentity()开头,您可能根本不需要使用矩阵堆栈。

编辑:更直接的答案

以下是渲染代码的外观:

void render()
{
  //Clear screen
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  //*************************************************************************
  //* Prepare to render main scene:
  //*************************************************************************
  glEnable(GL_DEPTH_TEST);
  glDepthMask(GL_TRUE);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(...);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslatef( cam.getEye().getX(), cam.getEye().getY(), cam.getEye().getZ() );
  glRotatef( cam.getTheta(), 0.0f, 1.0f, 0.0f );

  //*************************************************************************
  //* Draw Main Scene Here:
  //*************************************************************************

  // ... 


  //*************************************************************************
  //* Prepare to render HUD overlay:
  //*************************************************************************
  glDisable(GL_DEPTH_TEST);
  glDepthMask(GL_FALSE);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(...);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  //*************************************************************************
  //* Draw HUD here:
  //*************************************************************************

  // ...


  // Finish the frame:
  glutSwapBuffers(); //Send scene to the screen to be shown
}

现在,由于您将在每次渲染调用期间调整投影矩阵两次,因此应从resizeWindow()函数中删除gluPerspective()。另外,我从渲染函数中删除了glClearColor()调用 - 最好在程序开头设置一次并忘记它。状态变化很昂贵,所以你想尽可能地避免它们。