PDA

View Full Version : What are multiple windows good for?



marcus256
01-13-2003, 04:10 AM
Silly subject, perhaps. The real question is:

I want to add support for multiple windows in GLFW (http://hem.passagen.se/opengl/glfw) , and I want to know what they will be used for by real applications in order to make the GLFW API as useful and powerful as possible.

Just adding support for multiple windows is not difficult. What's more interesting is questions like support for "child windows", shared lists, etc. Here are a few more specific questions:

1) If "child windows" are useful, what kind of functionality do you expect? Input event propagation from child to parent? Parent closed => child closed? Window Z-ordering?

2) Is shared display lists / texture objects a useful feature? (This one seems very useful - and yet something that GLUT lacks)

3) Is it OK that "multiple windows" and "fullscreen window" are mutually exclusive? (This would probably help implementations alot on some platforms)

If someone could point me to some actual OpenGL applications that use multiple windows, I would be happy.

knackered
01-13-2003, 05:05 AM
Multiple windows are useful in a lot of applications, such as cad and a lot of simulations (3dview+planview).
My own approach is to allow creation of as many windows as you like, and as many 'views' within each window as you like (analogous to viewports, except each port has its own render states). You should translate any user input messages from the window to which ever view has 'focus'.
I also use a single gl context, which I make current to each window as and when I render to them. This saves on state save/restores.
I don't recommend using seperate threads for seperate windows either, as context switches will mean state switches on the graphics card at the same frequency as the threads are switched between! So that's not very efficient. One thread should look after all windows, stepping between them after each render has completed.
This is just how I do it, but it does work nicely.

marcus256
01-13-2003, 10:26 AM
Thanks knackered! This was useful information.


You should translate any user input messages from the window to which ever view has 'focus'.

Do you mean that input events should be sent to the "correct" window? I.e. check which window the event occured in, and use that window's callback - in this case? That was how I planned to do it. I just happened to stumble accross the GLUT source, which posts input events to "parent" windows too - something that I don't really see any use for (I mean, the GLFW user can manage this by assigning a single input event callback for all windows - for instance).


I also use a single gl context, which I make current to each window as and when I render to them. This saves on state save/restores.

This was a new concept for me - didn't even know it was possible. It will complicate the implementation a bit (not much), but from an API point of view it's very simple. E.g:



win1 = glfwOpenWindow( ... );

...

glfwOpenWindowHint( GLFW_SHARE_CONTEXT, win1 );
win2 = glfwOpenWindow( ... );

...

glfwSelectWindow( win1 );
glfwCloseWindow();
glfwSelectWindow( win2 );
glfwCloseWindow();

What I need is a way to manage the context(s) so that a context does not get destroyed until the last window that uses it is closed.

How do you manage the views? You have to reset the viewport etc every time you draw to a window then (since it's part of the context)?


One thread should look after all windows, stepping between them after each render has completed.

Sounds very reasonable - that's how I'd do it.

OneSadCookie
01-13-2003, 11:35 AM
I also use a single gl context, which I make current to each window as and when I render to them. This saves on state save/restores.

This approach is not portable -- if you remove a GL context from a window on Mac OS X you will also remove the rendered image.

Robbo
01-13-2003, 12:11 PM
Absolutely. Also, I have found that (under Windows), one thread per window works out. Sure you get a hit from the context switch and subsequent pipeline stall - but all in all, I can get more or less half the max frame-rate of one window when I have 2 (with equivalent fill-rate) etc.

I think the one thread per window is also anatomically neater as well as a little more portable.

knackered
01-13-2003, 12:23 PM
Originally posted by OneSadCookie:
This approach is not portable -- if you remove a GL context from a window on Mac OS X you will also remove the rendered image.

Remove a GL context? What do you mean? Making a GL render context NOT current to a window removes the rendered image from that window, on a Mac? Without you calling a swap? Without you being able to do anything about it in the paint message handler?
That's one hell of a limitation of that particular OS, in my opinion.


Robbo:
I think the one thread per window is also anatomically neater as well as a little more portable

And since when does something being anatomically neater become relevant in realtime graphics? Your code should be as fast as possible, not as neat as possible. Seriously, the method of one-thread-for-all-windows coupled with a single shared render context benchmarks much faster in all the tests I've done on MS Windows.
The only time coding should sacrifice small amounts of performance over useability is in the API itself, ie. the interface mechanisms to your renderer, not the internal workings of it. This isn't a beauty contest.

Robbo
01-13-2003, 01:04 PM
Yes but you have the overhead (more code) of having to manage a swap chain. In the context within which I work, I have in-process Active-X controls which run one render context on one thread. I don't have any context management to perform at all or any "overall" structural render target chain.

knackered
01-13-2003, 01:54 PM
Because it's being done for you - many times per window per frame, rather than once per window using your own 'swap chain'.

knackered
01-14-2003, 02:12 AM
another reason for a single-threaded render approach: view-dependent attributes in your nodes (such as distance from near plane, am I visible etc.)...if 2 views are being rendered at the same time, then the code to manage those attributes becomes messy itself.

marcus256
01-14-2003, 02:44 AM
So, I'm a bit confused here. http://www.opengl.org/discussion_boards/ubb/frown.gif I have some research to do, obviously.


Originally posted by OneSadCookie:
This approach is not portable -- if you remove a GL context from a window on Mac OS X you will also remove the rendered image.

Could you please check into this in more detail, Cookie?

marcus256
01-14-2003, 02:45 AM
Oh, and nobody has mentioned child windows. I would only be happy if I could exclude it from the API.

AdrianD
01-14-2003, 03:42 AM
knackered, i like your approach. i am currently working on an application with multiple viewports, and i was looking for a nice way to avoid this nasty multiple-context-state-problem. your method seems to solve this in a very nice way.
with what a system have you tested it ? win2K,XP?
works this only with nvidia drivers or does it work allways with win32?(have you tested it?)

Robbo
01-14-2003, 04:06 AM
Knackered, I think you are considering only the simplest context in which multiple windows will be used, that being where you have a kind of passive MDI and a nice little ringlet going around rendering each one when it needs an update.

In our "serious" applications, it makes more sense for each window to be a single thread and a single render context, to avoid us having to sync render\update between *all* windows whenever something changes.

Each window encapsulates the behaviour of external imaging equipment (real-time) and is easier to deal with in this way.

knackered
01-14-2003, 04:56 AM
I'm not going to rise to the bait and argue which of us does the most 'serious' applications, Robbo.

As for your assertion that my own method requires you to constantly render to all windows, well that simply ain't true. Each view has a 'dirty' flag, which is marked true when the data the view presents has changed in some way (or the viewpoint has changed), only then is the render context made current to the window the view resides in and renders to it.
I'm sure that your multithreaded approach works fine for you, but in the applications I have to write (where I could be mixing opengl with direct3d on the same desktop), my single threaded approach solves many problems.


[This message has been edited by knackered (edited 01-14-2003).]

zed
01-14-2003, 09:19 AM
dont most 'serious' http://www.opengl.org/discussion_boards/ubb/smile.gif modelling applications just use one opengl window.
eg 3dmax blender etc.
this one window is split into various regions (eg 3d view, left side view etc) with glViewPort(..)
just something to think about

OneSadCookie
01-14-2003, 12:36 PM
Remove a GL context? What do you mean? Making a GL render context NOT current to a window removes the rendered image from that window, on a Mac? Without you calling a swap? Without you being able to do anything about it in the paint message handler?

It's merely a side-effect of having a modern composited window-system.

You don't get repaint events when windows are moved or re-ordered; the window server has the image of what was in your window and handles re-compositing it appropriately.

OpenGL is in a lower-level layer even than the window system, basically the window server knows nothing about it.

If you want to keep the image in the window, you can readPixels() back and blit to the window before you remove the context.


That's one hell of a limitation of that particular OS, in my opinion.

There's nothing in any spec saying that your technique shoud work, so you're relying on undefined behavior. That's what's often known as a "hack". It's only a limitation in the sense that your particular hack doesn't work.

marcus256
01-14-2003, 10:16 PM
Hi again - thanks all for your response! Interseting what different approaches different people have taken.

Zed, I agree (single window = nice solution), but there are situations where multiple windows are preferrable. E.g.

1) You do not know beforehand how many windows you will need (e.g. scientific plots)
2) You want to have the possibility to manage each view independently (e.g. maximaize, iconify, place side-by-side etc). Especially useful when you have many views (>4).

Regarding GLFW, portability is way more important than functionality (that is why you can't change video modes in GLFW without destroying the GL context, for instance). Therefor I agree with OneSadCookie that context sharing between windows is not a good idea to support in the GLFW API.

If I'm not mistaking, one thread per window might not be a very bad idea for future applications (= applications that will be used on tomorrows hardware), since it seems like new GL accelerators will have HW support for multiple threads/contexts (e.g. the PV10 has something like that, doesn't it?). Then the context-switching overhead would be negligable, so not really an issue anymore. http://www.opengl.org/discussion_boards/ubb/smile.gif

knackered
01-15-2003, 12:03 AM
Originally posted by OneSadCookie:
There's nothing in any spec saying that your technique shoud work, so you're relying on undefined behavior. That's what's often known as a "hack". It's only a limitation in the sense that your particular hack doesn't work.

Mmm, no that is something that would be known as a "hack" on the Mac, obviously, but the spec for wglMakeCurrent on the little known "Microsoft Windows" system makes it clear that sharing render contexts between windows is perfectly legal and handled elegantly.
I'm midly interested in how the Mac handles things (I always considered Apple as the Atari of the OS world...full of good intentions and ideas, but being a bit of an anachronism) - from the way you describe the way the Mac OS handles windows (you give it a bitmap for it to display, while you render into that bitmap?) sounds pretty limiting to me - a backward step?...no clipping to overlapping windows means more rendering to do which won't even be seen, unless the occluding window is moved.
It's a good job that my renderer is designed for MS Windows only...

JustHanging
01-16-2003, 03:10 AM
Marcus, I wouldn't leave the child windows out if I was you. They are, in terms of usability, considered propably the best option for applications like modelling programs, where data is examined from several viewpoints.

Simple multiple windows totally suck at this, imagine having to minimize all your windows if you want to use another application. Sure, this can be worked around, but honestly it's a job for the window manager. The one-window solution in 3ds/blender is propably there just because their dos/unix roots. It only adds trouble to the user, since in each program the views are managed slightly differently.

I know these sound like little things, but in an actual working situation where several programs are used simultaneously such things can make an enormous difference.

-Ilkka

Robbo
01-16-2003, 03:20 AM
JustHanging, I think the issue of multiple "viewports" of the same view and multiple windows are slightly different. Obviously, with a cad program (like MAX), you would have a single window\context split into several viewports. This makes sense because they are usually displaying aspects of the same environment\model.

JustHanging
01-16-2003, 03:38 AM
As a matter of fact, on an usability course at my university, it was stated that child windows are in fact designed for showing the same data from multiple viewpoints. It was said that such applications are in practice rare, but a cad program is definitely one of them.

I agree that there's a kind of conceptual point of putting views of the same object to the same window, but then the inconsistent viewhandling issue is back again. Child windows can be thought of as viewpoints inside one window, only with a unified user interface.

-Ilkka

Robbo
01-16-2003, 03:45 AM
Well, the way I view it is like this: according to the currently dominant UI paradigm, you have multiple document interfaces - where typically you have one document per window. Microsoft changed this slightly, but opening up new instances of the app for each new document. The window then contains a document view - which, for a cad program can be full perspective or split into viewports - or configurable (as max is). But max isn't mdi - you can only work on one file at a time (at least to version 4 this was the case).

JustHanging
01-16-2003, 04:49 AM
Well, I guess we could go on with this forever, but I'm afraid I still can't agree with you.

You should never have multiple documents inside one window, mdi or not. It's just some old program centric thinking (this is my program and these are the documents inside it). Very understandable from programmers, but in general people tend to think data- or object centric. Imagine two documents on a desk, if you put the other one away, the other still stays there. That's why Microsoft opens a new window for every document.

Of course these are difficult issues which should be solved through testing, not reasoning, but in this case the guidelines seem clear to me (the famous last words of a user-interface designer). Don't let the stupid name, multi document interface, fool you.

-Ilkka

pkaler
01-16-2003, 11:50 AM
I'm gonna have to disagree with JustHanging. The tabbed MDI interfaces of Mozilla and Opera are much better than IE's interface. I switched my sisters over to Mozilla and they can't live without the MDI now (not to mention mouse gestures).

The problem with MDI in the past was that it was implemented poorly. The tabbed interface makes it blatantly obvious that there is more than one document open. Blatantly obvious is good. In the past you would have to do a bunch of tom-foolery with menus to switch between MDI documents.

When I have friends over they ask, "Do you have the internet? I want to check my webmail." Of course I don't "have the internet". I have a connection to the internet. Rather than being pedantic, I open up Mozilla for them. To most users, the browser is the internet. And each tab is some page/site on the internet. With IE, my dad never really uses more than one browser window. How can you have more than 1 internet? That's impossible.

So it is not really "old program centric thinking". It's that users are used to the Windows way. Which is unfortunate, because they have made it easy for the user to get up and going, but very difficult for them to learn to become efficient and multitask.

OneSadCookie
01-16-2003, 12:00 PM
]Mmm, no that is something that would be known as a "hack" on the Mac, obviously, but the spec for wglMakeCurrent on the little known "Microsoft Windows" system makes it clear that sharing render contexts between windows is perfectly legal and handled elegantly.

My apologies http://www.opengl.org/discussion_boards/ubb/frown.gif


from the way you describe the way the Mac OS handles windows (you give it a bitmap for it to display, while you render into that bitmap?) sounds pretty limiting to me - a backward step?...no clipping to overlapping windows means more rendering to do which won't even be seen, unless the occluding window is moved.

Possibly less rendering, actually, since moving windows requires no extra rendering on the part of the application. It also allows for things like true transparency in windows, since the window server has all the necessary information to recomposite, without requiring the application to re-render. It also means that the compositing step can be handled on the graphics card, which would otherwise be idle most of the time.


It's a good job that my renderer is designed for MS Windows only...

Sounds like it http://www.opengl.org/discussion_boards/ubb/wink.gif

Robbo
01-16-2003, 12:55 PM
Originally posted by PK:

The problem with MDI in the past was that it was implemented poorly. The tabbed interface makes it blatantly obvious that there is more than one document open. Blatantly obvious is good. In the past you would have to do a bunch of tom-foolery with menus to switch between MDI documents.


Absolutely and Microsoft is now moving back towards tabbed MDI, check out studio 7 for example.

marcus256
01-16-2003, 10:40 PM
Originally posted by JustHanging:
Marcus, I wouldn't leave the child windows out if I was you. They are, in terms of usability, considered propably the best option for applications like modelling programs, where data is examined from several viewpoints.

I see your point, but then I'm facing this problem:

GLFW is a multi-platform API. If I expose "child windows" through the API, I need to decide between A) Use the platform specific child window paradigm (which isn't even defined for some platforms), and B) Make a strict and platform independent definition of what a child window is, and implement it exactly the same way for all platforms.

To me, B) is the most appealing solutions. Not only is it a stronger API specification, it also means that the GLFW user knows exactly what behaviour to expect from his program, regardless of which platform it is running on.

So, should it be A or B? If B, what should the exact specification of a child window be?

knackered
01-17-2003, 12:32 AM
Originally posted by OneSadCookie:
Possibly less rendering, actually, since moving windows requires no extra rendering on the part of the application. It also allows for things like true transparency in windows, since the window server has all the necessary information to recomposite, without requiring the application to re-render. It also means that the compositing step can be handled on the graphics card, which would otherwise be idle most of the time

Sounds good - when will MS Windows be changing over to this method? I wouldn't have thought it would be difficult to change to this way of doing things, even keeping the existing paint handling messages, etc.
I'm being practical, Macs are not practical in the simulation market.

JustHanging
01-17-2003, 04:14 AM
Yeah, you might be right. Take my words as coming from an educated kid with no real experience. I still think the way things should be handled, in general, is to have the documents (models, texts, whatever) there, and when you open a document, around it are the tools to manipulate it. That is, a program. And all documents should be handled independently of each other. Web browsers don't really fit in this analogy, since there isn't much to manipulate.

As for Marcus' question, I really don't know. It depends on how big the differences are between different systems. But since you have to do some default thing for systems that don't support child windows, I guess you might as well go with B. Altough it would stink to have non-windows type windows in a windows enviroment. On the other hand, programmers propably prefer B, and they are your target audience...

Child windows are windows that belong to the client area of the parent window, but I don't know if it's a sufficent definition.

-Ilkka

JustHanging
01-18-2003, 08:45 AM
I guess this is where we get to the nutpicking, but I have to add...

Having given PK:s example some more thought, if there's only one internet like PK says, then the different pages can be seen as different views of it. In that sense Mozilla uses MDI exactly the way I said it should be used. Apparently your sisters have proven this a good solution.

Anyway, sorry for being a pain in the ass, I just can't help myself. I find usability very interesting, almost as interesting as graphics. I'm gonna go now, have a nice weekend.

-Ilkka