libRocket & Shadows issue

Problems building or running the engine, queries about how to use features etc.
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3

libRocket & Shadows issue

Post by SpaceDude »

I've started using libRocket (http://www.librocket.com/) for rendering the GUI in my game. So far I like libRocket a lot, but I've encountered a problem with shadows. libRocket comes with a sample interface to ogre which works by registering a RenderQueueListener derived class. It makes calls directly to the RenderSystem to render itself, something like this:

Code: Select all

// Called from Ogre after a queue group is rendered.
void CRocketInterface::renderQueueEnded(uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation)
{
	if (queueGroupId == Ogre::RENDER_QUEUE_OVERLAY)
	{
		m_pContext->Update();

		ConfigureRenderSystem();
		m_pContext->Render();   // This ultimately results in calls being made directly to the RenderSystem
	}
}
My problem is that it is also rendering the GUI on top of the shadow caster which results in some rather interested effects (see below, no the menu is not meant to be casting a shadow onto the main scene :)).

How can I tell if this is the shadow caster stage or not?

Image
Last edited by SpaceDude on Tue Mar 25, 2008 7:46 pm, edited 1 time in total.
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

Ideally you'd want SceneManager::mIlluminationState; one problem - it's protected, and there's no corresponding get function.

If the GUI is making direct calls to the render system, why not render it separately, after the main scene? This is how I'm doing it, I set the destination viewport and call renderGUI() which "emulates" the calling of renderQueueStarted()/Ended() manually. You might need RenderSystem::_beginFrame()/_endFrame(), though.
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3

Post by SpaceDude »

nullsquared wrote:If the GUI is making direct calls to the render system, why not render it separately, after the main scene? This is how I'm doing it, I set the destination viewport and call renderGUI() which "emulates" the calling of renderQueueStarted()/Ended() manually. You might need RenderSystem::_beginFrame()/_endFrame(), though.
Sounds like a good idea, I tried something like this:

Code: Select all

void CGame::renderFrame()
{
	mRoot->renderOneFrame();
	m_pRocket->RenderGUI();
}

void CRocketInterface::RenderGUI()
{
	m_pContext->Update();

	RenderSystem* pRenderSystem = Root::getSingleton().getRenderSystem();
	pRenderSystem->_setViewport(GAME->GetWindow()->getViewport(0));
	pRenderSystem->_beginFrame();
	ConfigureRenderSystem();
	m_pContext->Render();
	pRenderSystem->_endFrame();
}
Well it doesn't work because somehow I feel that RenderGUI should be called from within renderOneFrame. While doing this I saw the Ogre::ShadowListener class which I think I can use to determine if shadows are being rendered or not.

EDIT: Adding the ShadowListener did the trick, thanks for pointing me in the right direction.

Code: Select all

//Shadow listener override
void shadowTexturesUpdated(size_t numberOfShadowTextures) { m_bRenderingShadows = false; }
void shadowTextureCasterPreViewProj(Light* light, Camera* camera) { m_bRenderingShadows = true; }
void shadowTextureReceiverPreViewProj(Light* light, Frustum* frustum) {}
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Post by nullsquared »

Oh, good solution there. I didn't think of using the ShadowListener like that, I was stuff with more of a "tell me whether you're rendering shadows right now" solution :lol:.

As for the "outside" rendering, yeah, it needs to be "inside" renderOneFrame(). The reason it works for me is because I manually render to my render targets (SceneManager::_renderScene()), and I can slap in renderGUI() right after the main scene. There's really only one advantage to this method, being able to arbitrarily render the gui whenever one feels like it to any viewport one wishes (or multiple, for that matter) - meaning, the GUI is not tied to the main scene's render queue.
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218

Re: libRocket & Shadows issue

Post by Jabberwocky »

SpaceDude wrote:I've started using libRocket (http://www.librocket.com/) for rendering the GUI in my game. So far I like libRocket a lot
Hey SpaceDude,

If you get a chance, I'd be interested in hearing a review of libRocket. I know your project used to use CEGUI - what prompted the change? What is working out better for you?
Image
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3

Re: libRocket & Shadows issue

Post by SpaceDude »

Jabberwocky wrote:If you get a chance, I'd be interested in hearing a review of libRocket. I know your project used to use CEGUI - what prompted the change? What is working out better for you?
Well the main reason for looking for an alternative to CEGUI was that I felt building new menus and modifying old ones was too time consuming. I was adding widgets in by editing the .layout files manually. The problems with this are:

- Adding a new widget typically takes up at least 5 lines of XML (depending on the type)
- You need to explicitly specify the position of the widgets, which is very time consuming especially if you need to shuffle around existing widgets to make space.

Secondly the whole theme system seems quite long winded to define (the default .looknfeel file is 4000 lines long). I looked at it briefly and decided it would be too much effort to define my own. That leaves you with just modifying the existing imageset which is quite restrictive because you can't change any of the dimensions.

Finally there is not much to optimise rendering performance in CEGUI, but it seems that crazy eddie is back in town and trying to address that.

So I looked around for alternatives and decided to take the plunge with libRocket. So far I'm very happy with libRocket, they have excellent support on the forums and good documentation. I've had a response to every single of my questions usually within the same day. The library is quite new so there may be odd features missing simply because they hadn't thought of people trying to do certain things. But overall they have a very solid framework and its often small details that are missing. Any features that are missing will probably get implemented very quickly. They have already implemented several features on my request despite the fact that I'm on the Free license :P.

In terms of the issues I had with CEGUI, you define menus and widgets using an HTML-like description. They call them .rml files, good things about it are:

- Each widget typically takes up 1 line of code
- You don't need to explicitly specify position (although you can if you want), they get aligned next to each other automatically

The theme system is also much easier to deal with, they are defined with a syntax similar to CSS except they are called .rcss. I have defined my custom theme in 700 lines of code which wasn't so painful. I did it step by step modifying 1 widget at a time.

The good thing about the theme system combined with the fact that you don't specify widget positions explicitly is that for example if you decide to change the graphics of your button such that it's size increases you won't have to redefine all your menus adding extra space between your buttons. So the defining of layout is almost completely separated from the theme definition.

I'm really liking the Python interface too, I'm quite a big fan of the Python language which probably helped sway me towards libRocket. I can't compare this against CEGUI's LUA interface because I never got round to using it. I should point out that I knew pretty much nothing about HTML and CSS before starting with libRocket, so it's not just for web junkies (and you might welcome the opportunity to learn something about BLOCKED).

On the down side, as far as I can tell there isn't a lot in terms of rendering optimisation either but that may be something that I can work on myself. Although I would guess the performance is better than say Navi.

Anyway I better stop there before I keep rambling on for pages.
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66

Post by sinbad »

Even though you found your own way around this, the way I would have suggested is to look at the 'invocation' parameter to renderQueueEnded. When rendering shadow casters, this is set to 'RenderQueueInvocation::RENDER_QUEUE_INVOCATION_SHADOWS'. Not hugely well publicised, I'll admit :)
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3

Post by SpaceDude »

sinbad wrote:Even though you found your own way around this, the way I would have suggested is to look at the 'invocation' parameter to renderQueueEnded. When rendering shadow casters, this is set to 'RenderQueueInvocation::RENDER_QUEUE_INVOCATION_SHADOWS'. Not hugely well publicised, I'll admit :)
Ah ok, that seems like a simpler solution indeed. I did wonder what the invocation parameter was and found it to be empty most of the time. Is it safe to assume the invocation parameter will always be empty on the main render? So would it be sensible to change my code to:

Code: Select all

void CRocketInterface::renderQueueEnded(uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation)
{
	if (queueGroupId == Ogre::RENDER_QUEUE_OVERLAY && invocation.empty())
	{
		m_pContext->Update();

		ConfigureRenderSystem();
		m_pContext->Render();
	}
}
Is that likely to work for future version of Ogre too? I'm thinking its better to check it is the "main" render rather than checking it is not a "shadow" render to avoid similar situations with other render to textures and whatnot.
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66

Post by sinbad »

It's blank in all other cases for now. We may use it for other purposes / special renders in future but the 'main' render is likely to remain blank.
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218

Post by Jabberwocky »

Thanks SpaceDude,

I appreciate you taking the time to write the libRocket review.

Several of the issues you have with CEGUI don't bother me, but others I agree with. Particularly, I find the .lookandfeel files are cumbersome to deal with. Still, I plan on sticking with it.
Image
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3

Post by SpaceDude »

Jabberwocky wrote:Several of the issues you have with CEGUI don't bother me, but others I agree with. Particularly, I find the .lookandfeel files are cumbersome to deal with. Still, I plan on sticking with it.
Fair enough, in terms of features I can't fault CEGUI. I think it has pretty much everything you'll ever need for a standard game GUI. I just think libRocket wins in terms of easy of use, which for me is rather important. With CEGUI, every time I needed to add a new menu or modify something I always put it off because it's a pain in the ass to do.
User avatar
chmod
Greenskin
Posts: 131
Joined: Tue Feb 25, 2003 10:33 pm
Location: Seattle, Washington USA

Post by chmod »

Can you test the libRocket gui files outside of the game? That's one nice thing about using Navi, is that I can build and test the entire GUI with Firefox locally. Building the GUI without recompiling every 5 seconds is very nice.
User avatar
SpaceDude
Bronze Sponsor
Bronze Sponsor
Posts: 822
Joined: Thu Feb 02, 2006 1:49 pm
Location: Nottingham, UK
x 3

Post by SpaceDude »

chmod wrote:Can you test the libRocket gui files outside of the game? That's one nice thing about using Navi, is that I can build and test the entire GUI with Firefox locally. Building the GUI without recompiling every 5 seconds is very nice.
No not really, I don't see how you can really test the GUI separately because surely the GUI will depend on events and data that come from the game. But you don't need to recompile anything if you are using libRocket with the Python interface. Python is an interpreted language so no recompile needed. If you are using C++ only, then you still don't need to recompile if you are only making changes to the layout & style because those are defined in text files not in the C++ code.
LBDude
Gnome
Posts: 389
Joined: Mon Jul 26, 2010 10:53 pm
x 22

Re: libRocket & Shadows issue

Post by LBDude »

Edit: Oh continued reading some more and found the invocation.empty post.

Edit: Ignore what I wrote below. See here:

http://forums.librocket.com/viewtopic.php?f=2&t=59




I can no longer do the above the fix because ShadowListener and SceneManager::Listener classes have been refactored.

Anyone know how to do something similar to the above. If not, then I guess I will have to implement the _renderOneFrame thing.
My blog here.
Game twitter here