Skip to content

Latest commit

 

History

History
104 lines (70 loc) · 3.35 KB

File metadata and controls

104 lines (70 loc) · 3.35 KB

Architecture

Libraries used

Assimp Used for reading 3D models
Dear ImGui Used for 2D GUI
GLAD Used for loading OpenGL extensions
GLFW Used for OpenGL initialization and management
GLM Used for linear algebra math
GoogleTest Used for unit testing
OpenGL Used for 3D rendering
STB Used for reading image files

Wireframe rendering

Various wireframe rendering techniques exist, each more/less different; efficient; modern than others.

The current architecture allows devs to implement their own model loader via the ModelLoaderImpl interface, in which they choose how each mesh's triangles layout is made (triangles, strips, fans). This would have potentially required different ways of handling that in shaders. For simplicity, the traditional global polygon mode (glPolygonMode) is used.

Tick-based updates

The main loop frame rate is capped at the primary monitor's refresh rate. For example, if your primary monitor's refresh rate is 144 Hz, the main loop will run approximately 144 ticks in 1 second. However, because frame rate can still fluctuate, a fixed timestep with an accumulator is also used when computing camera movement, model transform and animation to ensure a fixed number of ticks per second. This timer's frequency is also set to the primary monitor's refresh rate.

Fixed-size circular queue

A fixed-size circular queue was developed for the dev messages system. It is implemented similarly to what's explained here. This data structure was needed for efficiently adding and popping messages to the dev messages queue in O(1).

Interfaces

ModelLoaderImpl

The interface to use for all model loaders. It has 2 methods:

  • LoadModel
  • LoadAnimation

LoadModel

virtual bool LoadModel(
  const std::string& file_path, 
  const ProgramBindings& program_bindings, 
  TextureStore& texture_store,
  Model& out_model
) = 0;

Parameters:

Parameter Description
file_path The model's file path
program_bindings The OpenGL program bindings singleton
texture_store The texture store singleton
out_model The output model

Return value:

  • true if the model was successfully loaded
  • false otherwise

LoadAnimation

virtual bool LoadAnimation(
  const std::string& original_model_file_path,
  size_t animation_index,
  Animation& out_animation
) 

Parameters:

Parameter Description
original_model_file_path The original model's file path
animation_index Zero-based index of the animation. 0 = first animation, 1 = second animation, etc.
out_animation The output animation

Return value:

  • true if the animation was successfully loaded
  • false otherwise
  • Default: false

Implementations

AssimpModelLoaderImpl

Implements ModelLoaderImpl. Uses Assimp to read a model file and creates each mesh, texture and animation.

Note: For embedded textures, it currently always assumes each texture's pixel format is GL_BGRA and sets the OpenGL internal format to GL_RGBA8.

Note: It currently only supports linear interpolation when reading animations.

MyModelLoaderImpl

Implements ModelLoaderImpl. Builds a 3D cube made of 6 meshes (1 mesh per face), each with 3 skins. No skeletal animations.