openglrenderingrasterizingdepth-testing

In OpenGL, is it possible to draw the edges of the unoccluded triangles only?


I have a mesh to render with OpenGL. What I want is to render its edges, but only the ones of the un-occluded faces. However, I realize that this is not possible with only:

glEnable(GL_DEPTH_TEST);    // Enable depth test
glDepthFunc(GL_LEQUAL);     // Accept fragment if it closer to the camera than the former one
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

since there is no depth information in-between the edges, so the edges of the occluded triangles are still rendered.

A work around is to draw the triangles with GL_FILL first in background color (in my case, white), and then draw the edges separately. But doing so results in artifacts similar to the z-fighting phenomenon, i.e., some edges seem thinner than others or even vanish, as shown below

enter image description here

On the left is what I have, and on the right is what I desire (viewed in MeshLab). Since depth test of triangles seems to be unavoidable in this case, I guess I am also asking:

How can I draw edges over triangles without the z-fighting artifacts?

Note that face culling is not useful, as it only eliminates faces facing backward, but cannot deal with occlusion.


Solution

  • Set a polygon offset for the first pass with glPolygonOffset:

    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(1, 1);
    

    Disable the polygon offset for the 2nd pass:

    glDisable(GL_POLYGON_OFFSET_FILL);
    

    Polygon fill offset manipulates the depth of a fragment by a minimum amount. This results in the depth of the fragments in the first pass being a small amount greater than the depth of the same fragments in the second pass. This is how you get rid of the deep conflict.