The source code of the 17th tutorial of the C++ 3D Game Tutorial Series is now available in early access on GitHub!
This tutorial primarily focuses on introducing full texture sampling support and refactoring the graphics pipeline to be more flexible and reflection-driven. Rather than hardcoding geometry and shader bindings, the engine now decouples asset data from the renderer and properly tracks resource slots. Here’s how the changes tie together:
• Texture & Sampling Pipeline Added: The engine now supports 2D textures with a dedicated TextureResource class that leverages stb_image to load .jpg and .png files. A corresponding Sampler class handles filter states, and MaterialResource has been expanded to manage a vector of textures. The DeviceContext now exposes setTextures() and setSamplers() methods, allowing the renderer to properly bind these resources before draw calls.
• Pipeline Layout & Shader Modernization: The legacy VertexShaderSignature class was retired and replaced by GraphicsPipelineLayout, which reflects both vertex and pixel shaders to dynamically calculate input layouts and maximum texture/sampler/cbuffer slot counts. This unification updated GraphicsPipelineStateDesc to accept a single layout object instead of separate VS/PS handles. Meanwhile, the HLSL shaders were updated to pass UV coordinates (texcoord) from the vertex to pixel stage, and Basic.hlsl now samples a diffuse texture, multiplying it with the material's base color.
• Geometry & Renderer Decoupling: The hardcoded vertex and index buffers previously living in WorldRenderer have been completely removed. CubeComponent now generates and owns its own geometry (complete with per-face UV mapping) and exposes it via getVertexBuffer()/getIndexBuffer(). During rendering, the system dynamically pulls geometry from components, applies the material’s texture sampler, and submits draw calls, laying the groundwork for a much more modular, asset-driven architecture.
• Project & Demo Polish: On the gameplay side, the demo scene was simplified: instead of randomly scaling cubes, MainGame.cpp now spawns uniformly sized cubes with randomized Y-rotation. Two new texture assets (wood.jpg and floor.jpg) were added to showcase the new material system, with the floor and cubes now displaying the appropriate diffuses.
Overall, this tutorial shifts the engine from a fixed-function demo toward a modern, data-driven rendering setup where geometry, materials, and textures are properly separated and dynamically bound.
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!