Multiple Window Example

What it says on the tin: a place to discuss proposed new features.
Post Reply
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Multiple Window Example

Post by KungFooMasta »

It would be great if somebody could share a simple example (on the ogre wiki) of an application using multiple windows. Specifically, an application where you can safely close the "main" window and all other windows are destroyed properly. I say "main" because there is mention of having a 1 x 1 dummy window used for the main rendering context, and having it remain hidden behind the "main" window. I haven't been able to create an invisible dummy window, and a multiple window example would be helpful to a lot of people, I imagine.

KungFooMasta
Creator of QuickGUI!
User avatar
FrameFever
Platinum Sponsor
Platinum Sponsor
Posts: 414
Joined: Fri Apr 27, 2007 10:05 am

Post by FrameFever »

you know, that this works only for GUI systems. like Qt or MFC?
create simply an invisible Widget, give the handle Ogre, and thats it. You have to destroy all other windows, before you destroy the MAIN window.
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 67
Contact:

Post by sinbad »

Precisely. Every single application created using something like Qt or wxWidgets has to have a top-level window. So create a 1x1 primary Ogre window attached to the HWND of that. Then create 'proper' windows for all the viewports or real app windows that you use. Simple, effective. The code is no different to creating one window with an externalWindowHandle.
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

you know, that this works only for GUI systems. like Qt or MFC?
I don't understand why this is the case. I've created multiple windows using the Ogre::RenderSystem::createWindow function, and I've setup each window with its own viewport and QuickGUI Manager, and I've been able to work with UI in each window. My main problem is figuring out how to use Ogre API to create the dummy window. In my situation I cannot close my main window before any other windows, or the main render context is destroyed and an exception is thrown. Maybe I can't use Ogre's API for this?
So create a 1x1 primary Ogre window attached to the HWND of that.
It probably is a very simple implementation, I was just requesting a code snippet of creating the top-level window, (for simplicity, say in Windows OS) creating the dummy window, and attaching the dummy window to the Top Level Window.

Is this a very environment specific solution, such that nobody can produce this snippet of code and have it work for others? If its so simple, whats stopping people from posting a few lines of code? :) (with code comes additional clarity)

Judging by the 150+ views on this thread, I'm not the only person interested in this.
Creator of QuickGUI!
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Post by CABAListic »

It's simply not doable with Ogre alone. The Ogre code to create a render window just handles a rather basic window without any advanced stuff, simply because that's not Ogre's scope to do. But you do need something slightly more sophisticated, so you need a GUI library like wxWidgets or whatever to do that job.
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 67
Contact:

Post by sinbad »

I have snippets but they're either wxWidgets or Qt specific and I don't have time to create another one right now. To recreate it in Win32, just do this:

- create a win32 window
- create a 1x1 ogre window and give it the HWND using externalWindowHandle
- create x number of child windows and create ogre windows for each, passing them the HWNDs as externalWindowHandle

You've specifically chosen not to do a top-level window by the sounds of it, and this is biting you in the ass. My constant recommendation to you has been not to do this, but to use a consistent single top-level window which cannot be destroyed independently of the other windows, because it's the parent of the others. This is how the majority of wx and qt apps work. If you want to do it a different way, with no single 'master' window in your app, then you're on your own, sorry. You'll have to find your own way to manage the issue of what to do with the 'master' window that all render system APIs need.

I think the problem is not code, it's your window structure design. Every GUI app I've ever dealt with has a 'master' window, closing which causes the app to terminate (and thus other windows to close first). That's the case even with 'floating' window models (which I hate anyway) like GIMP - there's usually one window (e.g. a toolbox) that if you close it indicates 'exit entire app'. Most apps use a contained model where all child windows are contained in one outer window so the outer layers (top level window, or a container that manages multiple viewport subwindows) are perfect holders for the master window reference. Ogre works perfectly with this setup because you use the master window as your anchor point for the rendersystem's device / context with a 1x1 window. If you choose to deviate from that model, and allow other render windows to exist after your previous 'master' window has been destroyed, that's your choice but don't be surprised if we can't give you a code snippet to handle it - you're making it hard for yourself ;)

In short, your question is not about a multi-window example, it's about how to handle completely arbitrary windows that can all be opened and closed independently with no single window always being in existence. I can't give you a snippet, all I can do is tell you no-one else I know does it that way, and for a good reason. It's not impossible to handle, but you would have to deal with managing the device / context differently to what pretty much everyone else does. Maybe putting a little window in the corner of the desktop or something would be an option, I dunno - I've never had to do it. Hence, the lack of snippets. My best advice to you is to change your thinking on window structure, it's that that's causing you all the problems.
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

Thanks for the long response Sinbad. I was only throwing out my approach to give an understanding of my situation. I would like to make it work in the way you have suggested, but I'm not sure I understand (via code) how to implement the following steps you outlined:
- create a win32 window
- create a 1x1 ogre window and give it the HWND using externalWindowHandle
- create x number of child windows and create ogre windows for each, passing them the HWNDs as externalWindowHandle
I'm using Windows, so step 1 will be using the Windows API directly, right? What parameters should I provide the window? (specific border type, or showing titlebar, etc.)

For step 2, will I use Ogre API to create a Render Window? (ie RenderSystem::createRenderWindow and set the "externalWindowHandle" property)

For step 3 I will use both Windows API and Ogre API, creating 2 windows and linking the Ogre window to Windows window?

Any snippets are most welcome, its the easiest for me to understand in this case.
Creator of QuickGUI!
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 67
Contact:

Post by sinbad »

KungFooMasta wrote:
- create a win32 window
- create a 1x1 ogre window and give it the HWND using externalWindowHandle
- create x number of child windows and create ogre windows for each, passing them the HWNDs as externalWindowHandle
I'm using Windows, so step 1 will be using the Windows API directly, right? What parameters should I provide the window? (specific border type, or showing titlebar, etc.)

Anything you like really. OGRE just wants to render into the client area, it doesn't care about anything outside it. Usually I use a nested panel rather than a whole window because it fits better with the docking / MDI style but it's up to you. For the dummy render window in fact, nothing matters because you're never going to render it, you just need a HWND.
For step 2, will I use Ogre API to create a Render Window? (ie RenderSystem::createRenderWindow and set the "externalWindowHandle" property)

For step 3 I will use both Windows API and Ogre API, creating 2 windows and linking the Ogre window to Windows window?
Yes. You'll want to listen in on sizing events from these windows and tell the Ogre window to resize too, as in the WxOgre examples in the wiki.
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

For anybody who wants to look into this, the following project should shed light on how to accomplish a multi window example:

http://www.ogre3d.org/phpBB2/viewtopic.php?t=41153

This example uses WxWidgets, but I don't think it will be difficult to use the code as reference to support a non-WxWidgets solution.

Here is some code snippets to give a place to start looking:

Code: Select all

	bool ViewApp::OnInit()
	{
		bootstrapOgre();

		addHandlers();

		int displayWidth, displayHeight;
		wxDisplaySize(&displayWidth, &displayHeight);
		mMainFrame = new ViewTopFrame("Top Frame", 0, 0, 
			std::min(1024, displayWidth), std::min(768, displayHeight));
In particular, we want to focus on creation of the ViewTopFrame object.

Code: Select all

	ViewTopFrame::ViewTopFrame(const wxChar *title, int xpos, int ypos, int width, int height)
		: wxFrame( (wxFrame *) NULL, -1, title,	wxPoint(xpos, ypos),
			wxSize(width, height)
		), mTreeImageList(16, 16), mCreateMenuSeparatorIndex(0)
	{
		// Create dummy window just to hold device, prevents constant lost devices
		// when resizing the 'real' viewable windows
		// We'll never render to this window or give it a viewport or camera, it's
		// only there to hold the rendering device
		ViewUtils::createOgreWindow(this, wxSize(1,1));
Creator of QuickGUI!
User avatar
pjcast
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2543
Joined: Fri Oct 24, 2003 2:53 am
Location: San Diego, Ca
x 2
Contact:

Post by pjcast »

Well, long before that was release, there was also Ogre Studio codebase completely available to see multiple/resizable/reconfigurable multi-window code base with Ogre (although using C#) ;)

http://www.wreckedgames.com/svn/


But anyways, kudos for Sinbad for releasing an awesome wxwidgets + Ogre framework :) If I ever do work on a Ogre editor again, I will probably use this as a basis, since I think it is a great basis for a cross platform editor.
Have a question about Input? Video? WGE? Come on over... http://www.wreckedgames.com/forum/
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

Ah, Ogre Studio, I forgot! :oops:

I will look into that also. :D
Creator of QuickGUI!
Post Reply