Render into multiple windows / widgets

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Donner
Posts: 87
Joined: Fri May 18, 2007 11:27 am

Render into multiple windows / widgets

Post by Donner »

Hi,

i'm working on a program that has to be able to render from three cameras into three different widgets (I'm using Qt, but I guess this is a general question).

This is how I did it so far:

First, I create an Irrlicht device and I set the window handle of the first widget to render in as the WindowId-property of the creation parameters.

Then, whenever there needs to be a render in a certain widget, I do this:

Code: Select all

Driver->OnResize(widgetSize); // widgetSize_id = size of the current widget to render into
Driver->beginScene(true, true, backgroundcolor, irr::video::SExposedVideoData(window_id)); // window_id = handle of the current widget to render into
SceneManager->setActiveCamera(cam);
SceneManager->drawAll();
Driver->endScene()
The problem with this is, that this has horrible performance. Calling OnResize every time is taking really long so the fps rate drops a lot (under 10 fps).
On the other hand, when I don't call OnResize, the driver uses the same resolution for all rendering widgets, but actually they have different sizes.

What do I have to do to make this work?

Thanks a lot,
D.
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

Each time you resize the device you reset the video driver, which is very expensive.

I suggest making the device the size of the largest widget, then use setViewPort to set the rendering area to the size of the current widget.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
Donner
Posts: 87
Joined: Fri May 18, 2007 11:27 am

Post by Donner »

Hey,

thanks for your reply!

The problem with your approach is the following:
The scale gets messed up if the widget size is different from the size set with OnResize.
So for instance, if i set the driver size to 200x200 and the widget is 100x200 and now i set the viewport to 100x200, the actual viewport will have the size 50x200. It seems like irrlicht "squeezes" the whole screen size into the widget.

How can I solve this problem?
Thank you!
D.

PS: Maybe there is any code I can use? Unfortunately irrEdit isn't openSource, but there it seems to work fine, so there should be a way to realize rendering in several widgets with different sizes...
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Just set your apsect ratio of the camera to the desired values, and render into the viewport. Yes, the currently set up ratio is used for rendering, squeezing the whole screen into the view port dimensions. For irrEdit and our split screen example we use 4 viewports, which keep the aspect ratio.
Donner
Posts: 87
Joined: Fri May 18, 2007 11:27 am

Post by Donner »

Thanks for your help!

Unfportunately it still doesn't work. I did call aspectRatio(Width / Height) before, now I also added it right before the call of drawAll() - nothing changes.
Irrlicht still squeezes the whole screen size into the widget.

I use multiple SceneManagers, what Camera's aspect ratio does the driver take? Does it always use the standard scenemanager's active camera?
It seems not to matter, even if I set the aspectRatio to all existing cameras, it still doesn't change anything.

What else could be the problem?

Thanks,
D.
blAaarg
Posts: 94
Joined: Tue Mar 02, 2010 9:11 pm
Location: SoCal

Post by blAaarg »

Can you use the last parameter of irr::video::IVideoDriver::beginScene() to create a rectangle of the same dimensions and/or aspect ratio as the widget in order to clip the current camera's render? The API says this only works on certain platforms but unfortunately doesn't specify which. :cry:

I do know that setViewPort() does stretch or squish the render, like you say, but I don't know how Qt handles that (clip or squish). When you use hybrid's suggestion, are you resetting the camera's aspect ratio AND the viewport? 'Cuz, I would think it's an either/or implementation: reset the camera's aspect ratio but make sure the view port isn't altered.

I'm asking for my own edification since this is something I'm looking forward to, myself. Hopefully, those are useful suggestions that don't waste your time. :)

Interested in your outcome,
blAaarg

P.S.
what Camera's aspect ratio does the driver take? Does it always use the standard scenemanager's active camera?
I believe it takes the current scene manager's active camera, if that's what you meant. So Smgr1->drawAll() sets Smgr1's "active" camera, Smgr2->drawAll() first sets it's own/different "active" camera and so on...
"Computers don't make mistakes! What they do they do on purpose!!"

-Dale Gribble
Donner
Posts: 87
Joined: Fri May 18, 2007 11:27 am

Post by Donner »

Hey blAaarg,
thank you very much for your help!

I finally got it to work!
Indeed I had to set the last parameter of beginScene().
Nevertheless, I still had to use setViewport AND setAspectRatio in order to get everything displayed the right way.

Now I got it looks somewhat like this:

Code: Select all

cam->setAspectRatio(size_rect.Width / size_rect.Height);
Driver->setViewPort(size_rect);
Driver->beginScene(true, true, backgroundcolor, irr::video::SExposedVideoData(window_id), &size_rect); 
SceneManager->setActiveCamera(cam); 
SceneManager->drawAll();
Driver->endScene()
blAaarg wrote:The API says this only works on certain platforms but unfortunately doesn't specify which.
Does anyone know more about this?

Thank you all for your help!
D.
blAaarg wrote:Hopefully, those are useful suggestions that don't waste your time.
As you can see, they solved my problem :)
Post Reply