This project was a rather large undertaking to build a basic 3D renderer from essentially nothing. SDL2 is used for windowing, but the rendering pipeline is built completely by hand. Frames are written to a buffer which are then passed to SDL2 for display.
Source: https://github.com/CurtisBuckoll/CGL
Project Overview
The scene configuration is first read from a file which specifies the transformations of models to be placed into the scene in world space. The models themselves are stored in .obj files and are loaded while parsing the scene configuration file, which also contains lighting and initial camera position/view information. There are three shading styles which can be specified in this file, consisting of flat, Gouraud, and Phong,
Following the coordinate transform from object to world to camera, we perform clipping and culling of the polygon primitives for each model based on the camera view. For the polygons that intersect with the clipping planes, we triangulate these polygons at the clipping plane and construct new triangular primitives existing only within the render bounds. Since perspective projection has not yet been performed, we clip to the 3D frustum defined by the field of view. Back face culling is also performed for the non-counterclockwise wound polygons which we expect to be facing away.
Now with the refined list of primitives to draw, we iterate through each primitive and draw it to the screen, performing the lighting calculation based on the lighting model specified. Depth shading was also implemented to darken objects which fall far into the background. Although not shown in the demonstrations, basic texture mapping was also implemented to give our models a more interesting appearance beyond flat colour.
The first depiction demonstrates interaction with a simple scene illuminated by Gouraud shading. The second depicts the same scene in wireframe mode, and shows how the primitives are triangulated as they are clipped to the 3D viewing frustum before perspective projection.