Best way to render on two separate windows/graphics contexts

For help with anything that CEGUI doesn't offer straight out-of-the-box, e.g.:
- Implementation of new features, such as new Core classes, widgets, WindowRenderers, etc. ...
- Modification of any existing features for specific purposes
- Integration of CEGUI in new engines or frameworks and writing of new plugins (Renderer, Parser, ...) or modules

Moderators: CEGUI MVP, CEGUI Team

HorizonDefeated
Just popping in
Just popping in
Posts: 19
Joined: Tue Feb 16, 2010 00:17

Best way to render on two separate windows/graphics contexts

Postby HorizonDefeated » Mon May 16, 2011 23:59

Hello.

I'm investigating the best way to modify our app. It currently has one application window (top level window). All CEGUI widgets/windows render on that context and everything is happy. We are now required to have two top-level windows / graphics contexts and move a few of the CEGUI widgets/windows over to that other window. Ideally this other window would dynamically come into or out of existence while the program is running.

Does anyone have any tips on the best way to accomplish this? I though maybe I could call setGUISheet to one value, render, setGUISheet to another value, render. Seems kind of clunky though, and when I want move the widgets between app windows I would have to remove and add them...

Render to Texture (RTT)? If I do I will have to do a copy because they are in different graphics contexts...

Thoughts?

Thanks

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: Best way to render on two separate windows/graphics cont

Postby Kulik » Tue May 17, 2011 01:15

You have encountered a limitation of CEGUI, I believe CrazyEddie said in the past that this is doable but requires custom code, I don't know the details unfortunately (perhaps searching through the forum might surface some solution).

0.8 has multi root rendering planned so that should allow much comfier multi window rendering. renderGUI will go away in 0.8 and you will simply have 1 or more RenderingRoots.

My idea of how to solve this:
In the meantime I believe setting up 2 separate OpenGL contexts (you are using OpenGL, right?) to share texture data (this is platform specific but IIRC supported on all major platforms) and using RTT is the preferred way. You basically set up 2 default windows, enable "AutoRenderingSurface" on both and then use their RTT surfaces and render them on 2 separate quads on both windows. This way you have most control and it should be pretty fast as well.

What is the minimum hardware your software has to run on? If FBO is assured to be supported, this is IMO a good way to go.

HorizonDefeated
Just popping in
Just popping in
Posts: 19
Joined: Tue Feb 16, 2010 00:17

Re: Best way to render on two separate windows/graphics cont

Postby HorizonDefeated » Tue May 17, 2011 17:54

Thanks Kulik.

I briefly tried a search through the forums but I must not have hit upon the right keywords to find anything useful.

We are using OpenGL. We have run on some older hardware that doesn't support FBO. I suspect we could make an arbitrary decision to require FBO support...

I'll look at how to share textures between contexts so as not to require a copy.

HorizonDefeated
Just popping in
Just popping in
Posts: 19
Joined: Tue Feb 16, 2010 00:17

Re: Best way to render on two separate windows/graphics cont

Postby HorizonDefeated » Thu May 19, 2011 16:52

Kulik et al

I see how I can set Windows to have the property AutoRenderingSurface and how I could possibly directly access the texture via TextureTarget. I'm unsure on still on how I would get CEGUI to render on two different contexts. I have tried changing setmainsheet in between renders of the different contexts and that seems to work but I fear it's expensive.

Were you suggesting using CEGUI to render to texture and then just using OpenGL to display a textured quad (rather than CEGUI reusing a texture that it generated?).

Thanks

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: Best way to render on two separate windows/graphics cont

Postby Kulik » Sat May 21, 2011 12:46

I am doing this in python but I believe this might help you as an example code.

http://crayzedsgui.hg.sourceforge.net/hgweb/crayzedsgui/CEED/file/be1cad8b3afb/cegui/__init__.py#l780

Basically rendering just one widget (it could have subwidgets of course).

HorizonDefeated
Just popping in
Just popping in
Posts: 19
Joined: Tue Feb 16, 2010 00:17

Re: Best way to render on two separate windows/graphics cont

Postby HorizonDefeated » Tue May 24, 2011 16:13

Thanks Kulik.

Another follow-up question. I have the CEGUI widget/window rendering to texture and I am able to display it on a quad in the other context. Now how do I map events (mouse, etc) back into the CEGUI system?? Is there any way to direct an event at a particular Window, or do I need to apply some hack where I map screen space from my widget in screen 2 to coordinates in screen 1??

Thanks

Jamarr
CEGUI MVP
CEGUI MVP
Posts: 812
Joined: Tue Jun 03, 2008 23:59
Location: USA

Re: Best way to render on two separate windows/graphics cont

Postby Jamarr » Tue May 24, 2011 23:58

Another follow-up question. I have the CEGUI widget/window rendering to texture and I am able to display it on a quad in the other context. Now how do I map events (mouse, etc) back into the CEGUI system??


CEGUI's input system uses simple bounds checking against the window geometry and the mouse-input coordinates (assuming same coordinate system) to determine if the mouse event affects the GUI. You can see this by looking at the code for the System::inject* methods. Since CEGUI is still based on the idea of a single rendering context it has no built in knowledge a second context / screen-space and thus no means of translating between them. On a slight tangent, if CEGUI supported multiple contexts natively it would not need a translation method since then you would not need the RTT work-around ;)

Is there any way to direct an event at a particular Window


You can create/fire events from any window, but you are responsible for filling out and providing a contextually-valid EventArgs object. And in this particular case, in order to determine which window the event should fire upon you would still have to translate the screen coordinates from the second context, making this approach pointless as then you could simply inject the input into CEGUI normally and avoid rewriting CEGUI's input-management :)

, or do I need to apply some hack where I map screen space from my widget in screen 2 to coordinates in screen 1??


I would hardly call this a hack, more an external extension to provide non-native support for multiple non-uniform screen spaces :) Normally most dual-contexts use uniform screen dimensions and so no coordinate-translation is necessary, but in this case it sounds like you will need to provide this since your original post hints at non-uniformity and only your code knows about this second context ;)
If somebody helps you by replying to your thread, upvote him/her as a thanks! Make sure to include your CEGUI.log and everything you tried when posting! And remember that we are not magicians!

HorizonDefeated
Just popping in
Just popping in
Posts: 19
Joined: Tue Feb 16, 2010 00:17

Re: Best way to render on two separate windows/graphics cont

Postby HorizonDefeated » Wed May 25, 2011 20:26

One more thing.

I have now setup several RTTs via AutoRenderingSurface. However, how do I make it so that the top level GUI doesn't render to the front buffer (visible screen)? I assume there is some setting so that the OpenGL render just renders to texture and never tries to present that texture to visible graphics memory-- letting the user handle that part?

Thanks

Jamarr
CEGUI MVP
CEGUI MVP
Posts: 812
Joined: Tue Jun 03, 2008 23:59
Location: USA

Re: Best way to render on two separate windows/graphics cont

Postby Jamarr » Wed May 25, 2011 23:03

HorizonDefeated wrote:I have now setup several RTTs via AutoRenderingSurface. However, how do I make it so that the top level GUI doesn't render to the front buffer (visible screen)? I assume there is some setting so that the OpenGL render just renders to texture and never tries to present that texture to visible graphics memory-- letting the user handle that part?


Note that I have not upgraded to v0.7 yet so this may wrong. The default RenderTarget ("whatever buffer is active"? typically the front-buffer) for the default RenderingSurface (viewport in current context?) is set when you initialize CEGUI. Typically this will be in the call to bootstrapSystem or when you directly create the Renderer object. You should be able to change the RenderTarget to a texture/fbo target by specifying the target-type when initializing CEGUI. Then when you call System::RenderGUI() it will render to the specified texture (fbo) instead of the front buffer. The RenderTarget object should? provide a means of retrieving the texture/id, at which point you can manually texture a quad in the relevant context.

Alternatively, since the default target/surface does not (i think?) enforce a specific (front/back/etc.) buffer when CEGUI::System::RenderGUI is called. So you may be able to manually change the opengl render target prior to calling RenderGUI (restoring the original target afterwards), and then use that manually created texture/fbo target to texture a quad in the relevant context.
If somebody helps you by replying to your thread, upvote him/her as a thanks! Make sure to include your CEGUI.log and everything you tried when posting! And remember that we are not magicians!


Return to “Modifications / Integrations / Customisations”

Who is online

Users browsing this forum: No registered users and 12 guests