Rendering silhouette edges is a classic problem in NPR. It has other uses to - for example, in terrain rendering, it can convey quite a bit about where ridge lines are:
Of course, the above comparison is not very fair. The image on the left is just shaded by height (no lighting) which can hide terrain features, especially for horizon views. Regardless, silhouettes are cool and most graphics developers are familiar with the standard geometry shader approach based on adjacency information (if not see Inking the Cube: Edge Detection with Direct3D 10 or Single Pass GPU Stylized Edges). What I'd like to briefly share with you is a geometry shader approach that does not require adjacency info, which means you won't need one index buffer with adjacency info and another without it!
I should mention that Deron came up with this and I am sharing it so he can keep busy on the book! The idea is simple - use the geometry shader to do a procedural geometry technique called triangle fattening (see Image Precision Silhouette Edges) in screen space. In the first pass, the model is rendered normally with backface culling. In the second pass, it is rendered with front face culling and a geometry shader that transforms the triangle to screen space and expands each edge by a given number of pixels. To eliminate elongated corners, the three input vertices are turned into six as shown here:
The original triangle is gray and the expanded "triangle" is black. The result is a uniform width silhouette. This method is similar to a fixed function algorithm, which renders the second pass in wireframe mode using a wide line. But in OpenGL 3, line widths greater than one were deprecated.
In our method, the geometry shader outputs six vertices for all backfacing triangles. Most of those fragments should get thrown away by early z since the front facing triangles were laid down in the first pass. The geometry shader could output more vertices to reduce the rasterization load but we found this to slow things down quite a bit. Performance is commonly bound by geometry shader output and this algorithm will output a lot more triangles than the standard geometry shader algorithm that only outputs triangles for edges on the silhouette. We think this algorithm is still worth mentioning since it is so easy to integrate into a rendering pipeline, especially if you have the shader source. Here: SilhouetteGS.glsl.