February 2026
githubA fun and easy feel good project, although my choice to use Vulkan added a bit of complexity.
Where most students use OpenGL for this project, I chose Vulkan — deliberately, to understand what a graphics API actually requires from the programmer rather than what it chooses to hide. The result is a viewer that loads OBJ files, applies PNG/JPEG textures, and allows full keyboard-controlled object manipulation across all three axes, with continuous Y-axis rotation.
The renderer is structured around explicit Vulkan objects - instance, physical/logical device selection, swapchain, render pass, graphics pipeline, descriptor sets, command buffers, synchronization primitives - each isolated in its own module. GPU memory management is manual: vertex and index data are uploaded through staging buffers into device-local memory.
The most significant debugging effort went into frame synchronization. Vulkan requires tracking two distincts counts: frames in flight (how many frames the CPU can prepare ahead of the GPU) and swapchain images (how many presentation buffers exist). Conflating them produces validation errors or race conditions that are difficult to trace. Getting the semaphore end fence coordination right across those two dimansions was the sharpest learning curve of the project.
OBJ parsing handles concave faces through ear clipping - projecting each polygon onto a 2D plane, testing ear candidates with cross-product convexity checks, and falling back to fan triangulation on degenerate geometry. Missing UVs are generated via planar projection from faces normals.
The math library (vectors, matrices, transforms, perspective projection, complex number support) is the one written for the Matrix project, reused directly.
The famous Utah teapot.

The subject demanded that “the texture should be something cheerful - like ponies, kittens, or unicorns”. Made with AI.

A beautiful cottage model.