The source code of the 15th tutorial of the C++ 3D Game Tutorial Series is now available in early access on GitHub!
This tutorial represents a significant architectural and functional leap for the engine. It introduces a dynamic camera pipeline, and replaces the placeholder demo with a working player prototype. Here’s a walkthrough of what actually shifted under the hood:
The old hard-coded orthographic setup has been
replaced. A brand-new CameraComponent now calculates view and perspective matrices on the fly, factoring in
field of view, near/far clipping planes, and viewport dimensions. These matrices are pushed through to
Basic.hlsl, where the vertex shader now properly applies the view transform to position coordinates. To make
perspective work correctly, the SwapChain and DeviceContext were also updated to initialize and clear a proper
depth-stencil buffer, giving you actual 3D depth testing.
Mat4x4 now includes perspectiveFovLH, matrix inversion, determinant
calculation, and row/column extraction. Vec4 gained a cross product helper, and a MathUtils header was
introduced for shared constants like PI. Simultaneously, TransformComponent was refactored to output two
distinct world matrices: getRigidWorldMatrix() (rotation + translation only) and getAffineWorldMatrix()
(includes scale). It also now provides directional vectors (forward(), right(), up()) extracted directly from
the camera's orientation, which is a much cleaner way to handle movement and rotation logic.
This tutorial introduces a GameContext struct that neatly bundles critical references
like the InputSystem. This context is now passed cleanly from Game → World → GameObject, meaning any component
(like the new camera) can instantly query input or game state without relying on globals or tight coupling. The
World and GameObject classes were updated to respect and forward this context.
The old MyObject placeholder has been completely pruned. In its place, a Player class now handles
both camera rotation and WASD movement. It uses the newly added forward()/right() transforms to move relative to
camera orientation, clamps pitch to prevent gimbal lock, and mounts the CameraComponent with a scaled transform.
The scene itself was also fleshed out: a flat ground plane and a randomly generated 5×5 grid of cubes with
varying heights were added, giving you a tangible playground to test the new perspective camera.
In short, this tutorial essentially upgrades the project to a functional 3D prototype. The engine now has dynamic camera, proper depth testing, a cleaner context-passing architecture, and a player controller that demonstrates how all these pieces interact in practice.
You can find the full source code on GitHub here: GitHub Link
I hope you enjoy the tutorial, and thank you for all your support!