I am currently in the process of trying out CEGUI and figuring out if various things we need for our project are possible with it.
It was pretty easy to setup and get it running with Ogre, which we are using as our rendering engine. So thumbs up for that.
We also want to have the possibility to display and manage 3D rendered content using the CEGUI's framwork with layout files.
I already figured out that RTT is probably the way to go for this and I have found posts and code for that as well with this one being the most helpful so far.
However, I got this example running with the current version 0.8, but it does not allow me to declare it that way in a layout xml file. So I started a class which inherits the CEGUI Window to create my own widget. This should simply display the rendered scene a camera can see which is attached to it.
Here is the code I got so far:
Header file:
Code: Select all
class CEGUIViewportWindow : public CEGUI::Window
{
public:
static const CEGUI::String EventNamespace; //!< Namespace for global events
static const CEGUI::String WidgetTypeName; //!< Window factory name
CEGUIViewportWindow(const CEGUI::String& type, const CEGUI::String& name);
virtual ~CEGUIViewportWindow();
void setCameraToRender(Ogre::Camera& camera);
void removeCamera(void);
protected:
void onRenderingStarted(CEGUI::WindowEventArgs& e);
void onSized(CEGUI::ElementEventArgs& e);
private:
Ogre::RenderTexture* mRttTexture;
Ogre::Camera* mCamera;
Ogre::Viewport* mViewport;
void __initialiseRTTViewport(CEGUI::RenderingSurface* surface, bool force);
void __setCamera(Ogre::Camera& camera);
bool __handleResize(const CEGUI::EventArgs& args);
};
Here the source file:
Code: Select all
const CEGUI::String CEGUIViewportWindow::EventNamespace("ViewportWindow");
const CEGUI::String CEGUIViewportWindow::WidgetTypeName("CEGUI/ViewportWindow"); //!< Window factory name
CEGUIViewportWindow::CEGUIViewportWindow(const CEGUI::String& type, const CEGUI::String& name) :
CEGUI::Window(type, name)
{
this->mRttTexture = NULL;
this->mCamera = NULL;
this->mViewport = NULL;
}
CEGUIViewportWindow::~CEGUIViewportWindow(void)
{
}
void CEGUIViewportWindow::setCameraToRender(Ogre::Camera& camera)
{
this->__setCamera(camera);
}
void CEGUIViewportWindow::removeCamera(void)
{
this->mCamera = NULL;
}
// ------------------------------------------------------------------------------------------------
void CEGUIViewportWindow::__initialiseRTTViewport(CEGUI::RenderingSurface* surface, bool force)
{
Ogre::RenderTexture* old_rtt = this->mRttTexture;
// extract the Ogre render target at for the surface
CEGUI::OgreTextureTarget& textureTarget = dynamic_cast<CEGUI::OgreTextureTarget&>(
surface->getRenderTarget());
CEGUI::OgreTexture& ogreTexture = dynamic_cast<CEGUI::OgreTexture&>(textureTarget.getTexture());
this->mRttTexture = ogreTexture.getOgreTexture()->getBuffer()->getRenderTarget();
// only do set up if target is changed.
if (old_rtt != this->mRttTexture || force)
{
// tell Ogre not to draw this target automatically (else you get
// visible flickering).
this->mRttTexture->setAutoUpdated(false);
// setup viewport from the same camera as the main scene.
Ogre::Viewport* viewport = this->mRttTexture->addViewport(mCamera);
viewport->setOverlaysEnabled(false);
viewport->setBackgroundColour(Ogre::ColourValue::Black);
}
}
void CEGUIViewportWindow::__setCamera(Ogre::Camera& camera)
{
this->mCamera = &camera;
CEGUI::RenderingSurface* surface = this->getRenderingSurface();
if (surface != NULL)
this->__initialiseRTTViewport(surface, true);
}
void CEGUIViewportWindow::onRenderingStarted(CEGUI::WindowEventArgs& e)
{
if (this->mRttTexture != NULL)
this->mRttTexture->update();
}
void CEGUIViewportWindow::onSized(CEGUI::ElementEventArgs& e)
{
// get rendering surface used by FrameWindow.
CEGUI::RenderingSurface* surface =
static_cast<CEGUI::Window*>(e.element)->getRenderingSurface();
// if there's no surface, skip the RTT setup parts!
if (surface)
this->__initialiseRTTViewport(surface, false);
}
I also registered the new widget with the WindowFactoryManager like this:
Code: Select all
CEGUI::WindowFactoryManager::getSingleton().addFactory<CEGUI::TplWindowFactory<CEGUIViewportWindow> >();
So I just took the example from this forum I found and tried creating my own widget. I took the already existing widgets from CEGUI as examples. So here is the problem with this:
If I try to create a new window of my own widget type "CEGUI/ViewportWindow", the rendering surface of it is always NULL.
It doesn't matter whether I access it within the class or outside of the class.
I am sure I forgot something, but I wasn't able to figure it out so far. Can somebody give me a hint on this? Or is there a tutorial with an example of a real custom widget based on the Window class?
That's the code section which creates my widget and adds it to the root window:
Code: Select all
CEGUI::Window* fw = wmgr.createWindow("CEGUI/ViewportWindow");
rootWindow->addChild(fw);
fw->setSize(CEGUI::USize(CEGUI::UDim(0.5f, 0), CEGUI::UDim(0.5f, 0)));
((ogreaddon::cegui::CEGUIViewportWindow*) fw)->setCameraToRender(*camera);
// this always returns NULL
CEGUI::RenderingSurface* renderingSurface = fw->getRenderingSurface();
Thanks in advance for any help on this.