Renderer System
DirectX 11 Renderer (Bindful/Slot-based Rendering)
DirectX 12 Renderer (Bindless Rendering with HLSL Dynamic Resources)
DX Shader Compiler
Bitmap font
Sprite sheet and sprite animation
Debug Render help functions
Asset Loading System
Images (stb_image)
XML (TinyXML2)
OBJ Loader
Network System using Winsock2
Hierarchical Scalable Clock System
Input System (keyboard, mouse and xbox controller)
Audio System using FMOD
Event System
Dev Console
Dear ImGui
2D Physics
Math
EulerAngles, Matrix, Quaternion
Geometric Primitives
Spline 2D/3D
Raycast 2D/3D
ChessDX - Chess Game with DirectX 12 Rendering, and Networked Multiplayer
Doomenstein - Doom-like 3D FPS game with data-driven actors, weapons, and maps
Libra - Top-down 2D tank game
Starship - Top-down 2D space shooter game
Visualizes and verifies C++ engine math functions through interactive test scenes.
Test experimental shaders and validate the renderer system
In traditional DirectX 12, root signatures specify how shader-visible resources are bound to the pipeline. Typically, you either create a generic root signature or maintain multiple root signatures for different rendering scenarios, possibly using HLSL root signature reflection or macros (as Unity does) to manage complexity.
However, for a small engine, I found the bindless resource approach (especially with Shader Model 6.6’s ResourceDescriptorHeap and SamplerDescriptorHeap ) to be a much cleaner solution which allows you to have a fast iteration. With bindless, you only need a single, simple root signature (e.g., with 64 unsigned ints), and shaders can access resources via indices.
I implemented a DirectX 12 bindless rendering system that uses index-based resource access through centralized descriptor heap management. My DX12DescriptorHeap class handles both persistent and temporary descriptor allocations, with automatic recycling for temporary descriptors each frame and user-controlled lifecycles for persistent ones. The engine also handles different types of view allocation (SRV, UAV, RTV, DSV, CBV) and returns a lightweight DescriptorHandle struct.
These design choices free developers from root signature constraints and reduce the need for constant rendering system modifications, boosting iteration speed and flexibility. Though requiring DirectX expertise for direct use, the system serves as a robust foundation for implementing advanced pipelines, enabling rapid development of sophisticated rendering architectures without traditional binding limitations.
Here’s a sample code snippet: