Display not correct using glEnable(GL_DEPTH_TEST)
Asked Answered
P

1

5

My program below must display a cube in rotation illuminated with a simple light. The problem is the cube is flashing. When I withdraw the call glEnable(GL_DEPTH_TEST) the cube is not flashing but I can see the faces inside it (it's normal because there is no depth test). However this call is essential. So I don't understand why the call of this function does not work correctly.

Here's my code :

#include <iostream>
#include <SDL/SDL.h>
#include <gl/glut.h>

const static int    WIDTH = 640;
const static int    HEIGHT = 480;

GLfloat angle = 0.0f;

static GLfloat  position[4] = {0.0, 50.0, -50.0, 1.0};
static GLfloat diffuse[3] = {0.64, 0.64, 0.64};
static GLfloat specular[3] = {0.64, 0.64, 0.64};
static GLfloat emissive[3] = {0.0, 0.0, 1.0};

static GLfloat vertices[72] =
{
    1.000000, -1.000000, -1.000000,     //V1
    1.000000, -1.000000, 1.000000,      //V2
    -1.000000, -1.000000, 1.000000,     //V3
    -1.000000, -1.000000, -1.000000,    //V4

    1.000000, 1.000000, -0.999999,      //V5
    -1.000000, 1.000000, -1.000000,     //V8
    -1.000000, 1.000000, 1.000000,      //V7
    0.999999, 1.000000, 1.000001,       //V6

    1.000000, -1.000000, -1.000000,     //V1
    1.000000, 1.000000, -0.999999,      //V5
    0.999999, 1.000000, 1.000001,       //V6
    1.000000, -1.000000, 1.000000,      //V2

    1.000000, -1.000000, 1.000000,      //V2
    0.999999, 1.000000, 1.000001,       //V6
    -1.000000, 1.000000, 1.000000,      //V7
    -1.000000, -1.000000, 1.000000,     //V3

    -1.000000, -1.000000, 1.000000,     //V3
    -1.000000, 1.000000, 1.000000,      //V7
    -1.000000, 1.000000, -1.000000,     //V8
    -1.000000, -1.000000, -1.000000,    //V4

    1.000000, 1.000000, -0.999999,      //V5
    1.000000, -1.000000, -1.000000,     //V1
    -1.000000, -1.000000, -1.000000,    //V4
    -1.000000, 1.000000, -1.000000      //V8
};

static GLfloat normals[72] =
{
    0.000000, -1.000000, 0.000000,
    0.000000, -1.000000, 0.000000,
    0.000000, -1.000000, 0.000000,
    0.000000, -1.000000, 0.000000,

    0.000000, 1.000000, 0.000000,
    0.000000, 1.000000, 0.000000,
    0.000000, 1.000000, 0.000000,
    0.000000, 1.000000, 0.000000,

    1.000000, 0.000000, 0.000000,
    1.000000, 0.000000, 0.000000,
    1.000000, 0.000000, 0.000000,
    1.000000, 0.000000, 0.000000,

    -0.000000, -0.000000, 1.000000,
    -0.000000, -0.000000, 1.000000,
    -0.000000, -0.000000, 1.000000,
    -0.000000, -0.000000, 1.000000,

    -1.000000, -0.000000, -0.000000,
    -1.000000, -0.000000, -0.000000,
    -1.000000, -0.000000, -0.000000,
    -1.000000, -0.000000, -0.000000,

    0.000000, -0.000000, -1.000000,
    0.000000, -0.000000, -1.000000,
    0.000000, -0.000000, -1.000000,
    0.000000, -0.000000, -1.000000
};

static void     eventListener(SDL_Event *pEvent, bool *pContinue)
{
    while (SDL_PollEvent(pEvent))
    {
        switch(pEvent->type)
        {
        case SDL_QUIT:
            *pContinue = false;
            break;
        case SDL_KEYDOWN:
            switch (pEvent->key.keysym.sym)
            {
            case SDLK_ESCAPE:
                *pContinue = false;
                break;
            }
        }
    }
}

static void     beginRender(void)
{
    /*Perspective*/

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, WIDTH, HEIGHT);
    gluPerspective(60.0, (float)(WIDTH/HEIGHT), 0.0f, 1000.0f);
    gluLookAt(0.0f, 0.0, 7.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

    /*Clear screen*/

    glClearDepth(1.0f);
    glClearColor(0.13f, 0.12f, 0.13f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    /*Prepare model transformations*/

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    /*Light settings*/

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    /*Depth test*/

    glEnable(GL_DEPTH_TEST);  //PROBLEM COMES FROM HERE
}

static void     renderFrame(void)
{
    /*light position*/

    glLightfv(GL_LIGHT0, GL_POSITION, position);

    /*Model transformations*/

    glPushMatrix();
    glRotatef(angle, 0.0f, 1.0f, 1.0f);

    /*Light materials*/

    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
    glMaterialfv(GL_FRONT, GL_EMISSION, emissive);
    glMateriali(GL_FRONT, GL_SHININESS, 10);

    /*Model rendering*/

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glNormalPointer(GL_FLOAT, 0, normals);

    glDrawArrays(GL_QUADS, 0, 24);

    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    angle += 0.010f;
    glPopMatrix();
}

static void     endRender(void)
{
    glFlush();
    SDL_GL_SwapBuffers();
}

static void     startRendering(void)
{
    bool        continuer = true;
    SDL_Event   event;

    while (continuer)
    {
        eventListener(&event, &continuer);
        beginRender();
        renderFrame();
        endRender();
    }
}

int             main(int ac, char **av)
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_WM_SetCaption("Test luminosity",NULL);
    SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL | SDL_DOUBLEBUF);

    startRendering();
    SDL_Quit();
    return (0);
}

Here's the screen with glEnable(GL_DEPTH_TEST) (faces are flashing)

enter image description here

And without this call (no flashing display but not depth test)

enter image description here

I tried several code combination without success.

Does anyone can help me ?

Thanks in advance for your help.

Paleozoic answered 18/3, 2013 at 22:31 Comment(0)
I
8

Your near clipping plane isn't set up correctly, so your Z-buffering isn't working.

gluPerspective(60.0, (float)(WIDTH/HEIGHT), 0.0f, 1000.0f);
                                            ^^^^

Set it to a reasonable distance - as far away as you can live with.

Also, don't put the camera orientation (i.e the view transform) into the projection matrix...

Finally, note that most of this functionality is deprecated, and no longer available in newer versions of GL. The recommended approach is to handle your own matrix calculations, and use the programmable pipeline to render geometry.

Ingrowth answered 18/3, 2013 at 23:9 Comment(1)
Hello, thank you very much for your answer. About matrix and geometry managing I'm going to use my own matrix managing and shaders like you said. It's my main objective. Thanks for all. Bye.Paleozoic

© 2022 - 2024 — McMap. All rights reserved.