1

I render two triangles: one is a smaller red triangle with negative depth value(z coordinate of the vertex), the other is a bigger triangle with a positive depth value.

float smallVertices[] = {
        //position          color
       -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0, 1.0f,// left
        0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0, 1.0f,// right
        0.0f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0, 1.0f// top
    };

float bigVertices[] = {
        //position          color
        -1.0f, -1.0f, 0.5f, 0.0f, 0.0f, 1.0, 1.0f,// left
         1.0f, -1.0f, 0.5f, 0.0f, 0.0f, 1.0, 1.0f,// right
         0.0f,  1.0f, 0.5f, 0.0f, 0.0f, 1.0, 1.0f// top
    };

//test1
Before rendering the triangles, I enable depth test, then draw the smaller triangle, finally draw the bigger triangle. The rendered result is what I expected.

//test2
Before rendering the triangles, I disable the depth test but enable update the depth buffer(glDepthMask(GL_TRUE)). Then I draw the smaller triangle first, then enable the depth test and set depth compare function to GL_LESS, finally draw the bigger triangle.

I expected to have a red smaller triangle inside a blue bigger triangle. However, the rendering result is just a blue bigger triangle.

I set glDepthMask(GL_TRUE) to make the depth buffer' value updated to the smaller triangle's depth value. Then using the bigger triangle's depth value compared to depth buffer' value. In this way, I thought I can see a red smaller triangle inside a blue bigger triangle.

// render
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glUseProgram(shaderProgram);

glDisable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

// draw our first triangle with negative depth value
glBindVertexArray(smallTriangleVAO);
glDrawArrays(GL_TRIANGLES, 0, 3);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

// draw the other triangle with positive depth value
glBindVertexArray(bigTriangleVAO);
glDrawArrays(GL_TRIANGLES, 0, 3);

Is there something wrong with my codes?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
coulsonwang
  • 161
  • 1
  • 11

1 Answers1

1

When the depth test is disabled, then the depth buffer is not written at all.
If you want to write the depth buffer and every fragment should pass the depth test, then you've to enable the depth test, but you've to change the the depth function to GL_ALWAYS, by default the depth function is GL_LESS.
There is no need of changing the depth mask, because the depth mask by default is enabled. See glDepthFunc, glDepthMask and Depth Test

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE); // superfluous
glDepthFunc(GL_ALWAYS);

// [...]

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Is it correct that `glDisable(GL_DEPTH_TEST)` means all the fragments will "always pass", does it equals to `glEnable(GL_DEPTH_TEST) and glDepthFunc(GL_ALWAYS)`? – coulsonwang Apr 08 '19 at 06:00
  • @coulsonwang Yes and no, the fragments will pass, because there is no depth test, but the different is that nothing is written to the depth buffer. – Rabbid76 Apr 08 '19 at 06:02
  • Depth test is disabled by default. So it is strange that if I only common `glDisable(GL_DEPTH_TEST);`, then rendered result is what I expected, why? – coulsonwang Apr 08 '19 at 06:37
  • @coulsonwang No, it only seems to work. It doesn't work in the 1st frame, but it works in the 2nd frame, because of `glEnable(GL_DEPTH_TEST);` in the middle of the code. OpenGL is a state engine, a state kept until it is changed again, even beyond frames. – Rabbid76 Apr 08 '19 at 06:38
  • Got it. Thank you! – coulsonwang Apr 08 '19 at 06:39