Core OpenEngine Architecture

This page describes the core components of a OpenEngine game. More detailed information may be found in the [browser:/ source code] and documentation hereof.

Table of contents

Interfaces

Most of the structures in OpenEngine are defined in terms of an interface. The interface is a signature of their usage and allows clients to make use of their services without knowledge of the concrete implementation.

Below is a brief description of the most central interfaces and how to use them.

The Game Engine

At the heart of the system is the implementation of the game engine interface.

The interface is an instance of the singleton pattern. And through the interface the concrete implementation can be retrieved for use in other places of the program. The interface allows us to implement different strategies for the "main engine loop".

Our game engine implementation is a single threaded engine containing the code to initialize the engine, run the main loop until notified of shutdown and finally code to shutdown properly.

The engine is basically just a container for other modules that contain the engines functionality.

Modules

The engine modules are described by the module interface Each module consists of three main methods.

Initialize
Run once at the engine start fase. Used to handle different tasks such as prepossessing of data structures.
Process
Run once for every module on every loop. That is, the process method is called on every module in turn. When all modules have had their method called it starts over. The argument is the time of the last engine loop in milliseconds.
Deinitialize
Deinitialize is called once for every module as part of the engine shutdown fase. It should safely cleanup after its self.

Last a fourth method must be implemented in order to correctly find the module in the engine.

Modules are added, removed and found by use of the game engine interface:

  #!cpp
  // create some modules
  Module1* m1 = new Module1();
  Module2* m2 = new Module2();

  // get the engine instance
  IGameEngine& engine = IGameEngine::Instance();

  // add some modules
  engine.Add(*m1);
  engine.Add(*m2);

  // look up a module
  Module2* m3 = dynamic_cast<Module2*>(engine.Lookup(typeid(Module2)));

  // m3 is now a pointer to the same object as m2.

The following are some mandatory modules. If one of them is not supplied the engine will refuse to run.

Frame

Our implementation of the game engine requires a frame on which it may draw. The frame interface defines its functionality.

Renderers

The most central task of a 3d game engine is to render. The renderer interface defines this central module. The renderer is a more complex object and uses other objects in performing its task.

Scene

The scene is a tree structure that represents, among other things, geometry and transformations. The renderer module requires a scene root node fulfilling the scene node interface in order to perform its task.

Views

renderering views are the structures that traverse the scene tree performing rendering tasks on each node as it is encountered.

Game factory

The final component that binds all of this together is the game factory. A game factory must be supplied to the start method of the game engine. It is then responsible for returning valid instances of the frame and renderer. Last it has a setup method allowing it to perform custom tasks on the engine prior to the engines start (or initialization) phase. This could consist of adding a module to capture keyboard and mouse input.

A minimal game factory would look like this (assuming that all the included files are available):

#include <Core/IGameFactory.h>
#include <Display/SDLFrame.h>
#include <Renderers/OpenGL/Renderer.h>
#include <Renderers/OpenGL/SimpleRenderingView.h>
#include <Scene/SceneNode.h>

using namespace OpenEngine::Core;
using namespace OpenEngine::Display;
using namespace OpenEngine::Renderers::OpenGL;
using namespace OpenEngine::Scene;

class MyGameFactory : public IGameFactory {

  IFrame* GetFrame() { 
    return new SDLFrame(); 
  }

  IRenderer* GetRenderer() {
    IRenderer* renderer = new Renderer(); 
    renderer->SetSceneRoot(new SceneNode());
    renderer->AddRenderingView(new SimpleRenderingView());
    return renderer;
  }

  bool SetupEngine(IGameEngine& engine) {
    return true;
  }

};