5

我下面的程序必须显示一个用简单灯照亮的旋转立方体。问题是立方体在闪烁。当我撤回调用 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) 的屏幕(面孔在闪烁)

在此处输入图像描述

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

在此处输入图像描述

我尝试了几种代码组合都没有成功。

有人可以帮助我吗?

在此先感谢您的帮助。

4

1 回答 1

8

您的近剪裁平面设置不正确,因此您的 Z 缓冲不起作用。

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

将其设置为合理的距离 - 尽可能远的距离。

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

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

于 2013-03-18T23:09:34.693 回答