A Vulkan rendering engine built while following the Vulkan Tutorial, extensively refactored into a modular engine and extended well beyond the tutorial into original engine work.
The tutorial phase is complete. The engine has moved on to original architecture work in pursuit of a simple solar system demo scene.
src/engine/
core/ — Camera, Input, Scene, SceneObject, Mesh, Transform, OrbitalBody, config
vk/ — Vulkan wrappers: Instance, Device, SwapChain, Pipeline, Renderer, Buffer, Image, Texture
io/ — File reading, OBJ model loading
ui/ — ImGui integration
app/ — Reserved for solar system specific code
shaders/ — HLSL source + compiled SPIR-V
textures/
solar/ — 2K planet texture maps (NASA/public domain)
Member declaration order in Engine determines construction and destruction order. Key constraints:
InputbeforeWindow— input callbacks fire duringglfwDestroyWindow, so Input must outlive WindowInput::init()beforeimguiRenderer.initGlfw()— ImGui chains onto GLFW callbacks set by Inputrenderer.onSceneReady()called afterinitScene()— descriptor sets must be allocated after the scene is populated
Each SceneObject holds a Texture*. Renderer allocates one descriptor set per object per frame
(descriptorSets[objectIndex][frameIndex]), each pointing at the shared UBO and that object's texture.
Engine owns textures in a std::list<Texture> — list nodes never move on insertion, keeping pointers stable.
A picking pass runs every frame before the main pass, rendering each object's index as a uint into an
R32_UINT image. The pixel under the cursor is copied to a host-visible readback buffer and read back
the following frame after the fence. Cursor coordinates are multiplied by contentScale for HiDPI displays.
Orbit camera with smooth exponential interpolation on yaw, pitch, distance, and target. Double-clicking an object locks the camera to follow it. ESC resets to the default view.
| Input | Action |
|---|---|
| Right mouse drag | Orbit camera |
| Scroll | Zoom |
| Double-click object | Follow object |
| ESC | Reset camera |
| SPACE | Pause / resume simulation |
- CMake >= 3.29
- GCC 13+ / Clang 17+ / MSVC 19.34+ (C++20)
- vcpkg with:
vulkan,glfw3,glm,stb,tinyobjloader - Vulkan SDK (validation layers +
dxcfor HLSL -> SPIR-V) - ImGui built from source via
FindImgui.cmake(FetchContent, v1.92.6) — vcpkg with imgui seems to have some issues.
cmake -B build
cmake --build buildThe CMakeLists auto-detects vcpkg via $VCPKG_ROOT, a local vcpkg/ directory, or C:/vcpkg.
- Vertex / index buffers
- Uniform buffers + descriptor sets
- Texture mapping + mipmaps
- Depth buffering
- Model loading (OBJ)
- Multisampling (MSAA)
- Modular architecture
- Orbit camera with smooth interpolation
- Scene graph with per-object transforms
- GPU picking + hover outline
- ImGui UI
- Per-object textures
- Solar system scene (sun + orbiting planets)
- glTF model loading
- Real solar system data (scales, orbital periods, axial tilt)
- Moons (parented orbital bodies)
- Sun glow / bloom
- ECS refactor
- Planet textures from Solar System Scope — CC BY 4.0.
- "Painterly Cottage" by glenatron on Sketchfab (source), licensed under CC BY-NC 4.0. Removed ground (since we only use 1 texture per model for now) and scaled up.
- "Viking Room" by nigelgoh on Sketchfab (source), licensed under CC BY 4.0. Used as the sample model in the official Vulkan Tutorial.