A "back-to-basics" 3D engine written in C that eschews modern GPUs and floating-point math in favor of retro-inspired fixed-point arithmetic and manual rasterization.
This project is a educational deep-dive into how 3D graphics were handled in the 80s and 90s. Instead of relying on OpenGL, DirectX, or Vulkan, this renderer treats the screen as a raw linear array of memory (a framebuffer) and calculates every pixel manually using Fixed-Point Integer Math.
- Performance: Historically, CPUs lacked Floating-Point Units (FPUs). Integer math was the only way to achieve real-time frame rates.
- Determinism: Eliminates rounding errors across different hardware architectures.
- Educational Value: Strips away the "magic" of modern APIs to show the raw geometry and trigonometry beneath the surface.
The engine follows a classic software rendering pipeline:
- Fixed-Point Math: Uses bit-shifting (16.16 format) to simulate decimals without a performance hit.
- LUT (Look-Up Tables): Pre-calculates Sine and Cosine values at startup to avoid expensive runtime trigonometric calls.
- Transformation: Applies matrix rotation and perspective projection to convert 3D model coordinates into 2D screen space.
- Back-Face Culling: Uses cross-product area calculations to skip drawing faces pointing away from the camera.
- Barycentric Rasterization: Fills triangles by testing pixel containment and interpolating Z-depth for proper occlusion (Z-Buffering).
Instead of float, I use int shifted by 16 bits.
The draw_triangle function implements a barycentric coordinate method to ensure sub-pixel accuracy and smooth depth testing.
// Example of the edge function used for point-in-triangle testing
long long w0 = (long long)(v2.x - v1.x) * (y - v1.y) - (long long)(v2.y - v1.y) * (x - v1.x);- A C compiler (GCC/Clang)
- SDL2 library (used only for creating the window and pushing the final pixel buffer to the screen)
You will need the SDL2 development libraries installed on your system.
# Option 1: Using sdl2-config (Recommended for Linux/macOS)
gcc -o renderer fixed3d.c `sdl2-config --cflags --libs` -lmor
# Option 2: Manual linking with optimization (Great for performance)
gcc fixed3d.c -lm -lSDL2 -O2 -o cube- Close Window: Exit the program.
- The cube rotates automatically to demonstrate the real-time transformation and depth buffering.
This project is open-source and intended for educational purposes. Feel free to use it to learn more about the foundations of computer graphics.
