Client Render Systems - Kyoril/mmo GitHub Wiki

Introduction

There are different render systems in the client. In this page I want to describe which ones exist, and why they exist at all. Let's get started.

The EventLoop

The event loop is what drives the game currently. It has a Paint signal, which you can subscribe to. Subscribing to it will trigger a function every time a frame is drawn. This is the most low level system where you can issue render calls, although it is not recommended to use this unless you really know what you do and you really need that much control on low level stuff.

Screen Layers

The screen layer system subscribes to the event loops events and is driven by it. What this system does is basically manage "layers" on the screen, where each layer is updated once per frame and has a call to some Render method once per frame. Layers have priorities which control the order of rendering.

This system exists to do the most basic, generic renderings. You have to issue render calls against the graphics api yourself here, and rendering is very low level.

Existing layers so far are (in the following order):

  • The game state manager
  • The game console
  • The loading screen

FrameUI

FrameUI is the ingame UI library for this game, written entirely from scratch. It uses many libraries to do what it needs to do, such as the graphics library for issueing render commands and such.

FrameUI does not require you to send custom render commands. All UI frames are organized and rendered if needed based on the frame's states. Frame components describe how a frame should be rendered. To render the whole frame ui, just call the FrameManager's render method whenever you think the whole UI should be rendered.

Currently, FrameUI is rendered in the game states.

You can write custom frame renderers, which can render anything you like into a texture which is then displayed as a UI texture with dynamic content (render to texture). This is how the game world is rendered in the game right now (WorldFrame & WorldFrameRenderer).

SceneGraph

Managing complex 3D Scenes is quite a challenging tasks. To simplify management of 3d scenes, the scene graph library was built. It has a scene object, which has a root scene node. You can attach scene nodes to the root scene node, apply transformations to these scene nodes and ultimately attach movable objects to scene nodes.

A movable object's job is to add renderable to a render queue if it is asked to do so. It can choose which ones to add. This allows for culling and stuff like that to be implemented.

Object rendering is managed through renderables. Order of render operations are managed by a render queue. Everything is managed automatically. All you need to do to render the scene graph is call the Scene::Render(camera) method and provide the camera (which is also created and managed by the Scene object) to tell the graph where the viewer is located at.

Currently, the scene graph is rendered by a custom FrameUI renderer called the WorldRenderer. So the whole scene is rendered into a texture and then displayed as a UI element which is full screen. But this also technically allows to resize the world frame to only take up a specific area of the screen or hide it completely.