A framework is written in 8 weeks (C++), this framework can be used to create tower defense games. It has been written in DirectX12 and I was responsible for graphics programming and the engine architecture. The biggest tasks I had during this project are listed below.

- IMGUI implementation & implementation single draw call debug renderer.

- Implementation of the model loader (using Assimp).

- core architecture (scene support, data management, system interaction).

- World space selection (cursor to world position).

- Shadow mapping.

- input handling

- Scalable UI with alignment & clickable buttons with callbacks per state.

- Particle system that supports laser and projectile particles.

Since I had quite a lot of responsibilities, a limited amount of time to develop this framework and no prior experience with DirectX12, I decided to start with [this] basic renderer that has features like basic lighting and GPU resource management and mipmapping set up.

Core architecture

When designing the core architecture I wanted it to become modular and easy to maintain. I also wanted encapsulation between modules (systems) that are not supposed to access each other. This resulted in the following hierarchical design that only allowed a system to access it's root system.

Root systems, child systems and leaf systems can be added as shown above, when a new module or system is created it needs to inherit from either the CoreSystem or the GameSystem depending on if it is going to have child systems. The OnItemAdded and OnItemRemoved functions are guaranteed to be of the type defined in the template brackets of the function call so the static cast is safe to use in this case.

Notes after having used this system.


- The codebase remained quite clean when used properly.

- It required a very small amount of code to create new systems.

- The fact that everything was modular gave a lot of control.


- Mistakes were harder to track because of templates.

- Inheritance tree could get quite deep.

Shadow mapping

Shadow mapping required an additional pass where the scene is rendered from the perspective of the light source. I will then be using the depth buffer from that pass to sample from when rendering the geometry from the perspective of the camera. The depth stencil view requires a different format than the shader resource view so therefore I needed to make it into a weakly typed resource. I didn't need the stencil buffer so I went for an R32 format. In the image above I used a shadow map with a resolution of 3840 x 2160, rendered using a orthographic projection matrix.