搞砸了OpenGL深度缓冲区?

use*_*468 0 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
};
Run Code Online (Sandbox Code Playgroud)

请注意,我的坐标在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);
Run Code Online (Sandbox Code Playgroud)

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

最后这是我的渲染代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

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

小智 5

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


use*_*468 5

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

if(!eglChooseConfig(egl_disp, attrib_list, &egl_conf, 1, &num_configs)) {
        bbutil_terminate();
        return EXIT_FAILURE;
    }
Run Code Online (Sandbox Code Playgroud)

(这不是文件中的所有代码,而是重要的一点)

如果给定的属性列表不受支持,这基本上是怪胎。上级文件 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};
Run Code Online (Sandbox Code Playgroud)

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

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};
Run Code Online (Sandbox Code Playgroud)

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