Ant Game


Chase Percy

Ant Game


Chase Percy

C++ | LUA | CMAKE | GITHUB

A Random Assortment of Ideas


Development Team

Matthew Davis
Rhys Mader
Aaron Koenig
Chase Percy

Project Planning and Tools

  • Weekly meetings
  • Kanban Board
  • Git with GitHub for source control
  • Doxygen
  • CI/CD
    • Static Analyzer (CPPCheck)
    • Automated unit tests
    • GitHub Actions


Features developed by me

Terrain

I implemented the terrain using the strategy pattern so that I could switch out the vertex generation method (Triangles, Quads, Patches) and the height map generation methods (Noise, Fault, File) without altering any code in the terrain class or the game states. For this project, I used patches for the vertex generation and loaded the heightmap from a 16-bit raw file. The terrain was textured in the fragment shader, and textures were applied based on the height of the fragment. Steepness-based texturing was also used to apply rock to steep faces and mix flowers into the grass on flat grass surfaces.

Terrain Tessellation

I implemented our terrain tessellation shaders to improve performance when drawing the terrain over long distances. The patch’s distance from the camera determines the number of vertices per patch. Normals are dynamically calculated during the evaluation stage and are created by sampling and averaging the surrounding pixels on the heightmap.

GUI

The GUI was designed around a canvas and element system, allowing the designer to create and place elements on a canvas via a Lua script. It is abstracted from any library, but the library used for this project was ImGui. A factory takes the Lua tables, creates an abstract element object, and applies them to a canvas. These elements are drawn when the canvas is drawn, and their processing, such as clicking a button, is only handled when they are active.

Math Library Abstraction

The math classes were designed using templates and providing functions to be implemented by a math library. This decoupled the library from our engine and allowed us to switch out a library or function without touching any code outside the facade. The library we used for this project was GLM, as it was specifically designed for OpenGL. Below is an image of the facade in use.

Water Shader

The water shader was implemented using a separate fragment shader for the models. The movement effect was created by sampling a DuDv map (An inverted normal map to store directional data) and offsetting it by a movement value multiplied by the delta time since the last frame. The reflection was created by sampling the skybox relative to the camera, and the distortion from the DuDv map was applied to give it the rippling movement effect. This was then mixed with a blue colour to provide its final colour for the fragment.

Lighting

Phong lighting Phong lighting was applied to the models and terrain to create a more immersive environment. Terrain lighting was calculated dynamically based on the normals generated in the tesselation evaluation shader. This allowed the terrain to be lit smoothly and cheaply as the number of vertices was limited by the tesselation control shader. Matt initially implemented the Phong lighting for the models, but I refactored it to use the bi-tangent and tangent of the vertices so that the lighting would update relative to a model’s orientation when it moved. I also implemented normal mapping to give the models much more depth and better lighting by sampling a normal map texture.

Per Vertex

Normal Mapping

Game Logic

The game logic for the game loop was implemented on a game state object and included basic rendering updating (camera, physics, etc.) and input handling. It was responsible for loading the initial game objects from Lua and storing them for use at run time. The game state contained an entity manager responsible for tracking the game objects, providing access to them and calculating which objects should be rendered and at what LOD level. The majority of the logic was implemented through the entity component system ECS attached to the game objects and mainly the player object.