Render overlay on top of cegui window
Moderators: CEGUI MVP, CEGUI Team
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Render overlay on top of cegui window
Just to update on this: I did not get the multiple VP support done yet (yeah, yeah, I know! I said the weekend! ). I'm looking at it right now, though. It may even get done today, otherwise, probably Wednesday; I'm having to fit CEGUI work in around a bunch of other stuff at the moment
To add to the woes, I'm having serious connectivity issues, so am not able to work in as efficient manner as I'd like
CE.
To add to the woes, I'm having serious connectivity issues, so am not able to work in as efficient manner as I'd like
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Render overlay on top of cegui window
Ok. I have the basic issues resolved. Here's a video:
I just have to test this on Windows for the D3D support, and I'll commit the changes and post back with the details about how it needs to be done along with a bit of a caveat / condition regarding the successful use of this (or in other words, this is still a bit of a hack, so you have to do something to ensure it works correctly).
Watch this space...
CE.
I just have to test this on Windows for the D3D support, and I'll commit the changes and post back with the details about how it needs to be done along with a bit of a caveat / condition regarding the successful use of this (or in other words, this is still a bit of a hack, so you have to do something to ensure it works correctly).
Watch this space...
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
-
- Quite a regular
- Posts: 79
- Joined: Wed Jan 09, 2008 11:06
Re: Render overlay on top of cegui window
Excellent work, eagerly awaiting news
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Render overlay on top of cegui window
Ok. I have just committed the mods required to get this support working, most of the rest of this post will deal with the app side of what must be done. Before I get on to that I must mention that I've spotted a graphical glitch when rendering using the D3D render system in Ogre - GL is fine, and plain old D3D is fine, but D3D under Ogre currently exhibits a minor issue with clipping - so if you see some single pixel gaps and/or alignment issues, then this is now a known issue and I'll investigate and fix ASAP.
Ok. On to the goodies...
First the caveat. In the current code we use scissoring to perform clipping when rendering window content. The problem is that the scissor region is not affected by the set viewport (it's always screen space). In order to work around this, when using the following multi-viewport hack, you need to ensure that all your top-level windows have the AutoRenderingSurface property enabled; this way content is cached to texture correctly clipped and the Right Thing is done when drawing back into multiple viewports. It may be possible to work around this issue in the future by using the viewport and projection to perform the scissoring instead (we already do that in Irrlicht, which does not expose scissoring facilities), but for now this limitation exists.
Now, the first thing you need to do is disable CEGUI's use of the _beginFrame and _endFrame calls in Ogre::RenderSystem, you can do this like so:
As noted in the comment above, this call will automatically disable the usual rendering done by the CEGUI::OgreRenderer, so after making this call, nothing will be drawn.
Now you have to hook back into the rendering process, and we'll do that by way of a Ogre::RenderQueueListener, which is set up in the usual manner, such as:
Finally, we have the rewritten CEGUIRQListener class, which looks like this:
The above example only has the code that 'does the business' in the renderQueueEnded member function, if you want the same thing in renderQueueStarted, you can either duplicate the code or refactor a bit. I'll just overview on what's going on in there.
Basically, because that function is called for each view port, we have to query the active view port from the Ogre render system, and pass the viewport size to the CEGUI::RenderTarget by way of the setOgreViewportDimensions function.
Hope this is useful You'll have to bear with me on the clipping glitch mentioned at the top of the post, I'll get it fixed soon
CE.
Ok. On to the goodies...
First the caveat. In the current code we use scissoring to perform clipping when rendering window content. The problem is that the scissor region is not affected by the set viewport (it's always screen space). In order to work around this, when using the following multi-viewport hack, you need to ensure that all your top-level windows have the AutoRenderingSurface property enabled; this way content is cached to texture correctly clipped and the Right Thing is done when drawing back into multiple viewports. It may be possible to work around this issue in the future by using the viewport and projection to perform the scissoring instead (we already do that in Irrlicht, which does not expose scissoring facilities), but for now this limitation exists.
Now, the first thing you need to do is disable CEGUI's use of the _beginFrame and _endFrame calls in Ogre::RenderSystem, you can do this like so:
Code: Select all
// disable calls to _beginFrame and _endFrame, which also disables
// default rendering: we will use a custom rendering method.
myOgreRenderer->setFrameControlExecutionEnabled(false);
As noted in the comment above, this call will automatically disable the usual rendering done by the CEGUI::OgreRenderer, so after making this call, nothing will be drawn.
Now you have to hook back into the rendering process, and we'll do that by way of a Ogre::RenderQueueListener, which is set up in the usual manner, such as:
Code: Select all
myRenderQueueListener = new CEGUIRQListener(myOgreRenderer, Ogre::RENDER_QUEUE_OVERLAY, true);
mySceneManager->addRenderQueueListener(myRenderQueueListener);
Finally, we have the rewritten CEGUIRQListener class, which looks like this:
Code: Select all
//! RenderQueueListener based class used to hook into the ogre rendering system
class CEGUIRQListener : public Ogre::RenderQueueListener
{
public:
CEGUIRQListener(CEGUI::OgreRenderer* renderer, Ogre::uint8 queue_id, bool post_queue) :
d_renderer(renderer),
d_queue_id(queue_id),
d_post_queue(post_queue)
{
}
void renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, bool& skipThisQueue)
{
if (!d_post_queue && d_queue_id == id)
CEGUI::System::getSingleton().renderGUI();
}
void renderQueueEnded(Ogre::uint8 id, const Ogre::String& invocation, bool& repeatThisQueue)
{
if (!d_post_queue || d_queue_id != id)
return;
// need to reset Ogre renderer viewport here for whichever vp is being drawn.
Ogre::Viewport* vp = Ogre::Root::getSingleton().getRenderSystem()->_getViewport();
int left, top, width, height;
vp->getActualDimensions(left, top, width, height);
const CEGUI::Rect vp_area(left, top, left + width, top + height);
dynamic_cast<CEGUI::OgreRenderTarget&>(
d_renderer->getDefaultRenderingRoot().getRenderTarget()).
setOgreViewportDimensions(vp_area);
CEGUI::System::getSingleton().renderGUI();
}
// methods for adjusting target queue settings
void setTargetRenderQueue(Ogre::uint8 queue_id)
{
d_queue_id = queue_id;
}
void setPostRenderQueue(bool post_queue)
{
d_post_queue = post_queue;
}
The above example only has the code that 'does the business' in the renderQueueEnded member function, if you want the same thing in renderQueueStarted, you can either duplicate the code or refactor a bit. I'll just overview on what's going on in there.
Basically, because that function is called for each view port, we have to query the active view port from the Ogre render system, and pass the viewport size to the CEGUI::RenderTarget by way of the setOgreViewportDimensions function.
Hope this is useful You'll have to bear with me on the clipping glitch mentioned at the top of the post, I'll get it fixed soon
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
-
- Quite a regular
- Posts: 79
- Joined: Wed Jan 09, 2008 11:06
Re: Render overlay on top of cegui window
Hey CE,
That works great!
The only issue is the 'AutoRenderingSurface for Top-level windows', what exactly constitutes a top-level window? We use a lot of layouts in one of our apps, so I'd like to automate that property somehow, would it be enough to tag the window returned from loadWindowLayout()? Or is it going to be more involved then that?
Thanks.
That works great!
The only issue is the 'AutoRenderingSurface for Top-level windows', what exactly constitutes a top-level window? We use a lot of layouts in one of our apps, so I'd like to automate that property somehow, would it be enough to tag the window returned from loadWindowLayout()? Or is it going to be more involved then that?
Thanks.
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Render overlay on top of cegui window
In this context, we can define a top level window like this:
For example, in Demo7 that comes with CEGUI there is a full screen root window, a full screen static image, and three frame windows. The AutoRenderingSurface is enabled on the frame windows only, and they are what we consider the top-level windows in that example.
Enabling the AutoRenderingSurface also enables the texture caching (which is the whole point), so which approach is 'best' will also depend largely on your usage. It can be set in the looknfeel for certain window types, or manually on the windows returned from loadWindowLayout as you suggest, or in the layout itself if it's only needed for certain instances of a window type. As an example, caching the entire sheet would be wasteful of resources if you only have a single button displayed - in cases like that, cache the button.
One thing you could do is enable it for the root windows as suggested, and see how things go - you can always go in and tune it later.
CE.
The root window or any window that is drawn directly onto either the root window or other full-screen window attached to the root window
For example, in Demo7 that comes with CEGUI there is a full screen root window, a full screen static image, and three frame windows. The AutoRenderingSurface is enabled on the frame windows only, and they are what we consider the top-level windows in that example.
Enabling the AutoRenderingSurface also enables the texture caching (which is the whole point), so which approach is 'best' will also depend largely on your usage. It can be set in the looknfeel for certain window types, or manually on the windows returned from loadWindowLayout as you suggest, or in the layout itself if it's only needed for certain instances of a window type. As an example, caching the entire sheet would be wasteful of resources if you only have a single button displayed - in cases like that, cache the button.
One thing you could do is enable it for the root windows as suggested, and see how things go - you can always go in and tune it later.
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
Re: Render overlay on top of cegui window
hehe. nice discussion here. No worries. It's always fun to follow interesting discussions.
I haven't had time to try out the solution yet.
I'll come back with the results this week.
I haven't had time to try out the solution yet.
I'll come back with the results this week.
-
- Quite a regular
- Posts: 79
- Joined: Wed Jan 09, 2008 11:06
Re: Render overlay on top of cegui window
Hi wizzler,
sorry for hijacking but this update should solve your request also, it now allows the old style implementation so you can render your gui in any Ogre::RenderQueue, apart from the clipping issue highlighted and the inclusion of the AutoRenderSurface flag it should work fine.
sorry for hijacking but this update should solve your request also, it now allows the old style implementation so you can render your gui in any Ogre::RenderQueue, apart from the clipping issue highlighted and the inclusion of the AutoRenderSurface flag it should work fine.
Re: Render overlay on top of cegui window
Greetings,
I'm a noob at Ogre and CEGUI and have been porting my project to Ogre 1.7 and CEGUI 0.7 (current stable svn version) and I'm having the same problem as wizzler. Previously I created a bunch of CEGUI-rtt objects like this: http://www.ogre3d.org/wiki/index.php/Ba ... to_Texture
And on top of them I added an Ogre::OverlayContainer over each rtt.
Now if I create an CEGUIRQListener with post_queue = false all my hud/overlay-objects (including ogre fps/logo etc) disappear and only one or no overlay is visible.
Any tips on how to modify the CEGUIRQListener to get the old behaviour back?
I'm a noob at Ogre and CEGUI and have been porting my project to Ogre 1.7 and CEGUI 0.7 (current stable svn version) and I'm having the same problem as wizzler. Previously I created a bunch of CEGUI-rtt objects like this: http://www.ogre3d.org/wiki/index.php/Ba ... to_Texture
And on top of them I added an Ogre::OverlayContainer over each rtt.
Now if I create an CEGUIRQListener with post_queue = false all my hud/overlay-objects (including ogre fps/logo etc) disappear and only one or no overlay is visible.
Any tips on how to modify the CEGUIRQListener to get the old behaviour back?
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Render overlay on top of cegui window
You must ALWAYS SPECIFY THE EXACT VERSION OF CEGUI YOU ARE USING. The easiest way to do this is to POST THE SECTION INDICATED IN THE CEGUI LOG FILE. Why do we have to keep reiterating this time and time again?
The CEGUI code is very fluid. The 0.7.1 code differs greatly from the 0.7.0 code, just as the current v0-7 subversion code - or a snapshot - will differ greatly from the released 0.7.1 code. There are things we could advise you to do that will only work with the v0-7 / snapshot code, so unless we know you're using that (or not) no advice can be given, because otherwise we get you guys coming back saying "a, b or c does not work".
All of this said, as far as I recall from my tests, the code above works fine - as in, restores the 0.6.2 behaviour exactly - when used with the v0-7 branch code. It will not work correctly with the 0.7.1 release, as discussed above.
CE
The CEGUI code is very fluid. The 0.7.1 code differs greatly from the 0.7.0 code, just as the current v0-7 subversion code - or a snapshot - will differ greatly from the released 0.7.1 code. There are things we could advise you to do that will only work with the v0-7 / snapshot code, so unless we know you're using that (or not) no advice can be given, because otherwise we get you guys coming back saying "a, b or c does not work".
All of this said, as far as I recall from my tests, the code above works fine - as in, restores the 0.6.2 behaviour exactly - when used with the v0-7 branch code. It will not work correctly with the 0.7.1 release, as discussed above.
CE
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
Re: Render overlay on top of cegui window
I'm re-hijacking this thread to elaborate on problems related to the original question
So, the problem we have in our game is that our console hasn't yet moved to CEGUI but uses Ogre Overlays instead. Hence CEGUI needs to be drawn prior to Overlays. For that I've implemented CE's proposed solution based on how CEGUI 0.6.2 works in order to also support CEGUI 0.7.x (most probably >= 0.7.5 because Ubuntu and Debian haven't yet moved to 0.7, Arch uses 0.7.5 and we have our own dependencies for Mac and Windows, both using 0.7.5).
Now it seems like this solution might not work anymore for CEGUI 0.7.5, which is what I'm using right now. Overlays simply stay behind, even if I set the RenderQueue to RENDER_QUEUE_SKIES_LATE, which comes before RENDER_QUEUE_OVERLAY. And I checked that CEGUI::System::renderGUI() is only called from my RQListener.
I know this doens't help much solving the problem at hand. So I have a tiny hint: If I cklick on a button, but unpress the mouse outside that button (so it gets the focus), the Ogre Overlay is then drawn on top of that button. Interestingly it only affects that 'highlighted' Button and nothing else. I can do it with any button but haven't tried it with any other element.
And I've checked: this doesn't happen without the RQListener fix.
Any ideas?
So, the problem we have in our game is that our console hasn't yet moved to CEGUI but uses Ogre Overlays instead. Hence CEGUI needs to be drawn prior to Overlays. For that I've implemented CE's proposed solution based on how CEGUI 0.6.2 works in order to also support CEGUI 0.7.x (most probably >= 0.7.5 because Ubuntu and Debian haven't yet moved to 0.7, Arch uses 0.7.5 and we have our own dependencies for Mac and Windows, both using 0.7.5).
Now it seems like this solution might not work anymore for CEGUI 0.7.5, which is what I'm using right now. Overlays simply stay behind, even if I set the RenderQueue to RENDER_QUEUE_SKIES_LATE, which comes before RENDER_QUEUE_OVERLAY. And I checked that CEGUI::System::renderGUI() is only called from my RQListener.
I know this doens't help much solving the problem at hand. So I have a tiny hint: If I cklick on a button, but unpress the mouse outside that button (so it gets the focus), the Ogre Overlay is then drawn on top of that button. Interestingly it only affects that 'highlighted' Button and nothing else. I can do it with any button but haven't tried it with any other element.
And I've checked: this doesn't happen without the RQListener fix.
Any ideas?
Re: Render overlay on top of cegui window
I remember CE saying something about disabling the automatic rendering and calling renderGUI yourself exactly when you want. I don't know the details off the top of my head though. HTH at least a little bit
Re: Render overlay on top of cegui window
Kulik wrote:I remember CE saying something about disabling the automatic rendering and calling renderGUI yourself exactly when you want. I don't know the details off the top of my head though. HTH at least a little bit
I suppose you are referring to this line to disable automatic rendering:
Code: Select all
myOgreRenderer->setFrameControlExecutionEnabled(false);
and this line to do the rendering manually in the RQListener:
Code: Select all
void renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, bool& skipThisQueue)
{
if (!d_post_queue && d_queue_id == id)
CEGUI::System::getSingleton().renderGUI();
}
that's of course implemented.
As I mentioned, it seems to work, at least for that button ^^
- Jabberwocky
- Quite a regular
- Posts: 86
- Joined: Wed Oct 31, 2007 18:16
- Location: Canada
- Contact:
Re: Render overlay on top of cegui window
Have a look at this:
http://www.ogre3d.org/forums/viewtopic. ... 04&start=0
That is a very old thread, but it might still be relevant. Or might not be. That thread was written back when CEGUI used the old OgreCEGUIRenderer. It now uses the completely rewritten CEGUIOgreRenderer. Still, have a look at the post that discusses resetting the view and projection matrix, that might be your problem.
Also, I should point out an issue (and solution) I found with this code (which was posted earlier on this thread):
I found that I also needed to check the invocation string like this:
Otherwise I ended up rendering the GUI multiple times per frame, as renderQueueStarted can be called multiple times for the same id - for example if texture shadows are enabled. The additional renderQueueStarted calls for texture shadows all have a different invocation string, so the above check fixes the problem.
The same change needs to be made to renderQueueEnded
http://www.ogre3d.org/forums/viewtopic. ... 04&start=0
That is a very old thread, but it might still be relevant. Or might not be. That thread was written back when CEGUI used the old OgreCEGUIRenderer. It now uses the completely rewritten CEGUIOgreRenderer. Still, have a look at the post that discusses resetting the view and projection matrix, that might be your problem.
Also, I should point out an issue (and solution) I found with this code (which was posted earlier on this thread):
void renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, bool& skipThisQueue)
{
if (!d_post_queue && d_queue_id == id)
CEGUI::System::getSingleton().renderGUI();
}
I found that I also needed to check the invocation string like this:
void renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, bool& skipThisQueue)
{
if (!d_post_queue && d_queue_id == id && invocation == "" )
CEGUI::System::getSingleton().renderGUI();
}
Otherwise I ended up rendering the GUI multiple times per frame, as renderQueueStarted can be called multiple times for the same id - for example if texture shadows are enabled. The additional renderQueueStarted calls for texture shadows all have a different invocation string, so the above check fixes the problem.
The same change needs to be made to renderQueueEnded
The Salvation Prophecy
Space Combat. Planet Exploration. Strategic Domination.
Space Combat. Planet Exploration. Strategic Domination.
Re: Render overlay on top of cegui window
Thank you for digging up some information.
But I'm afraid neither the hack from the Ogre forum nor the invocation string check has made any difference.
I guess I'm going to have to go about it the hard way: compare the new and the old version of the Ogre GUI renderer..
But I'm afraid neither the hack from the Ogre forum nor the invocation string check has made any difference.
I guess I'm going to have to go about it the hard way: compare the new and the old version of the Ogre GUI renderer..
Who is online
Users browsing this forum: No registered users and 13 guests