我已经看过许多教程,但仍然没有掌握如何在没有某种灾难发生的情况下用3D场景绘制2D HUD的方法。我从here和here收集了一些示例代码,并确定了必须以某种方式处理矩阵的顺序(请参见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(),然后从堆栈中弹出两个矩阵。那没用。我已经厌倦了按随机顺序推送和弹出矩阵。
最佳答案
如果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()。另外,我从render函数中删除了glClearColor()调用-最好在程序开始时将其设置一次,然后将其忘记。状态更改非常昂贵,因此您要尽可能避免更改。
关于c++ - 绘制了HUD,但OpenGL 3D场景消失了,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23506751/