Klimczak.Jan Posted February 7, 2018 Share Posted February 7, 2018 Hi, At the last time I make a few tests about implementing Coherent GT GUI framework into Unigine (just display layer). This is just prototype, needs refactoring (especially see header file) and maybe some optimize. It's not documented anywhere, so I would like to share with it: AppWorldLogic.h: #include <RenoirBackends/dx11backend/Dx11Backend.h> #include "ResourceFileHandler.h" #include <Coherent/UIGT/UISystem.h> #include <Coherent/UIGT/View.h> #include <Coherent/UIGT/IDiskCache.h> #include <Coherent/UIGT/ResourceHandler.h> #include <Coherent/UIGT/LicenseGT.h> #include <Coherent/UIGT/UISystemListener.h> #include <Coherent/UIGT/ViewInfo.h> #include <UnigineLogic.h> #include <UnigineStreams.h> #include "UnigineEngine.h" #include "UnigineGui.h" #include "UnigineWidgets.h" #include "UnigineEditor.h" #include "UnigineTextures.h" #include "UnigineApp.h" #include "UnigineMaterials.h" #include <windows.h> #if !defined(WIN32_LEAN_AND_MEAN) #define WIN32_LEAN_AND_MEAN #endif #if !defined(NOMINMAX) #define NOMINMAX #endif #if defined(COHERENT_PLATFORM_DURANGO) #include <d3d11_x.h> #else #include <d3d11.h> #endif #include <d3d11_1.h> #include "RenoirBackends/Common/Types.h" #include "RenoirBackends/Common/ComHelpers.h" #include <cassert> #if defined(COHERENT_SUPPORT_VS2013) #ifdef COHERENT_EXPORT #define COHERENT_RENDERERBACKEND_API __declspec(dllexport) #else #define COHERENT_RENDERERBACKEND_API __declspec(dllimport) #endif #endif using namespace Unigine; class AppWorldLogic : public Unigine::WorldLogic { int createdHUD = false; Coherent::UIGT::UISystem* system; Coherent::UIGT::View* view; Coherent::UIGT::ViewRenderer* viewRenderer; Coherent::UIGT::UISystemRenderer* systemRenderer; Coherent::UIGT::NativeRenderTarget rt; FileResourceHandler fileHandler; ID3D11Device* device; renoir::Dx11Backend* backend; WidgetSpritePtr hud; Engine* engine; Editor* editor; WidgetLabelPtr widget_label; TexturePtr my_texture; TexturePtr my_texture_ds; ID3D11DepthStencilView* DSV; ID3D11RenderTargetView* TextureRTV; NodePtr cube; public: AppWorldLogic(); virtual ~AppWorldLogic(); virtual int init(); virtual int update(); virtual int render(); virtual int flush(); virtual int shutdown(); virtual int destroy(); virtual int save(const Unigine::StreamPtr &stream); virtual int restore(const Unigine::StreamPtr &stream); void createHUDWidgetSprite(); void createLabel(); void createDSTexture(); int SetWidgetSpriteTexture(Unigine::WidgetSpritePtr sprite); }; AppWorldLogic.cpp: void AppWorldLogic::createHUDWidgetSprite() { GuiPtr gui = Gui::get(); hud = WidgetSprite::create(gui); hud->setPosition(0, 0); hud->setWidth(1600); hud->setHeight(900); hud->setLayerBlendFunc(0, Gui::BLEND_ONE, Gui::BLEND_ONE_MINUS_SRC_ALPHA); gui->addChild(hud->getWidget(), Gui::ALIGN_OVERLAP); } void AppWorldLogic::createLabel() { // getting a pointer to the system GUI GuiPtr gui = Gui::get(); // creating a label widget and setting up its caption widget_label = WidgetLabel::create(gui, "Label text"); // setting a tooltip widget_label->setToolTip("This is a label"); // rearranging label size widget_label->arrange(); // setting label position widget_label->setPosition(10, 10); // adding created label widget to the system GUI gui->addChild(widget_label->getWidget(), Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED); } void AppWorldLogic::createDSTexture() { my_texture_ds = Texture::create(); const int width = int(view->GetWidth()); const int height = int(view->GetHeight()); int flags = Unigine::Texture::FILTER_LINEAR | Unigine::Texture::USAGE_RENDER; my_texture_ds->create2D(width, height, Unigine::Texture::FORMAT_RGBA8, flags); } int AppWorldLogic::SetWidgetSpriteTexture(Unigine::WidgetSpritePtr sprite) { my_texture = Texture::create(); const int width = int(view->GetWidth()); const int height = int(view->GetHeight()); int flags = Unigine::Texture::FILTER_LINEAR | Unigine::Texture::USAGE_RENDER; my_texture->create2D(width, height, Unigine::Texture::FORMAT_RGBA8, flags); sprite->setRender(my_texture); return 1; } int AppWorldLogic::init() { // Write here code to be called on world initialization: initialize resources for your world scene during the world start. /// Configure the System settings in a Coherent::UIGT::SystemSettings variable. /// Only set a debugger port for debugging purposes everything else is /// by default. //! [System] Coherent::UIGT::SystemSettings settings; settings.DebuggerPort = 19999; system = InitializeUIGTSystem(COHERENT_UI_GT_LICENSE, settings, Coherent::LoggingGT::Info); //! [System] /// Configure the View settings in a Coherent::UIGT::ViewInfo variable. /// Create the FileResourceHandler if you want to work with "coui" resources. /// Set the full path to the html document you want to load. /// Create the View using the System->CreateView. //! [View] const char* resourcePath = "coui://uiresources/minRes/MainUI.html"; Coherent::UIGT::ViewInfo info; info.Width = 1600; info.Height = 900; info.IsTransparent = true; info.ResourceHandlerInstance = &fileHandler; /// Required for resources loaded via the coui:// protocol to work view = system->CreateView(info, resourcePath); //! [View] createHUDWidgetSprite(); createLabel(); SetWidgetSpriteTexture(hud); createDSTexture(); /// Create and initialize the rendering backend for DirectX11 /// You can use your own backend if it inherits from the RendererBackend interface. ////! [Backend] device = static_cast<ID3D11Device*>(Unigine::App::get()->getD3D11Device()); backend = new renoir::Dx11Backend(device, false); backend->InitializeStaticResources(); ////! [Backend] /// Create the System Renderer using the system->CreateRenderer method and the backend. //! [SystemRenderer] systemRenderer = system->CreateRenderer(backend, backend); //! [SystemRenderer] ///// Create the View Renderer using the systemRenderer->CreateViewRenderer method and ///// the textures from the DirectX initialization. ////! [ViewRenderer] DSV = static_cast<ID3D11DepthStencilView*>(my_texture->getD3D11DepthStencilView()); TextureRTV = static_cast<ID3D11RenderTargetView*>(my_texture->getD3D11RenderTargetView()); rt.Texture = TextureRTV; rt.DepthStencilTexture = DSV; viewRenderer = systemRenderer->CreateViewRenderer(view, rt, view->GetWidth(), view->GetHeight(), 1); ////! [ViewRenderer] Materials *materials = Materials::get(); MaterialPtr m = materials->findMaterial("mesh_base"); int num = m->findTexture("albedo"); m->setTexture(num, my_texture); return 1; } // start of the main loop int AppWorldLogic::update() { // Write here code to be called before updating each render frame: specify all graphics-related functions you want to be called every frame while your application executes. ////! [Loop] ///// Advances the timers of the UI. Should be called each frame. system->Advance(); ///// Layouts the content of the page. You should call this method each frame ///// after calling Advance on the UI system unsigned frameId = view->Layout(); ///// Paints the View in the user supplied texture when using hardware ///// rendering. viewRenderer->Paint(frameId); return 1; } int AppWorldLogic::render() { // The engine calls this function before rendering each render frame: correct behavior after the state of the node has been updated. return 1; } int AppWorldLogic::flush() { // Write here code to be called before updating each physics frame: control physics in your application and put non-rendering calculations. // The engine calls flush() with the fixed rate (60 times per second by default) regardless of the FPS value. // WARNING: do not create, delete or change transformations of nodes here, because rendering is already in progress. return 1; } // end of the main loop int AppWorldLogic::shutdown() { // Write here code to be called on world shutdown: delete resources that were created during world script execution to avoid memory leaks. return 1; } int AppWorldLogic::destroy() { // Write here code to be called when the video mode is changed or the application is restarted (i.e. video_restart is called). It is used to reinitialize the graphics context. ///// The order of resource destruction is really important! ////! [Destruction] viewRenderer->Destroy(); viewRenderer = nullptr; view->Destroy(); view = nullptr; systemRenderer->Destroy(); systemRenderer = nullptr; system->Uninitialize(); system = nullptr; ////! [Destruction] return 1; } Also you will need a ResourceFileHandler.h file that come and for e.g. dx11backend project from CoherentGT (I can't share it here because of license agreement). For work it needs an object witrh "mesh_base" material at scene. Also it needs minRes files from sample delivered with CoherentGT in data folder. It will display a Coherent GUI at the screen and at object in scene. 2 Link to comment
morbid Posted February 8, 2018 Share Posted February 8, 2018 Thank you a lot for sharing! I'll forward this to our tech writers team. 1 How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
Joslin.Chris Posted September 28, 2018 Share Posted September 28, 2018 Hi all, Sorry for reviving this thread but I'm experiencing some challenges integrating CoherentGT in our project. We are trying to render CoherentGT onto a plane in the Unigine world and are using the Vive. The Code above works as of Unigine SDK v2.7.1 and CoherentGT can render its UI into Unigine. However, the Vive screen mirror is being overlayed onto the CoherentGT UI. I believe this is because CoherentGT uses the same d3d11device as the Unigine::App window and renders the screen mirror along with Coherent. I can mitigate this by setting the Unigine::App width and height to 1, but we lose our app screen mirror view, which we do not want. What would be the best way to give CoherentGT a separate d3d11device for it to render its UI so the Vive screen mirror doesn’t get overlayed onto it? Link to comment
Recommended Posts