使用glEnable(GL_DEPTH_TEST)显示不正确

时间:2013-03-18 22:31:19

标签: opengl sdl depth-buffer depth-testing

我的程序必须显示一个旋转的立方体,用简单的灯照亮。 问题是立方体正在闪烁。当我撤回调用glEnable(GL_DEPTH_TEST)时,立方体不闪烁,但我可以看到它内部的面(这是正常的,因为没有深度测试)。但是这个电话是必不可少的所以我不明白为什么这个函数的调用不能正常工作。

这是我的代码:

#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);
}

这是带glEnable(GL_DEPTH_TEST)的屏幕(面部闪烁)

enter image description here

没有这个电话(没有闪烁显示但没有深度测试)

enter image description here

我尝试了几个代码组合而没有成功。

有人可以帮助我吗?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:8)

您的近剪裁平面设置不正确,因此您的Z缓冲无法正常工作。

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

将它设置在合理的距离 - 尽可能远的地方。

另外,请勿将相机方向(即视图变换)放入投影矩阵......

最后,请注意,大多数此功能已弃用,并且在较新版本的GL中不再可用。建议的方法是处理您自己的矩阵计算,并使用可编程管道来渲染几何体。