views:

34

answers:

1

Here is a quick and dirty GLUT based C++ program for windows that draws two rectangles, blue and green on a flat red background. Pressing 'a' or 'z' makes them orbit along the X axis in either direction. My problem is that if I enable GL_DEPTH_TEST, it sometimes draws one rectangle, sometimes two or sometimes just the background but never correctly with the nearer polygon obscuring some or all parts of the farther one. Not setting GL_DEPTH_TEST just makes the polygons appear in the drawing order.

What's wrong with the code below?

#include <windows.h>

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cmath>

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")

int angle = 0;

void oglDraw()
{
    angle += 360;
    angle %= 360;
    float fAngle = angle / (180 / 3.14159);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(90, 1, 0, 10);
    gluLookAt(0, 0, -1, 0, 0, 1, 0, 1, 0);

    float yFactor = 1;
    float zFactor = 1; 
    float y = yFactor * sin(fAngle);
    float z = 1 + zFactor - cos(fAngle) * zFactor;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glClearColor(1, 0, 0, 1);

    glPolygonMode(GL_FRONT, GL_FILL);

    glBegin(GL_POLYGON);
    glColor4f(0, 0, 1, 1);
    glVertex3f(-1.0, y-1.0, z);
    glVertex3f(+1.0, y-1.0, z);
    glVertex3f(+1.0, y+1.0, z);
    glVertex3f(-1.0, y+1.0, z);
    glEnd();

    fAngle = (180 - angle) / (180 / 3.14159);
    y = -yFactor * sin(fAngle);
    z = 1 + zFactor - cos(fAngle) * zFactor;

    glBegin(GL_POLYGON);
    glColor4f(0, 1, 0, 1);
    glVertex3f(-1.0, y-1.0, z);
    glVertex3f(+1.0, y-1.0, z);
    glVertex3f(+1.0, y+1.0, z);
    glVertex3f(-1.0, y+1.0, z);
    glEnd();

    glFlush();
    glutSwapBuffers();
}
//////////////////////////////////////////////////////////////////////////

void oglKeyboard(byte ch, int x, int y)
{
    if(ch == 'z')
    {
        angle++;

        glutPostRedisplay();

    }
    else
    if(ch == 'a')
    {
        angle--;

        glutPostRedisplay();
    }
}
//////////////////////////////////////////////////////////////////////////

int main(int argc, char **argv)
{
    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
    glutInitWindowSize(1024, 768);
    glutCreateWindow("OGL test");
    gluOrtho2D(0, 1024, 768, 0);

    glEnable(GL_DEPTH_TEST);
    glutDisplayFunc(oglDraw);
    glutKeyboardFunc(oglKeyboard);

    glutMainLoop();
}
+1  A: 

Pass something greater than zero for gluPerspective()'s zNear:

gluPerspective(90, 1, 0.1, 10);
genpfault
Absolutely right!Thanks, I've been tearing my hair for the past few hours!!!!
rep_movsd
@rep_movsd: Thank you for posting a complete, minimal, easy-to-compile program demonstrating the problem. That always makes this sort of thing *much* easier! :)
genpfault
This is a good reference on picking the right values for near and far z-buffer planes: http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html
Carlos Scheidegger