简体   繁体   中英

OpenGL Ubuntu Depth

I'm writing a simple OpenGL program on Ubuntu which draws two square (one in front of the other) using vertex array. For some reason, the GL_DEPTH_TEST does not seem to work. The object in the back appear in front of the one in the front. Depth buffer is enabled by

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);

GL_DEPTH_TEST is enabled by

glEnable(GL_DEPTH_TEST);

and depth buffer is cleared before drawing by

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

The complete code is shown below:

#define BUFFER_OFFSET( offset )   ((GLvoid*) (offset))

#define NUM_VERTICES 8

vec4 vertices[8] =
{{0.0, 0.0, -0.25, 1.0},    // front
 {0.0, 0.5, -0.25, 1.0},
 {0.5, 0.5, -0.25, 1.0},
 {0.5, 0.0, -0.25, 1.0}, 
 {0.25, 0.25, -0.75, 1.0},  // back
 {0.25, 0.75, -0.75, 1.0},
 {0.75, 0.75, -0.75, 1.0},
 {0.75, 0.25, -0.75, 1.0}};

vec4 vertex_colors[8] =
{{1.0, 0.0, 0.0, 1.0},  // red
 {1.0, 0.0, 0.0, 1.0},
 {1.0, 0.0, 0.0, 1.0},
 {1.0, 0.0, 0.0, 1.0},
 {0.0, 1.0, 0.0, 1.0},  // green
 {0.0, 1.0, 0.0, 1.0},
 {0.0, 1.0, 0.0, 1.0},
 {0.0, 1.0, 0.0, 1.0}};

void init(void)
{
    GLuint program = initShader("vshader_td.glsl", "fshader_td.glsl");
    glUseProgram(program);

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(vertex_colors), NULL, GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
    glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(vertex_colors), vertex_colors);

    GLuint vPosition = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray(vPosition);
    glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

    GLuint vColor = glGetAttribLocation(program, "vColor");
    glEnableVertexAttribArray(vColor);
    glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points)));

    glEnable(GL_DEPTH_TEST);
    glClearColor(1.0, 1.0, 1.0, 1.0);
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDrawArrays(GL_QUADS, 0, NUM_VERTICES);
    glutSwapBuffers();
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(512, 512);
    glutCreateWindow("Test Depth");
    glewInit();
    init();
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

The vertex shader is shown below: #version 130

in vec4 vPosition;
in vec4 vColor;
out vec4 color;

void main()
{
    color = vColor;
    gl_Position = vPosition;
}

and the fragment shader is shown below: #version 130

in vec4 color;
out vec4 fColor;

void main()
{
    fColor = color;
}

Why object in the front is blocked by the object in the back?

In the vertex shader, you do

 in vec4 vPosition; [....] gl_Position = vPosition; 

without applying any transformations. Since gl_Position is the clip space position of the vertex, this means that your vertex coordinates are interpreted as being specified in clip space.

And your vertex coordinates

 vec4 vertices[8] = {{0.0, 0.0, -0.25, 1.0}, // front [...] {0.25, 0.25, -0.75, 1.0}, // back 

just imply that the points you marked as "front" lie behind the ones you marked as "back".

I don't know how you came to the assumption that it should be the other way round, I can only guess that you confused this with classical, left-handed OpenGL eye space convention where the "camera: looks into -z direction - but that is totally irrelevant here, since you never established an eye space at all, and draw directly in clip space.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM