OVERVIEW
The Game Engine was prototyped in Visual Studio using C++. The Game Engine was constructed in phases over a course of a year in a series of courses at DePaul University; and uses a set of custom libraries and a conversion tool. The engine was further extended to allow for features such as multiple font support and basic scenes.
Highlights
PHASE 1: Libraries and OpenGL
The custom libraries were built to encapsulate core functionality for the engine. The libraries handle the file, math, resource organization and management. A sample demo from the OpenGL Superbible was used as the basis for integrating the OpenGL API into the game engine. Programmatic primitives were used to test perspective cameras, textures, graphics shaders (wireframe, texture, or Gourand), and mesh object transformations.
The custom libraries were built to encapsulate core functionality for the engine. The libraries handle the file, math, resource organization and management. A sample demo from the OpenGL Superbible was used as the basis for integrating the OpenGL API into the game engine. Programmatic primitives were used to test perspective cameras, textures, graphics shaders (wireframe, texture, or Gourand), and mesh object transformations.
PHASE 2: Data Serialization and Animation
A convertor tool was created to standardize any data passed to the engine. The tool parsed existing textures and glTF files, and serialized it as a runtime format(.azul) using Google Protocol Buffers. The engine was extended to use Google Protocol Buffers to deserialize the runtime file and create a rigid representation of the 3D model.
The convertor tool was then updated to parse animation data from glTF files. The engine organized the animation data as a series of clips. Each clip had a set of keyframes that held transformation data for each skeletal joint in that frame. Animation updates interpolated the joints and transformed the joints from local to world per frame. A lot of calculations were happening on the CPU and frame rate drops were noticeable in debug with multiple animations playing.
A convertor tool was created to standardize any data passed to the engine. The tool parsed existing textures and glTF files, and serialized it as a runtime format(.azul) using Google Protocol Buffers. The engine was extended to use Google Protocol Buffers to deserialize the runtime file and create a rigid representation of the 3D model.
The convertor tool was then updated to parse animation data from glTF files. The engine organized the animation data as a series of clips. Each clip had a set of keyframes that held transformation data for each skeletal joint in that frame. Animation updates interpolated the joints and transformed the joints from local to world per frame. A lot of calculations were happening on the CPU and frame rate drops were noticeable in debug with multiple animations playing.
PHASE 3: 2D System and Skinned Animation
The engine was updated to support 2D orthographic cameras, sprites, and handle multiple fonts. Sprites could also be animated through a series of timed image changes. Animation system was also updated to support vertex skinning and simplistic clip blending. Skinning for 3D Animations is the process of binding the vertices of a 3D mesh to the skeletal joints of a model; so every time the skeleton shifts, the mesh will also shift accordingly.
With the introduction of skinning, the engine was going to deal with increasingly higher poly models. All the animation data being processed by the CPU needed to be offloaded to the GPU. Compute shaders and Shader Storage Buffer Objects (SSBOs) were introduced to the engine. An interface was added to load in compute shaders, dispatch them, as well as supporting read and writes from buffers. SSBOs were used to upload data to use in compute calculations, store the result, and pass them directly into vertex shader. The vertex shader would calculate the skin matrices by applying the joint weights.
The engine was updated to support 2D orthographic cameras, sprites, and handle multiple fonts. Sprites could also be animated through a series of timed image changes. Animation system was also updated to support vertex skinning and simplistic clip blending. Skinning for 3D Animations is the process of binding the vertices of a 3D mesh to the skeletal joints of a model; so every time the skeleton shifts, the mesh will also shift accordingly.
With the introduction of skinning, the engine was going to deal with increasingly higher poly models. All the animation data being processed by the CPU needed to be offloaded to the GPU. Compute shaders and Shader Storage Buffer Objects (SSBOs) were introduced to the engine. An interface was added to load in compute shaders, dispatch them, as well as supporting read and writes from buffers. SSBOs were used to upload data to use in compute calculations, store the result, and pass them directly into vertex shader. The vertex shader would calculate the skin matrices by applying the joint weights.
Post-Mortem
If I were to continue this project, there are a few things I would expand on:
• Adding cube maps
• Scene support expansion
• Add a graphical interface library (i.e. IMGUI) for usability
Particularly, I would really like to further explore the OpenGL rendering and include more advanced lighting features; such as bump or normal mapping for more realistic lighting on 3D models. Also allow for multi-pass rendering for shadows.
• Adding cube maps
• Scene support expansion
• Add a graphical interface library (i.e. IMGUI) for usability
Particularly, I would really like to further explore the OpenGL rendering and include more advanced lighting features; such as bump or normal mapping for more realistic lighting on 3D models. Also allow for multi-pass rendering for shadows.
Documentation