I wanted to test how CEGUI compares to other GUI libraries I have used but I can't since the new Ogre 2.0 compositor system is not supported.
In the upcoming 2.0 release ViewPorts should not be used and thus the OgreRenderer needs an overhaul, from the 2.0 porting draft:
"3.5 Where is RenderTarget::update? Why do I get errors in Viewport?
Advanced users are probably used to low level manipulation of RenderTargets. As such they're used to setting up their custom Viewports and calling RenderTarget::update.
That is too low level. Instead, users are now encouraged to setup Compositor nodes and multiple workspaces to perform rendering to multiple RTs, even if it's for your own custom stuff"
So this means that all the ViewPort related code needs to be changed to work with the latest releases.
I haven't used the library at all and only worked a little bit with the new compositor2 but I did some changes that could be a base for properly fixing/improving the renderer.
(Syntax coloured version for your viewing pleasure: http://boostslair.com/files/CEGUI_fixes_colour.htm)
Code: Select all
// Put this to a static initialize which is called before any OgreRenderer instances are created
// Define a workspace template //
auto templatedworkspace = manager->addWorkspaceDefinition("CEGUI_workspace");
// Create a node //
auto rendernode = manager->addNodeDefinition("OverlayRenderNode");
// Use the render target passed from the workspace for rendering on top of //
rendernode->addTextureSourceName("renderwindow", 0, TextureDefinitionBase::TEXTURE_INPUT);
// Pass for it //
auto targetpasses = rendernode->addTargetPass("renderwindow");
targetpasses->setNumPasses(2);
Ogre::CompositorPassClearDef* clearpass = static_cast<Ogre::CompositorPassClearDef*>(targetpasses->addPass(Ogre::PASS_CLEAR));
// Only clear depth and stencil since we are rendering on top of existing image //
clearpass->mClearBufferFlags = Ogre::FBT_DEPTH | Ogre::FBT_STENCIL;
// Now the render scene pass during which the render queue listener should render the GUI //
Ogre::CompositorPassSceneDef* scenepass = static_cast<Ogre::CompositorPassSceneDef*>(targetpasses->addPass(Ogre::PASS_SCENE));
// Just render the overlay group since it is the only one used //
scenepass->mFirstRQ = Ogre::RENDER_QUEUE_OVERLAY;
scenepass->mLastRQ = Ogre::RENDER_QUEUE_OVERLAY;
// Connect the main render target to the node //
templatedworkspace->connectOutput("OverlayRenderNode", 0);
// Then put this into initialize method for all individual OgreRenderers (every window should have their own and they should
// have some of the functionality moved to a static class/OgreRenderMaster class
Ogre::Root& root = Ogre::Root::getSingleton();
// Set up a scene to use //
// These might not be required, but since they are empty it shouldn't matter that much
auto OverlayScene = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_INTERIOR, 1, Ogre::INSTANCING_CULLING_SINGLETHREAD,
"Overlay_forGUI_ID1");
auto OverLayCamera = OverlayScene->createCamera("empty camera");
Ogre::CompositorManager2* manager = root.getCompositorManager2();
// This is the part that replaces the ViewPorts
// Create the workspace to the render target //
// Pass this as a parameter to this function
Ogre::RenderTarget* target = NULL;
// The -1 should quarantee this to be rendered last on top of everything
manager->addWorkspace(OverlayScene, target, OverLayCamera, "CEGUI_rendering_for_window0", true, -1);
// TODO: start listening for RENDER_QUEUE_OVERLAY rendering and render during it //
// What this should accomplish is that pretty much everything else except setting up the matrices can be removed and of course the render queue listener
// needs to be added
static class OgreGUIFrameListener : public Ogre::RenderQueueListener
{
public:
OgreGUIFrameListener(OgreRenderer* owner) : Owner(Owner), d_enabled(true){};
void setCEGUIRenderEnabled(bool enabled);
bool isCEGUIRenderEnabled() const;
virtual void renderQueueStarted(RenderQueue *rq, uint8 queueGroupId, const String& invocation, bool& skipThisInvocation){
if (d_enabled){
// We should only render contexts that are on this render target //
// Pass pointer to the renderer here //
Owner->beginRendering();
// Stuff from System::renderAllGUIContexts
// We should get the right context from the OgreRenderer instance somehow
d_guiContexts[0]->draw();
// Maybe a vector
//Owner->VectorOfContextsOnThisTarget;
// This probably should only be called once //
// do final destruction on dead-pool windows
WindowManager::getSingleton().cleanDeadPool();
// This wouldn't even be required //
Owner->endRendering();
}
}
private:
bool d_enabled;
OgreRenderer* Owner;
} S_frameListener;
void OgreRenderer::beginRendering()
{
// Should now be called from the render queue listener //
initialiseRenderStateSettings();
}
void OgreRenderer::endRendering()
{
// Cleanup should no longer be required, at least it would be quite hard to try to restore the matrices etc //
}
Would be great if this would be supported in the future so I could actually use CEGUI
thanks