Non-Photorealism Rendering

* Interaction (except for what have been supplied by the skeleton code)
    -  't' and 'T': Toggle texture
    -  '+' / '-' : Change the silhouette line width
    -  Mouse left key drag : Move the point light around the object

* Silhouette

    I didn't actually detect the silhouette by myself but made OpenGL did it for me... Greg said it's hard to draw open shapes this way, but I don't quite understand. If there are edges that shared by only one triangle, then it's not a silhouette edge by definition. Otherwise, for every edge that shared by 2 triangles, we can test the dot products. Simply render the scene twice, one with front faces filled and another with front faces culled and depth buffer on. Other people also do it by pulling the back faces a bit backward (towards the camera) for better silhouette.
    I did search a lot on how to fast detect silhouette edges. The most common and quite efficient way is to randomly grab a bunch of edges as seeds, and search each neighbor until a silhouette edge is found. Once an edge is found, it's easy to trace this silhouette line. The drawback of this method is, it cannot guarantee to find all the silhouette edges. However, it works very well most of the time because we don't even need the whole silhouette in a non-photorealistic image. For each following frame, we can use the silhouette of the previous frame as the start point because of the frame coherence. 
    Nonetheless, I don't think this algorithm is very effective. Given a very huge set of polygons, it would still be a lot of work to find the silhouette edges one by one. Coherence between frames is not always so helpful. (And I don't think the implementation is simple :p) On the other hand, I really don't want to do brute force, check every edges in every frame. (It's not hard but kind of silly...) Since OpenGL can do that nicely and effectively, why not just use?
    One drawback is the lines may not be connective in the joint points, especially when the lines are thick. The pull-backward method I mentioned above can solve this problem and yield identical line width. And of course, I lost flexibility in controlling the silhouette by leaving it to OpenGL.

* Cel-Shading

    I referred to Cel-Shading (by Sami "MENTAL" Hamlaoui)@ GameDev.net for this part.
    The idea is quite simple: assign 3 colors to represent bright, light and dark respectively. I didn't directly use the 1D texture as the article suggests (I tried, but it didn't work...). Instead, I have an array as look up table for those 3 colors, and use the intensity (which is (I/ Distance^2) * (N·L) ) as the index.
    There are problems with this simple algorithm. First, I didn't do ray casting so I cannot handle the shadow. (See the teapot above, right side should not be lit by should be in shadow.) Second, there are serious aliasing with per vertex shading. The border between two colors is zigzag but not smooth. (It looks fine with the teapot but worse with things like a sphere. I would love to do per pixel shading, but give me a video card first please...) 

* Texture

    I was planed to use mipmap (which seems to be suggested by the skeleton code?) but not being success. Now I simply bind the proper texture for every triangle. Still, it doesn't look every pleasing, with some distortion in *thin* triangles and noticeable discrepancy between different textures. Part of the problem may be the texture itself and part of it may be the texture mapping scheme, which is EYE_PLANE in this case.