It has been a while since the last update (almost nine months!), and a lot has changed in that time! I finished adding support for image-based lighting and reflection probes, then after a short break I came back to the project and decided to shift my goal with it from being to create a tool to learn graphics APIs with to now creating a game with. To that end, I’ve temporarily suspended support for Vulkan and left OpenGL as the primary graphics API being used while I focus on adding support for gameplay systems.
Having a concrete goal to aim for has proven very useful for a number of reasons, the biggest of which being the restrictions a game places on the engine’s features. Any feature that doesn’t directly improve the game is immediately cut. By not making any assumptions about what might be needed in the future, and instead only implementing features which are necessary right now, I ensure that my time is spent directly benefiting the game.
The main features I’ve implemented since the last update include scene serialization, audio playback, text rendering, post-processing, and physics simulation.
To serialize a scene I write all objects, materials, and lights to a JSON file. I first added a JSON parser/writer, and then I added support for saving the various types of objects (simple meshes, physics data, reflection probes, the skybox, …). Recently I added a distinction between a user-saved file and the default scene layout. This way a player can go through the game and save their progress, while at any time being able to “restart” and erase all their progress. I also added support for saving out “prefabs” to individual files, which can be instantiated into scenes without duplicating the shared fields. I also added a translation gizmo which is displayed on top of the currently selected object to make moving objects around the scene easier.
For audio playback I’m using OpenAL. So far I’ve just added bare-bones support with no mixing or fancy controls – just playing, pausing, and stopping sounds and setting volume and pitch.
To load fonts I’m using FreeType, and then generating a signed distance-field font atlas per variant at startup. Signed distance-field fonts are great at drawing text at different sizes without loss of detail, which is why I chose to add support for them. The atlas generation is quite speedy, taking roughly 60 ms per variant in debug builds, so caching the generated texture to a file doesn’t seem like a pressing matter for now, although it may become worthwhile eventually.
Signed distance-field font atlas, utilizing four colour channels (right: combined)
I’ve added handful of post-processing effects thus far including basic contrast, brightness, and saturation control, tone-mapping, gamma-correction, “fast approximate anti-aliasing”, and chromatic aberration. Those effects already give me a lot of control over the final image, but I’ll definitely be adding more effects as time goes on, including a better AA solution, bloom, and screen-space ambient occlusion among others.
Some different looks I’m able to achieve by tweaking contrast, brightness, and saturation
For physics simulation I’m using Bullet. It was quite a simple addition to the project which just required adding some boilerplate initialization and destruction code and a wrapper for rigid bodies.
Besides that I’ve made lots of small changes and additions, including adding gamepad support, basic profiling helpers, and several configuration files which are super helpful for saving user-specific state between sessions.
Going forward I’ll be continuing to focus on implementing and improving gameplay-systems and hopefully getting closer to having a fun game.