Ogre 2.0 + multiple windows = fail

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

Suslik
Just popping in
Just popping in
Posts: 10
Joined: Sun Feb 01, 2015 10:37

Ogre 2.0 + multiple windows = fail

Postby Suslik » Sun Feb 01, 2015 10:55

I need to make 2 ogre windows and CEGUI stuff in each of them. I'm using CEGUI default branch that seems to support ogre 2.0 and ogre 2.0 from the repo that I've built for windows.

My code to create windows and initialize CEGUI looks like this:

Code: Select all

  Ogre::RenderWindow *window = root->createRenderWindow("Awesome window", 800, 600, false);
  Ogre::RenderWindow *window2 = root->createRenderWindow("Awesome window 2!", 800, 600, false);

  Ogre::SceneManager* sceneManager =  root->createSceneManager(Ogre::ST_EXTERIOR_CLOSE, /*"DefaultSceneManager", */8, Ogre::INSTANCING_CULLING_THREADED);
  Ogre::SceneManager* sceneManager2 = root->createSceneManager(Ogre::ST_EXTERIOR_CLOSE, /*"DefaultSceneManager", */8, Ogre::INSTANCING_CULLING_THREADED);

  Ogre::CompositorManager2 *compositorManager = root->getCompositorManager2();

  const Ogre::IdString workspaceName("Awesome workspace1");
  compositorManager->createBasicWorkspaceDef( workspaceName, Ogre::ColourValue(0.5f, 0.5f, 0.5f, 0.5f), Ogre::IdString());
  compositorManager->addWorkspace( sceneManager, window, camera, workspaceName, true );

  Ogre::Viewport* viewport = window->getViewport(0);
  camera->setAspectRatio(Ogre::Real(viewport->getActualWidth()) / Ogre::Real(viewport->getActualHeight()));

  /*const Ogre::IdString workspaceName2("Awesome workspace2");
  compositorManager->createBasicWorkspaceDef( workspaceName2, Ogre::ColourValue(0.5f, 0.5f, 0.5f, 0.5f), Ogre::IdString());
  compositorManager->addWorkspace( sceneManager2, window2, camera2, workspaceName2, true );

  Ogre::Viewport* viewport2 = window2->getViewport(0);
  camera2->setAspectRatio(Ogre::Real(viewport2->getActualWidth()) / Ogre::Real(viewport2->getActualHeight()));*/

  ceguiOgreRenderer = &CEGUI::OgreRenderer::create(*window);
  ceguiOgreRenderer->setDefaultRootRenderTarget(*window);

  &CEGUI::System::create(*ceguiOgreRenderer, new CEGUI::OgreResourceProvider(), 0, new CEGUI::OgreImageCodec());
  /*setting up CEGUI resources*/
  CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
  CEGUI::Window *sheet = wmgr.createWindow("DefaultWindow");
 
  CEGUI::RenderTarget *target = new CEGUI::OgreWindowTarget(*ceguiOgreRenderer, *root->getRenderSystem(), *window);
  CEGUI::GUIContext *guiContext = &CEGUI::System::getSingleton().createGUIContext(*target);
  //CEGUI::GUIContext *guiContext = &CEGUI::System::getSingleton().getDefaultGUIContext();
  guiContext->setRootWindow(sheet);

  frameListener->setGuiContext(guiContext);
  root->addFrameListener(frameListener);

  ceguiOgreRenderer->setRenderingEnabled(false);

Now frame listener's code:

Code: Select all

    CEGUI::System& gui_system(CEGUI::System::getSingleton());

    float dt = 1e-2f;
    gui_system.injectTimePulse(dt);
    //d_sampleApp->update(static_cast<float>(elapsed));

    //beginRendering(elapsed);

    CEGUI::Renderer* gui_renderer(gui_system.getRenderer());
    gui_renderer->beginRendering();
    //d_sampleApp->renderGUIContexts();
    guiContext->injectTimePulse(1e-2f);
    guiContext->draw();

    gui_renderer->endRendering();
    CEGUI::WindowManager::getSingleton().cleanDeadPool();

This code creates 2 windows and attaches CEGUI context to the first one. It works fine: there's 2 ogre windows and CEGUI button inside the first one.
However, if I uncomment commented code that creates a workspace for the second window, CEGUI in the first one gets borked: I get white rectangles instead of symbols in the fonts.

And if I init CEGUI for the second window as well, it renders perfectly well while the first window remains borked:
Image

Here's full code of my problematic code(with syntax highligting for easier reading): http://pastebin.com/mTvUSuMZ
It's a double-post from ogre's forums http://www.ogre3d.org/forums/viewtopic.php?f=25&t=82696 but no one managed to help me with this one. Hopefully you guys can help.

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

Re: Ogre 2.0 + multiple windows = fail

Postby Ident » Sun Feb 01, 2015 12:31

Regarding your setup: Which Renderer of Ogre do you use?

From what I can see in your screenshot, the issue should be blending. I am actually surprised it works so "well" at all, because I doubt anyone tested it yet. I mean: you can see the widget and the texture on it and those parts are rendered correctly, that is already great. My bets are that the blend states/ alpha blending is set wrong. Since this issue appears only in one window it must be some per-context state. You could try to look into the CEGUI OgreRenderer to check how blending is defined and see if there is some obvious reason it would not work in multi-window setups.


Lastly I wanna add that Ogre 2.0 is not released and neither is CEGUI default, so both are potentially buggy. The changes that made CEGUI compatible to Ogre 2.0 were contributed by a user, you might want to ask the user if he knows more about the issue (I assume the multi-window feature was never tested by him/her) or you look into it yourself and try to commit a pull request to default branch so we can maintain your changes. The user who did the most changes to the default-branch Ogre Renderer was "Henri Hyyryläinen", I think David Reepmayer also did some changes, you could try to contact these users (bitbucket/cegui forum/...) they might some more ideas on this.
CrazyEddie: "I don't like GUIs"

Suslik
Just popping in
Just popping in
Posts: 10
Joined: Sun Feb 01, 2015 10:37

Re: Ogre 2.0 + multiple windows = fail

Postby Suslik » Sun Feb 01, 2015 20:26

It was silly of me to forget mentioning that I use OpenGL Ogre renderer. I have just checked dx renderer and it turned out that instead of borking UI in the first window, creating the second workspace throws an exception on this line in OgreD3D9RenderSystem.cpp:

Code: Select all

    void D3D9RenderSystem::_beginFrame()
    {
        HRESULT hr;
        if( FAILED( hr = getActiveD3D9Device()->BeginScene() ) )
        {
            String msg = DXGetErrorDescription(hr);
            /*next line drops exception with msg = "Invalid call"*/
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error beginning frame :" + msg, "D3D9RenderSystem::_beginFrame" );
        }

        mLastVertexSourceCount = 0;
    }

And I know that neither ogre 2.0 nor corresponding CEGUI are released yet. But Ogre 2.0 gives me a very signifificant performance boost "for free" so I cannot give it up in favor of 1.9 that's officially supported. But I think I can contribute some tests and development when I'm more familiar with their sources.

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

Re: Ogre 2.0 + multiple windows = fail

Postby Ident » Sun Feb 01, 2015 21:54

Suslik wrote:And I know that neither ogre 2.0 nor corresponding CEGUI are released yet. But Ogre 2.0 gives me a very signifificant performance boost "for free" so I cannot give it up in favor of 1.9 that's officially supported. But I think I can contribute some tests and development when I'm more familiar with their sources.


I am confident that you can do that, if you feel confident about it as well ;) . We will also review you any changes you will provide us with (pull requests preferred!) and give you some guidance where needed. So feel free to make a pull request any tim: you will find more info on our bitbucket page about this, if you are not familiar with bitbucket PRs.

Overall, the Renderers of CEGUI are relatively easy to understand (and therefore also to modify), as compared to a lot of other aspects of the CEGUI library. Also, I worked a lot on the Rendering classes, changing abstractions, behavior etc, in the past years and I believe I made some things easier than they were before and also streamlined a lot of things across the renderers, removing unnecessarily copied code and simplifying rendering. However, I had to make the shader stuff more complicated to prepare the Renderers for more advanced rendering tasks as needed for custom rendering / SVG rendering. In any case, the current 2.0 support is entirely user-contributed, which really shows that users can contribute a lot to the development.
CrazyEddie: "I don't like GUIs"

Suslik
Just popping in
Just popping in
Posts: 10
Joined: Sun Feb 01, 2015 10:37

Re: Ogre 2.0 + multiple windows = fail

Postby Suslik » Mon Feb 02, 2015 11:24

Well that's underwhelming. I've just tested Ogre 1.9 + CEGUI 0.8.4. Both of them are actually released already but I'm getting very similar(though reversed) results with opengl renderer:
Image
By reversed I mean that the second windows in ogre 1.9 gets borked instead of the first with ogre 2.0 OpenGL renderer. With 1.9 D3D9 renderer though it seems to work fine(both windows render correctly).

Suslik
Just popping in
Just popping in
Posts: 10
Joined: Sun Feb 01, 2015 10:37

Re: Ogre 2.0 + multiple windows = fail

Postby Suslik » Mon Feb 02, 2015 11:55

Ok I managed to get the thing working on ogre 1.9 OpenGL/D3D9 renderer and ogre 2.0 OpenGL renderer. Ogre 2.0 D3D9 renderer still throws an exception on BeginFrame(). The fix was suggested in this thread: viewtopic.php?f=10&t=6831&start=15 and looks like this in my code:

Code: Select all

class FrameListener : public Ogre::FrameListener
{
public:
  bool frameStarted(const Ogre::FrameEvent& evt)
  {
    return true;
  }
  bool frameEnded(const Ogre::FrameEvent& evt)
  {
    return true;
  }

  bool frameRenderingQueued(const Ogre::FrameEvent& args)
  {
    CEGUI::System& gui_system(CEGUI::System::getSingleton());

    float dt = 1e-2f;
    gui_system.injectTimePulse(dt);

    ogreRenderer->initialiseRenderStateSettings(); //this line actually
    ogreRenderer->beginRendering();
    guiContext->injectTimePulse(1e-2f);
    guiContext->draw();

    ogreRenderer->endRendering();
    CEGUI::WindowManager::getSingleton().cleanDeadPool();

    return true;
  }
  void init(CEGUI::GUIContext *guiContext, CEGUI::OgreRenderer *ogreRenderer)
  {
    this->guiContext = guiContext;
    this->ogreRenderer = ogreRenderer;
  }
private:
  CEGUI::GUIContext *guiContext;
  CEGUI::OgreRenderer *ogreRenderer;
};

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

Re: Ogre 2.0 + multiple windows = fail

Postby Ident » Mon Feb 02, 2015 12:59

Good job. The fact that 1.9 +0.8.4 doesnt support multi-window is indeed underwhelming ): . The fix looks good, could you make a pull request for it for repository branch v0-8 so it can be in our next 0.8.X release?

Any idea why the D3D9 Renderer still doesn't work correctly?
CrazyEddie: "I don't like GUIs"

Suslik
Just popping in
Just popping in
Posts: 10
Joined: Sun Feb 01, 2015 10:37

Re: Ogre 2.0 + multiple windows = fail

Postby Suslik » Mon Feb 02, 2015 13:35

The workaround I provided is 100% on user-side. Just add state reset to user's frame listener. I'm not sure if it's safe to add it to ogre renderer itself.

Just to clarify again what it does:
It makes multi-windowed rendering work on ogre1.9+cegui0.8.4 for both ogl and d3d9 renderer and ogre2.0+cegui def for ogl only. Ogre2.0+cegui def with d3d9 renderer is still broken for me.
Last edited by Suslik on Mon Feb 02, 2015 13:40, edited 1 time in total.

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

Re: Ogre 2.0 + multiple windows = fail

Postby Ident » Mon Feb 02, 2015 13:39

Ah so it is not a change to the OgreRenderer. I assume there is not much we can do in that case except maybe make a standalone demo that show how ogre works with multiwindows. Or an addition to doxygen docu / or a new wiki page might do. If you wanna create wiki page - u can use your forum account. We dont yet have a standalone setup for Ogre yet in our repo, only glfw and sdl as far as I remember, so this option would take some effort.
CrazyEddie: "I don't like GUIs"

Suslik
Just popping in
Just popping in
Posts: 10
Joined: Sun Feb 01, 2015 10:37

Re: Ogre 2.0 + multiple windows = fail

Postby Suslik » Mon Feb 02, 2015 13:42

I think I'll get some more experience with ogre+cegui and document problems like this on my side locally. Then I'll commit them all to wiki when I have the time. I'm still very new to both of these technologies.

Suslik
Just popping in
Just popping in
Posts: 10
Joined: Sun Feb 01, 2015 10:37

Re: Ogre 2.0 + multiple windows = fail

Postby Suslik » Mon Feb 02, 2015 19:58

Well there's more. After injectic keyboard/mouse events into CEGUI I still found some serious non-obvious issues. On Ogre 2.0 or CEGUI default:
The second window with CEGUI renders the interface fine until it receives some kind of inputs: sometimes when you mouse over certain widget or scroll some CEGUI scrollbars the intefrace zooms x2 and flips upside down for a moment. It's very hard to screenshot or describe but believe me - this stuff is broken. If I use ogre 1.9 with CEGUI 0.8 the second window flashes a little darker instead of flipping and scaling randomly.

Tested OpenGL renderer only. Interface in the first window renders completely fine.

Boost113
Not too shy to talk
Not too shy to talk
Posts: 45
Joined: Sat Apr 12, 2014 09:44

Re: Ogre 2.0 + multiple windows = fail

Postby Boost113 » Tue Feb 03, 2015 15:23

I did the CEGUI Ogre 2.0 renderer and here's a few things that might be useful:

You don't seem to be using the Renderer bootstrap function.

This call might be pointless and it could potentially break something: ceguiOgreRenderer->setDefaultRootRenderTarget(*window);

You seem to be creating the workspaces for CEGUI. The Ogre 2.0 CEGUI renderer creates its own workspace, which has a render queue listener which calls this to perform rendering:

Code: Select all

         // We should only render contexts that are on this render target
        System::getSingleton().renderAllGUIContextsOnTarget(d_owner);

This could also be an issue as the renderer will run this in the constructor:

Code: Select all

    // Some automatic bootstrapping
    if (!OgreRenderer_impl::s_compositorResourcesInitialized)
    {
        createOgreCompositorResources();
    }


It could be enough to call

Code: Select all

OgreRenderer::constructor_impl(Ogre::RenderTarget& target)

With a different target which should then create its own workspace and render when the second window is rendered. There could be some textures/shaders that cause issues if multiple windows/renderers try to share them.
There are some other functions like "OgreRenderer::updateWorkspaceRenderTarget(Ogre::RenderTarget& target)" in RendererModules/Ogre/Renderer.cpp which may be useful.

Originally I intended to make multiple windows work with the Ogre renderer but I scrapped that after I realised I would have to make all parts of CEGUI aware of their render target, things like font scaling and mouse constraining to window size would break.

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

Re: Ogre 2.0 + multiple windows = fail

Postby Ident » Tue Feb 03, 2015 15:26

Sorry for attributing your contributions to somebody else, Boost113. My memory is not the best ;)
CrazyEddie: "I don't like GUIs"

Suslik
Just popping in
Just popping in
Posts: 10
Joined: Sun Feb 01, 2015 10:37

Re: Ogre 2.0 + multiple windows = fail

Postby Suslik » Tue Feb 03, 2015 17:19

Boost113 wrote:You don't seem to be using the Renderer bootstrap function.

I'm not using bootstrap because it calls CEGUI::System::create inside. So if I call bootstrap once per program I get only 1 ogre renderer which's probably not the thing I want. If I call one bootstrap per window I get "Already Initialized" exception. So that's why I'm using 2 renderers without a bootstrap. Is that wrong?
Boost113 wrote:This call might be pointless and it could potentially break something: ceguiOgreRenderer->setDefaultRootRenderTarget(*window);

Yeah thank you I already figured that out. Removed this line.

Boost113 wrote:You seem to be creating the workspaces for CEGUI. The Ogre 2.0 CEGUI renderer creates its own workspace, which has a render queue listener which calls this to perform rendering:

Code: Select all

         // We should only render contexts that are on this render target
        System::getSingleton().renderAllGUIContextsOnTarget(d_owner);

This could also be an issue as the renderer will run this in the constructor:

Code: Select all

    // Some automatic bootstrapping
    if (!OgreRenderer_impl::s_compositorResourcesInitialized)
    {
        createOgreCompositorResources();
    }


It could be enough to call

Code: Select all

OgreRenderer::constructor_impl(Ogre::RenderTarget& target)

With a different target which should then create its own workspace and render when the second window is rendered. There could be some textures/shaders that cause issues if multiple windows/renderers try to share them.

So you advice me to create OgreRenderers manually, one per window. And I don't want to call bootstrap after that, right?

If I don't create a workspace neither for window1 nor for window2, my program crashes. If I create only one workspace for winow1, it somewhat works but window 2 still has some weird glitches:
Image
I suppose it's normal that it does not clear color buffer but when I'm moving the scrollbar with mouse(and during some other mouse/window events as well), an upside-down and enlarged copy of my FrameWindow appears. If I create the workspace manually it's mostly the same except for color buffer being cleared as well.

Boost113 wrote:There are some other functions like "OgreRenderer::updateWorkspaceRenderTarget(Ogre::RenderTarget& target)" in RendererModules/Ogre/Renderer.cpp which may be useful.

I tried popping this call into my frameRenderingQueued listener but nothing changed :(



Boost113 wrote:Originally I intended to make multiple windows work with the Ogre renderer but I scrapped that after I realised I would have to make all parts of CEGUI aware of their render target, things like font scaling and mouse constraining to window size would break.

I really need multiple windows to function properly. I don't care about scaling in runtime and I use non-captured mouse so I'm not interested in mouse constraining either. Would you kindly help me with some code that I tried making somewhat bearable? It works for both ogre 2.0 and 1.9 but the second window glitches in both(in different ways). Here's the code: http://pastebin.com/i773VL6i

Boost113
Not too shy to talk
Not too shy to talk
Posts: 45
Joined: Sat Apr 12, 2014 09:44

Re: Ogre 2.0 + multiple windows = fail

Postby Boost113 » Tue Feb 03, 2015 19:10

Ident wrote:Sorry for attributing your contributions to somebody else, Boost113. My memory is not the best ;)

Well... I'm actually Henri Hyyryläinen ... so ... (It would probably avoid confusion if I hadn't used my "gaming" user name here)

I just did a quick test and got this result, which seem correct, I'm just not clearing the window so the background is wrong.
Image
(The image seems to be clipped when viewing it on this page...)

Sorry Suslik, but I don't have time to write an actual reply right now...

This is the class that initializes CEGUI in my project: https://bitbucket.org/hhyyrylainen/leviathan/src/675d1b4773d9949384cb06bc8b285d9072ba29b0/Engine/Rendering/GraphicalInputEntity.cpp?at=Networking
I added the new method registerWindow. Which can be seen here https://bitbucket.org/hhyyrylainen/cegui-fork/src/ac05e23e79eeb63bc5b2d85f99b3c38e8601a677/cegui/src/RendererModules/Ogre/Renderer.cpp?at=default
Once I get this done I'll create a pull request for the method.


Return to “Help”

Who is online

Users browsing this forum: No registered users and 15 guests