How do you render primitives as wireframes in OpenGL?

Viewed 151147

How do you render primitives as wireframes in OpenGL?

10 Answers
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

to switch on,

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

to go back to normal.

Note that things like texture-mapping and lighting will still be applied to the wireframe lines if they're enabled, which can look weird.

In Modern OpenGL(OpenGL 3.2 and higher), you could use a Geometry Shader for this :

#version 330

layout (triangles) in;
layout (line_strip /*for lines, use "points" for points*/, max_vertices=3) out;

in vec2 texcoords_pass[]; //Texcoords from Vertex Shader
in vec3 normals_pass[]; //Normals from Vertex Shader

out vec3 normals; //Normals for Fragment Shader
out vec2 texcoords; //Texcoords for Fragment Shader

void main(void)
{
    int i;
    for (i = 0; i < gl_in.length(); i++)
    {
        texcoords=texcoords_pass[i]; //Pass through
        normals=normals_pass[i]; //Pass through
        gl_Position = gl_in[i].gl_Position; //Pass through
        EmitVertex();
    }
    EndPrimitive();
}

Notices :

If you are using the fixed pipeline (OpenGL < 3.3) or the compatibility profile you can use

//Turn on wireframe mode
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

//Draw the scene with polygons as lines (wireframe)
renderScene();

//Turn off wireframe mode
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

In this case you can change the line width by calling glLineWidth

Otherwise you need to change the polygon mode inside your draw method (glDrawElements, glDrawArrays, etc) and you may end up with some rough results because your vertex data is for triangles and you are outputting lines. For best results consider using a Geometry shader or creating new data for the wireframe.

Use this function:

void glPolygonMode(GLenum face, GLenum mode);

face: Specifies the polygon faces that mode applies to. Can be GL_FRONT for the front side of the polygon, GL_BACK for the back and GL_FRONT_AND_BACK for both.

mode: Three modes are defined.

  • GL_POINT: Polygon vertices that are marked as the start of a boundary edge are drawn as points.

  • GL_LINE: Boundary edges of the polygon are drawn as line segments. (your target)

  • GL_FILL: The interior of the polygon is filled.

P.S: glPolygonMode controls the interpretation of polygons for rasterization in the graphics pipeline.

For more information look at the OpenGL reference pages in khronos group.

If it's OpenGL ES 2.0 you're dealing with, you can choose one of draw mode constants from

GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, to draw lines,

GL_POINTS (if you need to draw only vertices), or

GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, and GL_TRIANGLES to draw filled triangles

as first argument to your

glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices)

or

glDrawArrays(GLenum mode, GLint first, GLsizei count) calls.

A good and simple way of drawing anti-aliased lines on a non anti-aliased render target is to draw rectangles of 4 pixel width with an 1x4 texture, with alpha channel values of {0.,1.,1.,0.}, and use linear filtering with mip-mapping off. This will make the lines 2 pixels thick, but you can change the texture for different thicknesses. This is faster and easier than barymetric calculations.

Related