Fullscreen in multiwindow scenario

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
Post Reply
User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany

Fullscreen in multiwindow scenario

Post by xadhoom » Tue Jun 01, 2010 8:52 pm

Hi,

I am currently working on a configuration menu. I´m using the configuration properties retrieved from Ogre. In order to facilitate changing properties like Full Screen, VSync etc. without restarting Ogre, I use the the "1x1 pixel window trick" described by sinbad in the following thread:

http://www.ogre3d.org/forums/viewtopic. ... 11&start=0

Unfortunately I am always encountering an exception whenever I change the secondary window (in which the actual rendering occurs) to fullscreen. I am getting the following exception when I recreate the window with full screen set to true using D3D9 or when I set it to fullscreen afterwards:

Code: Select all

OGRE EXCEPTION(3:RenderingAPIException): Unable to get the swap chain in D3D9RenderWindow ::acquireRenderWindowResources at ..\..\..\..\..\RenderSystems\Direct3D9\src\OgreD3D9Device.cpp (line 1036)
Is it generally possible to have two windows (one which is actually hidden and is only used to hold the D3D context) while the other one is running in fullscreen? If yes, how?

It would be great if anybody could share his experience with multiple windows.

xad
0 x

User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
Contact:

Re: Fullscreen in multiwindow scenario

Post by sparkprime » Tue Jun 01, 2010 10:27 pm

Ogre should probably just do the 1x1 window thing internally and hide this irritation from the user. As I understand it it's a D3D9 thing anyway so no problem with using win api calls to hide the extra window.
0 x

User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
Contact:

Re: Fullscreen in multiwindow scenario

Post by jacmoe » Tue Jun 01, 2010 10:31 pm

I think the 1x1 window trick is helpful only when you want to destroy renderwindows, not for configuration switching.

The SampleBrowser does that, switching config on the fly, so if you're only using one renderwindow, peek at the code. :)
0 x
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.

User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
Contact:

Re: Fullscreen in multiwindow scenario

Post by sparkprime » Tue Jun 01, 2010 10:46 pm

But it does it by destroying everything, right? I can't find which source file this is implemented in...
0 x

User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany

Re: Fullscreen in multiwindow scenario

Post by xadhoom » Wed Jun 02, 2010 9:48 am

We checked the Ogre sample code beforehand and figured out the approach there. The sample browser also destroys the renderwindow and recreates it. See the excerpt here when applying config changes (SampleContext.h):

Code: Select all

virtual void reconfigure(const Ogre::String& renderer, Ogre::NameValuePairList& options)
{
    // save current sample state
    mLastSample = mCurrentSample;
    if (mCurrentSample) mCurrentSample->saveState(mLastSampleState);

    mNextRenderer = renderer;
    Ogre::RenderSystem* rs = mRoot->getRenderSystemByName(renderer);

    // set all given render system options
    for (Ogre::NameValuePairList::iterator it = options.begin(); it != options.end(); it++)
    {
        rs->setConfigOption(it->first, it->second);
                
#if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
        // Change the viewport orientation on the fly if requested
        if(it->first == "Orientation")
        {
            if (it->second == "Landscape Left")
                mWindow->getViewport(0)->setOrientationMode(Ogre::OR_LANDSCAPELEFT, true);
            else if (it->second == "Landscape Right")
                mWindow->getViewport(0)->setOrientationMode(Ogre::OR_LANDSCAPERIGHT, true);
            else if (it->second == "Portrait")
                mWindow->getViewport(0)->setOrientationMode(Ogre::OR_PORTRAIT, true);
        }
#endif
    }

#if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
    // Need to save the config on iPhone to make sure that changes are kept on disk
    mRoot->saveConfig();
#endif
    mLastRun = false;             // we want to go again with the new settings
    mRoot->queueEndRendering();   // break from render loop
This code changes the configuration params within Ogre. Most important here is the setting of "mLastRun = false" at the end of the method which leads to several reinitilisation calls in the main loop here:

Code: Select all

virtual void go(Sample* initialSample = 0)
{
    while (!mLastRun)
    {
        mLastRun = true;  // assume this is our last run

        initApp(initialSample);

        mRoot->startRendering();    // start the render loop

        closeApp();

        mFirstRun = false;
    }
}
initApp() eventually calls setup() which newly initialises the Root with:

Code: Select all

virtual void createWindow()
{
    mWindow = mRoot->initialise(true);
}
When you change your settings in the sample browser the window is completely recreated...
0 x

User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
Contact:

Re: Fullscreen in multiwindow scenario

Post by sparkprime » Wed Jun 02, 2010 1:56 pm

So all resources are dead because the render system was reinitialised?
0 x

User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany

Re: Fullscreen in multiwindow scenario

Post by xadhoom » Wed Jun 02, 2010 9:20 pm

AFAIK Ogre takes care of context reinitialisation but I don´t know if this also works when changing the whole rendersystem.

Actually I could deal with changing the Rendersystem seperately (telling the user that the changes will take affect on next run), but things like VSync/Resolution(!) I would like to change on the fly. Thats the reason why I catched up the 1x1 pixel window trick from sinbad. But if this does not support a proper fullscreen window then this is a sserious drawback of this approach...

Any knowledge how to have two windows created by Ogre while one is fullscreen (and the other actually hidden for the context) without getting these nasty swap chain exception :?:

xad
0 x

User avatar
sparkprime
Ogre Magi
Posts: 1137
Joined: Mon May 07, 2007 3:43 am
Location: Ossining, New York
Contact:

Re: Fullscreen in multiwindow scenario

Post by sparkprime » Wed Jun 02, 2010 11:40 pm

I know directx games support this so it must be possible. It might be difficult to make the changes within ogre to support this, though. But that's why programmers make more money than plumbers.
0 x

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 4148
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 270
Contact:

Re: Fullscreen in multiwindow scenario

Post by dark_sylinc » Sun Jun 06, 2010 5:40 pm

When you do the 1x1 window trick, be sure that you create the new window BEFORE removing 1x1 window.

If you remove the 1x1 window, then create a new window, there will be a time lapse where OGRE has no render window, which is not supported by OGRE. This causes lots of weird crashes.

Cheers
Dark Sylinc
0 x

User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany

Re: Fullscreen in multiwindow scenario

Post by xadhoom » Sun Jun 06, 2010 9:50 pm

dark_sylinc,

Thank you for your warning. Actually I never destroy the 1x1 window(!) because its especially meant to be alive throughout the whole application lifetime holding the Directx/GL context. I only destroy the secondary window (which actually shows rendered content) on property changes like the resolution without the need to destroy the context.

The problem is IMHO related to the directx specific management of the swap chain in a multiwindow environment. BUT as I described above the problem only occurs when making the secondary window fullscreen.

xad
0 x

Toadcop
Gnoblar
Posts: 15
Joined: Sat Jul 18, 2009 9:37 pm

Re: Fullscreen in multiwindow scenario

Post by Toadcop » Mon Jun 07, 2010 5:19 pm

same problem here.

are any solutions for this ? (keeping 2 renderwindows)
in my case the first one is custom created with windows api (with out Taskbar button etc.).
0 x

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Fullscreen in multiwindow scenario

Post by Nir Hasson » Wed Jun 09, 2010 10:53 pm

I will check and fix it soon…
The fix will go to the trunk anyway
0 x

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Fullscreen in multiwindow scenario

Post by Nir Hasson » Wed Jun 09, 2010 11:39 pm

Fixed commited - let me now if it works now... :D

EDIT:

You should know that in this scenario, you'll have two devices -
one for your hidden 1x1 window, and one for the fullscreen window, so I guess it takes out the advantage of the 1x1 trick...
0 x

User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel

Re: Fullscreen in multiwindow scenario

Post by Mattan Furst » Fri Jun 11, 2010 7:21 am

@Nir
You should know that in this scenario, you'll have two devices -
one for your hidden 1x1 window, and one for the fullscreen window, so I guess it takes out the advantage of the 1x1 trick...
I will soon need to implement a feature much like the one described by xadhoom and I have a couple of question.
  1. Does the 1x1 window always have a separate device from all other windows?
  2. Does this mean that resources such as dynamic textures and geometry buffers are automatically allocated separately for it in the graphics card? (wasting memory space in the process)
  3. If the answer to both questions is true, do I need to create the 1x1 window as the first window I create or can I create it just before I'm about to delete my last window? (That as long as any window exists the system wont throw exceptions)
0 x
it's turtles all the way down

User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany

Re: Fullscreen in multiwindow scenario

Post by xadhoom » Fri Jun 11, 2010 10:46 am

Nir Hasson wrote:Fixed commited - let me now if it works now... :D

EDIT:

You should know that in this scenario, you'll have two devices -
one for your hidden 1x1 window, and one for the fullscreen window, so I guess it takes out the advantage of the 1x1 trick...
Hi Nir,

Thank you for looking into this. Ofcourse the whole idea of this hidden window is to always keep the one-and-only context and do whatever with the visible window. So your change might be even worse then the previous solution. Because previously it was possible to have a hidden window (holding the one-and-only context) and another (not-fullscreen) window which rendered everything.

Isn´t it possible to consistently handle the fullscreen case as well, or is this probably a DirectX limitation?

xad
0 x

User avatar
Wolfmanfx
OGRE Team Member
OGRE Team Member
Posts: 1525
Joined: Fri Feb 03, 2006 10:37 pm
Location: Austria - Leoben
x 1
Contact:

Re: Fullscreen in multiwindow scenario

Post by Wolfmanfx » Fri Jun 11, 2010 11:15 am

I am using also this trick for my editor the whole idea is it that the two windows share their context so that you can create resources and many windows on the fly.
0 x

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Fullscreen in multiwindow scenario

Post by Nir Hasson » Fri Jun 11, 2010 1:09 pm

I’ll try to clear the things for all of you guys – and for me too :D

@xad, wolfmanfx
When a windowed mode scenario is in use – there is only one device held by the first window that created, which is the 1x1 window, and the rest of the windows are presenting the content using the swap chain interface.
So there is no waste of memory, and you gain the performance when resizing (no reset required) etc…
So bottom line – if you are working in this mode, (only windowed windows) everything works the same.

@Mattan
In case you are working in a windowed mode scenario – look at the answer for xad.
When creating a fullscreen render window an exclusive device is needed (the name is also sometimes refered as exclusive mode). That means that no other windows can use this device or its swap chain interface (except the case of multihead scenario – but it is really a special case and it is disabled in most cases anyway).
In order to avoid memory waste I can suggest you to set the resource creation policy to RCP_CREATE_ON_ACTIVE_DEVICE. So only the active device will have it’s resources.

Anyway for your questions –
1.Only in fullscreen scenario there are multiple devices.
2.It depends in the resource creation policy.
3.You should create it first in order to make it hold the device – otherwise it will only hold the swap chain and you’ll lose the benefits of this trick.
0 x

User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany

Re: Fullscreen in multiwindow scenario

Post by xadhoom » Fri Jun 11, 2010 1:59 pm

Nir,

Thanks for the clarification. :)

One more question you did not answer in particular. When I have the hidden 1x1 window (created as first window) and have now a second fullscreen window (general setup is RCP_CREATE_ON_ACTIVE_DEVICE). Does destroying the fullscreen renderwindow also destroy all resources or are these still present at the 1x1 window context. I´m probably a bit confused with exclusive modes, device contexts and the RCP_CREATE_ON_ACTIVE_DEVICE flag...

Actually the main motivation of the whole thread was to figure out a way to be able to easily adjust window settings at runtime without destroying any resources...

xad
0 x

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Fullscreen in multiwindow scenario

Post by Nir Hasson » Fri Jun 11, 2010 4:33 pm

@xad
In the scenario you described destroying the fullscreen render window will NOTaffect the resources that exists on the device of the hidden window.

Regarding the original motivation – working with windowed windows remains as usual.
When you decide to toggle to full screen mode, create the fullscreen render window, trigger an update call in order to create all the needed resources, and then destroy the hidden window in order to save memory.
Before switching back, create the hidden window, create a secondary windowed window, trigger an update call in order to force resource creation and then destroy the fullscreen window.
One thing to pay attention to is that in the ovelaps frames - the amount of resource memory is doubled since both devices holds all of them...
0 x

pencheff
Gnoblar
Posts: 3
Joined: Thu Oct 07, 2010 9:18 am

Re: Fullscreen in multiwindow scenario

Post by pencheff » Thu Nov 22, 2012 1:51 pm

Sorry to dig out this old thread, but let me share my workaround for switching between fullscreen/windowed on the fly...

After like a full week trying to work around the swapchain issues (there can be only one swapchain per Ogre::RenderWindow in exclusive fullscreen D3D9), I came to a working solution:

Normal renderer startup (in windowed mode):
  • 1. create hidden 1x1 renderwindow
    2. Do whatever resource creation and initialize ogre resource managers
    3. create any number of Ogre::RenderWindow instances
Switching from windowed to fullscreen:
  • 1. Set one of the visible Ogre::RenderWindow instances to fullscreen - RenderWindow::setFullscren(true, width, height)
    2. Destroy the hidden render window
Switching from fullscreen back to windowed (the tricky part):
  • 1. Internally destroy the fullscreen window and save its parameters somewhere (owner window handle if there is such, position and other parameters)
    2. Create the hidden render window, and call RenderWindow::update() so it recreates all resources
    3. recreate the windowed that you destroyed earlier in 1.
0 x

Post Reply