The HUD is drawn but the OpenGL 3D scene disappers

I’ve been through a number of tutorials but still haven’t got the hang of how to draw a 2D HUD with a 3D scene without some sort of a disaster happening. I’ve gathered some sample code and worked out the order in which matrices have to be treated in a certain way to achieve exactly what I’ve set out for. I’ve worked out a rendering code as shown below:

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.

    // ==================== Positional reference exercise: ======================
    //  - plane:
    // ... plane-drawing code here ...

    // pyramid:
    // ... pyramid-drawing code here ...

    // =================================== HUD: ==================================

    glMatrixMode(GL_PROJECTION);

    glPushMatrix();
    //glPopMatrix();

    glLoadIdentity();
    gluOrtho2D(-0.5, 0.5, -0.5, 0.5);
    glMatrixMode(GL_MODELVIEW);

    glPushMatrix();
    //glPopMatrix();

    glLoadIdentity();
    glColor3f(0.0f, 0.2f, 0.2f);

    // drawing the HUD rect here:
    glBegin(GL_QUADS);
        glVertex2f(0, 0);
        glVertex2f(640, 0);
        glVertex2f(640, 75);
        glVertex2f(0, 75);
        glVertex2f(0, 0);
        glVertex2f(1, 0);
        glVertex2f(1, 1);
        glVertex2f(0, 1);
    glEnd();

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

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

… but for some reason it only displays my dark-cyan HUD and the 3D scene simply disappeared. What am I doing wrong? What have I missed? I know I’m supposed to push the projection matrix, then the model-view matrix, then do glOrtho2D(), then pop the two matrices off of the stack. That didn’t work. I’m tired of fiddling with pushing and popping matrices in a random order.

Someone said that I’m underflowing the matrix stack with glPushMatrix()/glPopMatrix() calls. I did a little digging and found. The page suggests that I should use a PushStack object, but I don’t know how. So, I started experimenting:


glMatrixMode(GL_PROJECTION);
glutil::PushStack stackPusher ( glutil::MatrixStack() );
glLoadIdentity();
gluOrtho2D(-0.5, 0.5, -0.5, 0.5);

glMatrixMode(GL_MODELVIEW);
glutil::PushStack stackPusher ( glutil::MatrixStack() );
glLoadIdentity();

glColor3f(0.0f, 0.2f, 0.2f);
// draw quad
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(640, 0);
glVertex2f(640, 75);
glVertex2f(0, 75);
glVertex2f(0, 0);
glVertex2f(1, 0);
glVertex2f(1, 1);
glVertex2f(0, 1);
glEnd();

But that didn’t work because my glutil is missing boost/array.hpp .

Anyone cares to help?

Please use [noparse]


[/noparse] around source code.
I suspect your problem is that after the first frame your 3D scene is rendered with the orthographic projection from the previous frame’s HUD rendering, because you are not setting a perspective projection first (or anywhere as far as I can see).

Your render function should probably have a structure along these lines:


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glFrustum( /* ... */ );   // or some helper function that multiplies a perspective projection onto the current matrix

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
// apply view matrix

// render 3D scene

glPopMatrix(); // remove view matrix

glMatrixMode(GL_PROJECTION);
glPopMatrix(); // remove perspective projection matrix
glPushMatrix();
glOrtho( /* ... */);   // or similar

glMatrixMode(GL_MODELVIEW);
glPushMatrix();

// render your 2D HUD

glPopMatrix(); // remove modelview changes from HUD rendering

glMatrixMode(GL_PROJECTION);
glPopMatrix(); // remove orthographic projection matrix


        // =================================== HUD: ==================================
{
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();

        gluOrtho2D (-0.5, 0.5, -0.5, 0.5);   // Your vertex coordinates are not within these bounds.
                                             // Nothing should show up.

        glMatrixMode (GL_MODELVIEW);
        glLoadIdentity ();

        glColor3f(0.0f, 0.2f, 0.2f);
	
        // drawing the HUD rect here:

        glBegin(GL_QUADS);
            glVertex2f(0, 0);
            glVertex2f(640, 0);
            glVertex2f(640, 75);
            glVertex2f(0, 75);
            glVertex2f(0, 0);
            glVertex2f(1, 0);
            glVertex2f(1, 1);
            glVertex2f(0, 1);
        glEnd();
 }

If I understand correctly, you want to overlay some 2D graphics onto a 3D scene. No Pushes and Pops should be required. The code above should do it, except that you’ve set up a coordinate system from -0.5 to +0.5 in X and Y, but have coordinates with values like 75.0 and 640.0. If you’re trying to draw these as lines, I’d be surprised if anything showed on the screen. If you’re trying to draw the quads as filled polygons, they will probably cover anything drawn before them (like your 3D scene).

My suggestion is to use gluOrtho2D (-1000, 1000, -1000, 1000), and make sure to draw the quads as lines, not filled polygons.

Good luck.