Two 3d views running simultaneously in a Qt-application


photo

Recommended Posts

Posted (edited)

Hello,

We have a custom Qt app with an Unigine viewport integrated into it. There is a main 3d view which shows a scene and we're going to have a separate dialog windows that are supposed to include a 3d preview of a procedurally created object that is being edited in that window and added to the main scene afterwards. So this requires displaying two separate 3D scenes in two widgets: main scene that includes all objects and a 3d preview scene that includes one object only. We are using Unigine::CustomApp-derived class with the rendering loop controlled by Unigine. As far as we understood it is not possible to have two 3d widgets in the same app rendering two different scenes simultaneously. Is this correct? It seems that it is not possible to have two Unigine::Engine instances (we got "Unigine::Engine::init() : is already initialized" error).

If we cannot run two 3d views simultaneously, is there an easy way to stop rendering in one view and start in another one? This would also work for us. Since CustomApp-derived class deals with window handles when creating rendering context (each time window is resized), I thought maybe we could inject a new window id there whenever we open a 3d preview dialog so it will switch to rendering to a new render window. Is this feasible? Thanks in advance

Edited by scopic
Link to post

Hello scopic,


You can render a 3D scene in a Qt widget using RenderContext and Viewport.
For example, you have a Qt widget for rendering 3D objects and a main widget for rendering the world. Each widget must have a RenderContext and a Viewport instances.

RenderContext can be created as follows: 

RenderContextPtr ctx = App::createContext();
QWidget *window = new QWidget;

ctx->createVisual();
ctx->createContext(reinterpret_cast<void *>(window->winId()), window->width(), window->height());


In a class derived from CustomApp, you must override the methods: doUpdate, doRender, doSwap. 

void AppQt::doUpdate()
{
	update();
 
	// engine_window_ is QWidget-derived for world rendering
	main_context_->resizeWindow(engine_window_->width(), engine_window_->height());
	engine_window_->doUpdate(); // update some logic

 	// WindowData contains RenderContext and Widget
	for (const WindowData &data : window_resources_)
	{
		data.context->resizeWindow(data.window->width(), data.window->height());
		data.window->doUpdate(); // update some logic
	}
}

 
void AppQt::doRender()
{
	// rendering 3D scenes
	for (const WindowData &data : window_resources_)
	{
		data.context->renderWindow(); // set render target
		data.window->doRender(); // call Viewport::renderNodes and etc ...
	}
 
	// rendering world, profiler, etc ...
	main_context_->renderWindow(); // set render target
	render();
	engine_window_->doRender();
}

 
void AppQt::doSwap()
{
	swap();
	main_context_->swapWindow();
 
	for (const WindowData &data : window_resources_)
	{
		data.context->swapWindow();
	}
}

 

  • Like 2
  • Thanks 1
Link to post
Posted (edited)

Dear @scopic

You may also refer to this discussion for the same things required before.

And what @zayaa explained with example is sufficient to achieve what you need.

Rohit

Edited by rohit.gonsalves
  • Thanks 1
Link to post