Ion Core Game and Render Engine Documentation

Comments are questions? Discord

Application



The Application class manages all Resources, ServiceLocator, Windows and Scenes.
The main game loop is also run by this class but does nothing more than handling Windows messages. The parts of the traditional game loop are run in independent threads handled by the scene class.

ResourceManager


The ResourceManager holds all resources and makes sure you don't load a resource twice in memory. It also keeps a counter on the usage.
I'm thinking on adding a ResourceManager to a Scene instance (now it's only per Application) and maybe also per Cube, so if you remove a scene/cube all of it's resources are removed as well.

Scene



Multiple Scenes can run at the same time.
Scene holds all SceneThreads. They are the gameloop contents and run "independent" and timing can be set per SceneThread.
As the different SceneThreads are working on the same data, mutexes are used to protect data (from inconsistent read/write). More details on that later
A scene has all the objects:

Object (or ComponentManager)



Objects belong to a scene and are just a container of components. They can have parent/child objects but this should be avoided if possible as it will impact performance.
There is a split in the traditional component model (Model, View, Controller), because they are accessed separately in the SceneThreads.
A direct link to TransformMC is kept for performance reasons (I might be guilty against the "Premature optimization is the root of all evil" rule).
The full hierarchical model of Components:

Component hierarchy



Try not to get confused on ModelC and MeshModelVC, the first one refers to Model in the Model-View-Controller design pattern, the second one is a 3d model/mesh.
Another design pattern here is in ReceiverMC, the Command pattern.

Cubes



"Cubes" are a first and important optimization towards large Scenes, or even OpenWorld games.
The different Component types have different Cube properties (xyz size of cube, inactive distance, lod, ...)
Examples:
Render is only for ViewC Cubes in front of the Camera and the distance from the Camera to the Cube is passed to the Render function to be used as LOD.
For ModelC and ControllerC there can be multiple Camera's, which is taken into account and Update() is only called if for Cube Components within a certain distance from the Camera's
As there normally are very few objects moving in a Game, I chose for the std::vector container to store the pointer to the Components in the Cube and if an Object moves out of a cube the mHasMoved is set in the old one.
The list of Cubes is actually a std::multimap container. For the moment this is fast enough. A graph could be used but has it's disadvantages as well.

Command

Gameloop Threads

ControllerST



ControllerST holds all input & AI. Input needs to be registered and works with Command pattern.
The Inner loop gets keyboard input (mouse & gamepad will be added in the near future), then goes over all the Scene Objects, which in turn calls update() on all it's Controller Components.
It holds a share lock on all Scene Objects while doing this. Other threads do the same, so they can all run at the same time. The only exception is the ModelST, which takes an exclusive lock during Switch() on Model Components. More on that later.

ModelST




ModelST updates your object's data (like TransformMC, which holds position and rotation).
The inner loop goes over all the Scene Objects, which in turn calls Update() on all it's Model Components.
It holds a share lock on all Scene Objects while doing this.
Then it goes over all objects again and calls Switch(), which switches the buffer of the ModelC (More on double buffering later). For this it holds an exclusive lock on all objects.

ViewST



The ViewST inner loop works somewhat different.
It first does an Update() on all ViewC's belonging to a Canvas/Material (Rendered Cubes only)
For the actual Rendering, it calls the Scene Render().
The Scene Render() sends a signal using a condition variable to the Canvas to start Rendering. So multiple Canvases render simultaneously.
The Canvas Render Thread goes over all Materials. The material has a list of ViewCCubes. Only the Cubes in front of the Camera are being Rendered (ViewC's Render() function)

The rendering could be reworked to a render thread pool which processes these Cubes.

If a component needs information from another component of the same object, the component has a reference to the object and can thus ask for that information.
mpObject->GetModelC<TransformMC>()->GetWorld()

ServiceLocator



Audio is not implemented in the engine because of license restrictions. There's an example though in the Test project.
StatsWriter is still work in progress.


More coming soon on materials and shaders, physics, ...