본문 바로가기

OpenGL

Wireframe rendering with hidden line removal

Source: 1. Advanced graphics programming using OpenGL (Morgan Kaufmann)            
            2. OpenGL porgramming guide (Addison-Wesley Professional)

We assume that triangle mesh is rendered and then, we can draw the corresponding wireframe objects with their hidden lines removed as follows.

1. Disable writing to the color buffer with glColorMask.
2. Set the depth function to GL_LEQUAL.
3. Enable depth testing with glEnable(GL_DEPTH_TEST).
4. Render the object as triangles.
5. Enable writing to the color buffer.
6. Render the object as edges using such as GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP, or method using glBegin(GL_POLYGON) and glPolygonMode(GL_FRONT_AND_BACK, GL_LINE).

The above algorithm works for the almost cases. However, depth rasterization artifacts from quantization errors may happen since the pixels at the edges of triangles rendered as polygon and the pixels from the edges rendered as line have depth values that are numerically close. To handel this problem, we may use the glPolygonOffset command which move the lines and polygons relative to each other.

- glEnable(GL_POLYGON_OFFSET_LINE): to offset the lines in front of the polygons
- glEnable(GL_POLYGON_OFFSET_FILL): to move polygon surfaces behind the lines

Example code fragments using glEnable(GL_POLYGON_OFFSET_FILL) are as follows.

 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
 glDepthFunc(GL_LEQUAL);
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_POLYGON_OFFSET_FILL);
 glPolygonOffset(1.0, 1.0);
// Draw triangles
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
// Draw edges

Otherwise, we may accomplish the same effect by drawing line segments for edges and drawing filled triangles as follows.

glDisable(GL_LIGHTING);
glEnable (GL_DEPTH_TEST);
glPolygonMode(GL_FRONT, GL_LINE); 
glColor3f(FOREGROUND_COLOR);

// Draw triangle edges
glLineWidth(PRE_DEFINED_LINE_WIDTH);
glBegin(GL_LINES);
// ...
glEnd();
////////////////////////

glPolygonMode(GL_FRONT, GL_FILL);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0);
glColor3f(BACKGROUND_COLOR);

// Draw filled triangles
glBegin(GL_TRIANGLES);
// ...
glEnd();
////////////////////////
glDisable(GL_POLYGON_OFFSET_FILL);