Multiple render roots

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

Ivorne
Just popping in
Just popping in
Posts: 7
Joined: Tue Nov 12, 2013 11:05

Multiple render roots

Postby Ivorne » Tue Nov 12, 2013 11:17

Hello,

I am using freeglut and I want to be able to render GUI to two windows at the same time. Freeglut creates individual OpenGL context for each window. I would like to know, how to initialise CEGUI to do this.

Single window initialization:

Code: Select all

CEGUI::OpenGLRendererBase * renderer = &CEGUI::OpenGLRenderer::create();
CEGUI::System::create( *renderer );
/* ResourceProvider init */
.
.
.
/*-----*/

CEGUI::GUIContext * guiContext = new CEGUI::GUIContext( renderer->getDefaultRenderTarget() );
CEGUI::Window * myRoot = CEGUI::WindowManager::getSingleton().loadLayoutFromFile( filename );
guiContext->setRootWindow( myRoot  );


And single window render:

Code: Select all

renderer->beginRendering();
guiContext->draw();
renderer->endRendering();


Now, if I want to draw two GUIs to two OpenGL contexts, I have to create two GUIContexts and give each its own RenderTarget. So I will have to create two Renderers but system can be initialised only once using only one Renderer. I don't know, how to solve this.

Thank you.

User avatar
mmixLinus
Quite a regular
Quite a regular
Posts: 71
Joined: Fri May 20, 2011 08:46
Location: Lund, Sweden
Contact:

Re: Multiple render roots

Postby mmixLinus » Wed Nov 13, 2013 08:28

Sorry, I can't help you, but PLEASE post your solution once you find it!
Maybe this, this or this can help.

Thanks!
/mmixLinus
MMiX.Me 3D Music Player
Galaxy Navigator 3D - 2 million stars (ESA's Gaia satellite)
(YouTube|Facebook)

addictgamer
Just popping in
Just popping in
Posts: 10
Joined: Wed Oct 30, 2013 16:46

Re: Multiple render roots

Postby addictgamer » Wed Nov 13, 2013 18:23

Ivorne wrote:Now, if I want to draw two GUIs to two OpenGL contexts, I have to create two GUIContexts and give each its own RenderTarget. So I will have to create two Renderers but system can be initialised only once using only one Renderer. I don't know, how to solve this.


The same way you created the renderer for your first context -- just ignore the system initialization:

Code: Select all

CEGUI::OpenGLRendererBase *second_renderer = &CEGUI::OpenGLRenderer::create();
CEGUI::GUIContext *second_cegui_gui_context = &CEGUI::System::getSingleton().createGUIContext(second_renderer->getDefaultRenderTarget());

Ivorne
Just popping in
Just popping in
Posts: 7
Joined: Tue Nov 12, 2013 11:05

Re: Multiple render roots

Postby Ivorne » Thu Nov 14, 2013 19:59

This does not work good. Problem: initialisation of CEGUI::System requires reference to Renderer. Should I just give it just some random Renderer? When I want to render GUIContext, I do it like this:

Code: Select all

renderer->beginRendering();
guiContext->draw();
renderer->endRendering();


Which renderer should beginRendering? The one that initialises System or the one created for that particular GUIContext?

Every of these alternatives gives me poor results. One window is drawing something but textures are obviously damaged and the second window is totaly blank.

I have red the docs carefuly, so if you are just guessing from docs how it should be, you will probably not help me. If you made it work, please post larger snippet or your code.

I would realy love to solve this.

Thank you.

addictgamer
Just popping in
Just popping in
Posts: 10
Joined: Wed Oct 30, 2013 16:46

Re: Multiple render roots

Postby addictgamer » Fri Nov 15, 2013 06:32

Ivorne wrote:This does not work good. Problem: initialisation of CEGUI::System requires reference to Renderer. Should I just give it just some random Renderer? When I want to render GUIContext, I do it like this:

I give it the render of the first GUI context you want to create.
After that, I create the second, third, and so on GUI contexts and their renderers, the way I demonstrated in my previous post.

Ivorne wrote:

Code: Select all

renderer->beginRendering();
guiContext->draw();
renderer->endRendering();


Which renderer should beginRendering? The one that initialises System or the one created for that particular GUIContext?

You have to do that for every GUI context you want to render.

Example snippet from my code:

Code: Select all

renderMyProgram()
{
   ... //Render stuff here.

   for (std::vector<GUIContext_wrapper* >::iterator iter = contexts.begin(); iter != contexts.end(); ++iter)
   {
      //TODO: Set your OpenGL viewport to the viewport you want this GUI context drawn to.

      (*iter)->cegui_renderer->beginRendering();
      (*iter)->cegui_gui_context->draw();
      (*iter)->cegui_renderer->endRendering();
   }

   ...
}

where GUIContext_wrapper is just a class I use to wrap around the CEGUI context and store some variables I need in other code. Visual illustration for posterity's sake:

Code: Select all

class GUIContext_wrapper
{
   ...
   CEGUI::GUIContext *cegui_context;
   ...
};

Ivorne
Just popping in
Just popping in
Posts: 7
Joined: Tue Nov 12, 2013 11:05

Re: Multiple render roots

Postby Ivorne » Fri Nov 15, 2013 18:16

Thank you. I did it similar to as you said. I created one renderer for system initialization, and then i created two GUIContexts - each with it's own new renderer in its own window with own opengl context. It does not work at all.

The second created window is permanently black and part of the first window is black. The bottom two thirds of first window are ok.

I use OpenGL Renderer (not the one for GLv3). Which renderer do you use? Could this be the problem? I am slowly giving up. I will probably have to find another solution.

addictgamer
Just popping in
Just popping in
Posts: 10
Joined: Wed Oct 30, 2013 16:46

Re: Multiple render roots

Postby addictgamer » Fri Nov 15, 2013 21:41

Ivorne wrote:Thank you. I did it similar to as you said. I created one renderer for system initialization, and then i created two GUIContexts - each with it's own new renderer in its own window with own opengl context. It does not work at all.

The second created window is permanently black and part of the first window is black. The bottom two thirds of first window are ok.

I use OpenGL Renderer (not the one for GLv3). Which renderer do you use? Could this be the problem? I am slowly giving up. I will probably have to find another solution.

I also use am using OpenGL Renderer.

I don't know why you're getting those issues. Are you sure the right OpenGL viewport is active when you're telling each GUI Context to render?

Ya, I don't have any other ideas, sorry. Code works just fine for me.
An idea that might help you further debug this, you could try replacing:

Code: Select all

      //TODO: Set the active OpenGL viewport to the one you want to render to.
      (*iter)->cegui_renderer->beginRendering();
      (*iter)->cegui_gui_context->draw();
      (*iter)->cegui_renderer->endRendering();

for both GUI Contexts with some OpenGL calls to render some primitives:

Code: Select all

      //TODO: Set the active OpenGL viewport to the one you want to render to.
      glBegin(GL_TRIANGLES);
               glVertex3f(  0.0f,  1.0f, 0.0f );
               glVertex3f( -1.0f, -1.0f, 0.0f );
               glVertex3f(  1.0f, -1.0f, 0.0f );
      glEnd( );

You should see a white triangle in both windows if you're doing everything right. If you do see the triangles, that means that something's probably wrong with your CEGUI related code.
If you don't see the triangles, then something's probably wrong with your Freeglut or OpenGL code.


Otherwise, I'm sorry, I don't think I can help you any more. I showed you what code I use, it works just fine for me, went through possible problems that popped into my head...well, hope this helps.

Ivorne
Just popping in
Just popping in
Posts: 7
Joined: Tue Nov 12, 2013 11:05

Re: Multiple render roots

Postby Ivorne » Fri Nov 15, 2013 21:50

I tried it now and there are triangles. I have writen code, that alows me to have two windows with CEGUI but only one will render at the time and I can switch between them (during runtime). So my problem will not be in wrong usage of opengl.

I use Linux and my graphics driver (fglrx for ATI) is quite bugy. So it could be platform specific problem in CEGUI renderer.

Ivorne
Just popping in
Just popping in
Posts: 7
Joined: Tue Nov 12, 2013 11:05

Re: Multiple render roots

Postby Ivorne » Fri Nov 15, 2013 22:06

I which opengl context do you initializes renderers and GUIContexts? Do initialize each renderer and GUIContext in that opengl context in which I want to render them. The renderer passed to System::init() is created in first created opengl context.

addictgamer
Just popping in
Just popping in
Posts: 10
Joined: Wed Oct 30, 2013 16:46

Re: Multiple render roots

Postby addictgamer » Sat Nov 16, 2013 00:26

Ivorne wrote:I which opengl context do you initializes renderers and GUIContexts? Do initialize each renderer and GUIContext in that opengl context in which I want to render them.



Hmm, now that you mention it, whenever I create a Renderer and a GUI context, I first set the active OpenGL context to the one I want them to render to. Maybe doing that will work for you?

Ivorne
Just popping in
Just popping in
Posts: 7
Joined: Tue Nov 12, 2013 11:05

Re: Multiple render roots

Postby Ivorne » Sat Nov 16, 2013 11:39

addictgamer wrote:
Ivorne wrote:I which opengl context do you initializes renderers and GUIContexts? Do initialize each renderer and GUIContext in that opengl context in which I want to render them.



Hmm, now that you mention it, whenever I create a Renderer and a GUI context, I first set the active OpenGL context to the one I want them to render to. Maybe doing that will work for you?



Sorry, I wrote that message yesterday in 2 am and now I see that it is not readable much. I wanted to say, that I already do initialize each renderer and GUI context in opengl context in which i want to render them. So apparently that is not the problem either.

Thank you for your help, I will suspend my search for the solution for later as I do not think I can solve it now. Thanks again and have a nice day.

User avatar
Ident
CEGUI Team
Posts: 1995
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Multiple render roots

Postby Ident » Sat Nov 16, 2013 19:36

The problem is that each OpenGL context will have its own textures fbos vbos etc etc etc. All of these are by default not accessible from the other context.

In CEGUI the windows etc will have vbo's storing the vertices and the fonts and textures are stored in atlases.

addictgamer gave good feedback regarding GUIContexts. While this approach would be principially of good use here, it will still not work for different OpenGL contexts, because the vbos, textures, fbos are stored in different OpenGL contexts. Each OpenGL context only has access to its own data. But: there IS the possibility to share data between them if you EXPLICITLY define it that way. If you want to do this, we could look into that together. I have no experience with shared OpenGL contexts though. Another possibility is to have 1 OpenGL contexts with multiple windows, which is the absolutely favorable solution. However, i dont know if freeglut can do it. I also dont know if freeglut can do shared stuff.
CrazyEddie: "I don't like GUIs"

Ivorne
Just popping in
Just popping in
Posts: 7
Joined: Tue Nov 12, 2013 11:05

Re: Multiple render roots

Postby Ivorne » Sat Nov 16, 2013 20:33

Ident wrote:The problem is that each OpenGL context will have its own textures fbos vbos etc etc etc. All of these are by default not accessible from the other context.

In CEGUI the windows etc will have vbo's storing the vertices and the fonts and textures are stored in atlases.

addictgamer gave good feedback regarding GUIContexts. While this approach would be principially of good use here, it will still not work for different OpenGL contexts, because the vbos, textures, fbos are stored in different OpenGL contexts. Each OpenGL context only has access to its own data. But: there IS the possibility to share data between them if you EXPLICITLY define it that way. If you want to do this, we could look into that together. I have no experience with shared OpenGL contexts though. Another possibility is to have 1 OpenGL contexts with multiple windows, which is the absolutely favorable solution. However, i dont know if freeglut can do it. I also dont know if freeglut can do shared stuff.


Thank you. I think that having one opengl context for whole application would be generaly better solution.

HA! I just looked through freeglut API and it should be possible to share opengl context between windows( glutSetOption ( GLUT_RENDERING_CONTEXT, GLUT_USE_CURRENT_CONTEXT ) ). There occures another problem - closing and reopening window causes losing the context. I will probably solve this somehow.

So thank you, this could solve my problems. I would still prefer to be able to display cegui in different contexts, but now I think that I will probably use that single opengl context.

Maybe I will switch from freeglut to GLFW. I will do it probably at least in my next project.

Thank you both again for advices.

User avatar
Ident
CEGUI Team
Posts: 1995
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Multiple render roots

Postby Ident » Sun Nov 17, 2013 13:12

Ivorne wrote:So thank you, this could solve my problems. I would still prefer to be able to display cegui in different contexts, but now I think that I will probably use that single opengl context.

Maybe I will switch from freeglut to GLFW. I will do it probably at least in my next project.


In OpenGL it is simply not possible to have different contexts and access the data of one context from another context, WITHOUT doing extra work. If you really want to have two contexts, you need to set up shared contexts (afaik GLFW supports this in some MX version or so). I have no experience with shared contexts so I do not know if that will work straight out of the box. Either way, the underlying issue is that CEGUI will create all the data for the OpenGL context you initialise it with. So the problem is not a lacking feature of CEGUI, but the way that OpenGL is setup. With shared contexts, including some extra work, it should theoretically definitely work. With a single context and multi-windows it should work even easilier, all you need to do here is to check that you render the respective CEGUI GUIContext into the right window each time.

Also I can recommend you GLFW. I use it myself in my projects and have used freeglut, openglut and some other similar library before and had the best overall experience when using glfw. Also it is still developed quite actively.
CrazyEddie: "I don't like GUIs"


Return to “Help”

Who is online

Users browsing this forum: No registered users and 25 guests