This sample demonstrates how to use Coherent GT in a UWP application.
The sample solution is based on a default game template that VS2015 provides. Some of the sample code has been removed (such as the 3D cube rendering) but the rest is pretty much the same.
The output will be in the Coherent/bin directory.
This sample builds upon the HelloGT sample and assumes that you understand it.
GTClient
class wraps all interactions with Coherent GT - initializing the system and system renderer and creating a single view (and its view renderer).Game
class manages the DX11 device and contains the main loop for the game.The sample shows our Shadow of Saturn (SOS) UI which you've already seen in HelloGT. This controlled in Game::Initialize
:
void Game::Initialize(IUnknown* window, int width, int height){...m_demoPages.push_back("coui://uiresources/sos/MainUI.html");const char* initialURL = m_demoPages[m_currentDemoPage].c_str();...}
You can add multiple pages to m_demoPages
and then change between them using the A and D keys (see Game::OnKeyDown
).
The key part of the sample is the class GTClient
. It implements the management of GT objects. For example it initializes the system, view and their renderers in its constructor
GTClient::GTClient(const char* url, ID3D11Device* device, const CoherentDx11RenderTarget& renderTarget){Coherent::UIGT::SystemSettings settings;...m_System.reset(InitializeUIGTSystem(COHERENT_UI_GT_LICENSE,settings,Coherent::LoggingGT::Trace,m_LogHandler.get()));if (!m_System){assert(false && "System initialization failed!");return;}Coherent::UIGT::ViewInfo info;info.Width = renderTarget.Width;info.Height = renderTarget.Height;...m_View.reset(m_System->CreateView(info, url));if (!m_View){assert(false && "View initialization failed!");return;}m_Backend.reset(new renoir::Dx11Backend(device, enableMemoryTracking));auto customBackend = static_cast<renoir::Dx11Backend*>(m_Backend.get());bool didInitialize = customBackend->InitializeStaticResources();if (!didInitialize){m_Backend.reset(nullptr);assert(false && "Failed to initialize a rendering backend!");}m_UISystemRenderer.reset(m_System->CreateRenderer(m_Backend.get()));Coherent::UIGT::NativeRenderTarget rt;rt.Texture = renderTarget.RenderTargetView;rt.DepthStencilTexture = renderTarget.DepthStencilView;m_ViewRenderer.reset(m_UISystemRenderer->CreateViewRenderer(}
It also takes care of updating them:
// Advance returns a FrameId, which contains// id of the recorded rendering commands and a bool,// which marks if the id is valid or notFrameId GTClient::Advance(){FrameId frameId;if (m_System && m_View){m_System->Advance();frameId.SetValidId(m_View->Layout());}return frameId;}void GTClient::Render(unsigned frameId){if (m_System && m_ViewRenderer){m_ViewRenderer->Paint(frameId);}}
Application::Suspending
and Application::Resuming
as they may be called on threads other than the main thread.If you are interested in in using a worker thread for Coherent GT, see Asynchronous mode.