搞砸了OpenGL深度缓冲区?

时间:2012-11-12 18:54:34

标签: c++ opengl-es blackberry-playbook

我的代码目前正在发生一些比较奇怪的事情。我在BlackBerry Playbook上运行它,它是OpenGL ES 1.1

编辑4:我删除了我发布的所有内容以简化我的问题。

我拿了代码并将其简化为绘制两个重叠的三角形。这是包含坐标的数组以及包含颜色的数组:

GLfloat vertices[] =
{
          // front
           175.0f, 200.0f, -24.0f,
           225.0f, 200.0f, -24.0f,
           225.0f, 250.0f, -24.0f,

          // back
           200.0f, 200.0f, -25.0f,
           250.0f, 200.0f, -25.0f,
           250.0f, 250.0f, -25.0f
};


static const GLfloat colors[] =
{
       /* front  */  1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f, //Red
       /* back  */  0.0f,1.0f,0.0f,1.0f,0.0f,1.0f,0.0f,1.0f,0.0f,1.0f,0.0f,1.0f //Green
};

请注意,我的坐标在x方向为0到1024,在y方向为0到600,在z方向为0到-10000。

这是我的设置代码,反映了这一点:

    glClearDepthf(1.0f);
    glClearColor(1.0f,1.0f,1.0f,1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glShadeModel(GL_SMOOTH);

    glViewport(0, 0, surface_width, surface_height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrthof(0, surface_width, 0, surface_height, 0, 10000);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

我在两个地方都有深度启用,因为我试图排除在选择某种矩阵模式时应该使用它的可能性。

最后这是我的渲染代码:

void render()
{
    //Typical render pass
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertices);

    glEnableClientState(GL_COLOR_ARRAY);
    glColorPointer(4, GL_FLOAT, 0, colors);

    glDrawArrays(GL_TRIANGLES, 0 , 6);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);

    //Use utility code to update the screen
    bbutil_swap();
}

问题在于,无论我做什么,绿色三角形总是覆盖在红色三角形上。无论哪种方式更改z值都不会影响完成的图像。我无法弄清楚这一点。

2 个答案:

答案 0 :(得分:5)

默认情况下,禁用深度测试。您必须使用glEnable(GL_DEPTH_TEST)启用它。当你启用剔除时它工作的原因是因为没有绘制面向后的三角形,并且由于立方体是凸多面体,所以没有前面的四边形将与另一个前面的四边形重叠。但是,如果您尝试渲染第二个立方体,除非您启用深度测试,否则您将看到深度问题。

答案 1 :(得分:3)

我终于开始工作了。问题在于我使用的EGL设置代码。在bbutil.c(在我的例子中是.cpp)中有一些代码:

if(!eglChooseConfig(egl_disp, attrib_list, &egl_conf, 1, &num_configs)) {
        bbutil_terminate();
        return EXIT_FAILURE;
    }

(这不是文件中的所有代码,但它的重要位)

如果既不支持给定的属性列表,这也基本上是怪胎。 attrib_list文件中的更高位置设置如下:

EGLint attrib_list[]= { EGL_RED_SIZE,        8,
                        EGL_GREEN_SIZE,      8,
                        EGL_BLUE_SIZE,       8,
                        EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
                        EGL_RENDERABLE_TYPE, 0,
                        EGL_NONE};

没有指定深度缓冲区。现在,如果您查看EGL规范,它表示没有深度是默认值。 BINGO,这就是问题所在。所以我只是修改它看起来像这样:

EGLint attrib_list[]= { EGL_RED_SIZE,        8,
                        EGL_GREEN_SIZE,      8,
                        EGL_BLUE_SIZE,       8,
                        EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
                        EGL_RENDERABLE_TYPE, 0,
                        EGL_DEPTH_SIZE, 24,
                        EGL_NONE};

注意EGL_DEPTH_SIZE和24.这将深度缓冲区设置为24位。在PlayBook 32上引发了分段错误,尽管通常不支持32。也许这会帮助那些试图弄清楚为什么提供的包含导致我描述为我的问题这个有趣结果的人。