2.9.16
Coherent GT
A modern user interface library for games
HelloGT and the sample application framework walkthrough

The HelloGT application provides a starting point and testbed for Coherent GT and utilizes a large portion of the available events and notifications. This helps for quickly exploring Coherent GT features and examining the flow.

HelloGT consists of 3 modules:

  • HelloGT - main application.
  • CoherentApplication - cross platform library for providing a game loop, input event system and various other utilities.
  • CoherentSampleCommon - initialization, management and destruction for the Coherent GT SDK. This is where most of the heavy lifting is done.
  • RenderingBackend - Depending on the platfrom, it can be DirectX9, DirectX11 or OpenGL. The rendering backend is linked statically with the HelloGT sample.

The CoherentApplication framework gives us the basic functionality for setting up a cross platform application and we'll not go over it. The focus instead is on the the other 2 modules.

HelloGT main application

Main loop

The main entry point of HelloGT is the coherent_sample_main function. First, an Option structure is filled with various initialization options and then the application window and the Coherent GT SDK is initialized. Note that the Option structure comes from the CoherentSampleCommon module and not from the Coherent GT SDK.

Next, a ViewInfo structure is created and a single view is added on screen. The ViewInfo structure contains various view initialization parameters, along with ViewListener and ResourceHandler instances.

The ViewListener class receives notifications for the view. The sample only implements a single notification - OnViewCreated, in the SimpleViewListener class, but you can enhance it for your needs.

The ResourceHandler class is responsible for reading resources through the coui protocol. The sample uses an instance of the FileResourceHandler class, provided by the sample framework. The class reads files from disk, but it is not limited to that. Resources can be read from any location as you only need to supply the raw bytes for the resource to the Coherent GT SDK.

The Application class

The Application class in the HelloGT application derives from the SampleApplicationBase and overrides only a few methods, which are explained next. The base class will be examined in the next section.

  • The Update method is called every frame. It invokes the SDK's UISystem::Advance and View::Layout methods. The former is responsible for general tasks, such as resource loading, and the latter executes JavaScript and updates style and layout.
  • ResizeRendering is called when the application window is resized and scales the view to the new window size.
  • OnKeyEvent and OnMouseEvent forward the key and mouse events to the view.
  • DrawScene is called every frame and invokes the ViewRenderer::Paint method, which does the actual rendering of the view. This method is called from the dedicated render thread, if one is present. After the painting is done, the view's texture is rendered on the whole screen surface.

CoherentSampleCommon

Most of the work behind the scenes of the HelloGT main application is done in the Application.cpp file and the methods that are called from HelloGT. Those are SampleApplicationBase::Initialize and SampleApplicationBase::AddView.

Initialization of the SDK

The Initialize method first creates a window and initializes the graphics device using the requested API (OpenGL/DirectX). Then it proceeds with setting up the global SDK settings through the SystemSettings structure. The debugger port and disk cache manager are specified and finally the InitializeUIGTSystem SDK API is invoked. If there were any errors during initialization, a null pointer will be returned. Next are initialized the rendering resources.

Rendering initialization and multithreading

In Coherent GT, rendering is decoupled from other systems. This gives a clear notion which methods are designed to be called from the rendering thread, if one is present.

In the sample framework, the last thing that the Initialize method does is to initialize rendering resources. Depending on the requested threading options, it either creates a new thread that does that, or directly initializes them in the main thread. Any further UISystemRenderer or ViewRenderer calls will be made from the thread that initialized the resources.

The initialization itself is performed in InitializeRenderingResources. The client is required to provide a graphics device type and an ID of the graphics context. For example, in DirectX this ID is the pointer to the device. Using this information, an instance of the UISystemRenderer is created.

Creating a view

Creating a view involves 2 steps. The sample uses the AddView method for them. The first is to create a view object using the UISystem::CreateView API, taking the ViewInfo structure passed from the main application.

The second step is creating a ViewRenderer, which will be responsible for the actual rendering of the view into a texture. The creation of the ViewRenderer requires a valid UISystemRenderer instance, which is already created in the sample, and a texture ID that will be rendered to. This texture is created by the client and must be a valid render target. The ID passed to the GT SDK is specific for the graphics API, for example for OpenGL it's a resource ID, and for DirectX it's a pointer to the texture. After the ViewRenderer is created, each ViewRenderer::Paint call will render into the specified texture. That call is executed in the main application's DrawScene method.

If you need to change the render target the view renders into, you can call ViewRenderer::SetRenderTarget later.

Updating the view

The UISystem and view objects must be updated regularly to function properly. As already outlined in the previous section, this is done in the main application's Update method.

Destruction and clean up

The clean up is straightforward and requires the destruction of any view and view renderer objects, as well as UI system render, and finally use UISystem::Uninitialize.

Check the SampleApplicationBase::Uninitialize method for a reference on how to deal with destruction of rendering resources when a dedicated rendering thread is used.

Code flow overview

Following is a recap of the events happening in the sample. Each of them is marked either with a (A) or (S) at the end, meaning that the event implementation is in the main application or the sample framework, respectively.

  • An options structure specific for the sample framework is filled. (A)
  • The sample application is initialized with the options from the main app. (S)
    • A new window is created. (S)
    • The rendering API is initialized. (S)
    • The Coherent GT SDK is initialized. (S)
    • A UISystem and UISystemRenderer objects are created. (S)
  • A FileResourceHandler instance is created. (A)
  • A SimpleViewListener instance is created. (A)
  • A Coherent::UIGT::ViewInfo structure is filled. (A)
  • A view is created, along with a view renderer object and a texture to render into. (S)
  • The main loop is ran, invoked by the main application. (S)
  • After the main loop has ended, the created view is removed and the UI system is uninitialized. (S)

Building HelloGT on Linux

Before actually compiling the HelloGT sample, the OpenGLBackend must be built first. It is located in PackageRoot/include/RenoirBackends/OpenGLBackend

Please note that Coherent GT requires GCC 4.8 or higher.

To compile the backend, navigate to the backend folder and run make:

cd PackageRoot/include/RenoirBackends/OpenGLBackend
make config=release_x64
Note
CoherentGT supports only 64 bit architecture on Linux.

After the OpenGLBackend is built, the PackageRoot/Samples/UI/bin folder must be added to the LD_LIBRARY_PATH

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/desktop/PackageRoot/Samples/UI/bin

Now, you can compile the HelloGT sample:

cd PackageRoot/Sample/UI/C++/HelloGT
make config=release_x64

and then run it:

cd PackageRoot/Sample/UI/bin
./HelloGT