SceneManager::setMaterialListener(..)

What it says on the tin: a place to discuss proposed new features.
Post Reply
ssylvan
Gnoblar
Posts: 22
Joined: Sun Jun 05, 2005 5:29 pm

SceneManager::setMaterialListener(..)

Post by ssylvan »

I really don't understand why this feature isn't already in Ogre. I can't think of a single gaming engine that doesn't require and/or support this.

What I want is to be able to set up a listener (perhaps "Overrider" is a better name) for Material and RenderingOperations in the SceneManager. This means that everytime a material is being used (that is, when rendering) it will retrieve this material *via* the materiallistener, which may return the material of the given Renderble, or it may override the material of the Renderable and pass some other material back.

The MaterialListener class has a method like:

Code: Select all

MaterialPtr &getMaterial(Renderable* r) const

So if you, say, want to turn on a full-scene heat-vision effect you can just set the MaterialListener associated with the SceneManager (there's only one at a time) to ignore the material of the passed in renderable, and instead return a heat-vision material (which may depend on the renderable, such as if it uses skeletal animation etc.).

This is useful for *so* many effects, and also for many useful debugging features, such as drawing the world with a "+1" material to visualize overdraw-complexity, or rendering the world in wireframe to visualize geometric complexity (that's where the RenderingOperationListener comes in).

Doing any of the cool new full-scene effects that the latest graphics cards allows us to do is quite simiply impossible to do robustly and elegantly in Ogre without this feature.
You can hack up a little demo that looks cool with a single object or so (see the Cel-shading example), but you can't do it robustly for a general scene (such as turning on/off full-scene heat-vision, image-space post-processing motion blur, or an).
Adding this functionality on top of ogre is really tedious and results unneeded inefficiency (especially with regards to memory usage).
I am now in the process of writing a decorator for SceneNode, SceneManager, MovableObject and Renderable, which hopefully will allow me to add the ability to override all materials in a general scene (BSP, OctTree, whatever) - but I don't think that approach is generally viable, it' just a stop-gap meassure to make it work for my app.
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
Contact:

Post by sinbad »

I have an item on my TODO for Dagon called 'Customisable render queues' which incorporates an option to turn off automatic material / renderstate handling for a given queue invocation and to let the queue listener control it. I think controlling this at the queue level, rather than a per-Renderable callback, is slightly more powerful since you can also control things like stencil state which are not exposed in materials.

I'm really hoping to get time to address it this time, it was bumped back from Azathoth due to lack of time, and time is never something I have plenty of, but I'll try not to let it slip this time.
User avatar
:wumpus:
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3067
Joined: Tue Feb 10, 2004 12:53 pm
Location: The Netherlands
x 1

Post by :wumpus: »

Yeah, together with the compositor framework this could be very very powerful.
ssylvan
Gnoblar
Posts: 22
Joined: Sun Jun 05, 2005 5:29 pm

Post by ssylvan »

That sounds good.
ssylvan
Gnoblar
Posts: 22
Joined: Sun Jun 05, 2005 5:29 pm

Post by ssylvan »

Just to add another point.

I would imagine that the no. 1 use of this, would be to render the geometry with a special material (such as velocity-mapping, sihlouette mapping etc.).

One special case that's very important here, and would be nice if it was easy to do, is to split object into the groups "rigid" and "skeletal animated". This is because the latter requires extra stuff (skinning) to be done in the vertex shader in addition to whatever material-specific things you wish to do.

I'm doing velocity mapping so I'm simply writing two velocity-materials, one for skeletal animation, and one for the rest. I would imagine this is a common situation for most such effects.

So anything you can do when designing this to make this easier for people (without sacrificing flexibility of course) would be greatly apreciated, I'm sure.
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
Contact:

Post by sinbad »

You could just put these 2 categories into separate render queues.
klauss
Hobgoblin
Posts: 559
Joined: Wed Oct 19, 2005 4:57 pm
Location: LS87, Buenos Aires, República Argentina.

Post by klauss »

What about generalizing render queues?
I mean, not only a handful predefined queues, why not use a user-supplied render order (a Real), and sort them out that way?

No need to break code, only define the enumerators as static reals within RenderGroupManager with the same relative order.
Oíd mortales, el grito sagrado...
Hey! What is it with that that?
Wing Commander Universe
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
Contact:

Post by sinbad »

klauss wrote:What about generalizing render queues?
I mean, not only a handful predefined queues, why not use a user-supplied render order (a Real), and sort them out that way?
Because if you need a Real to represent a render queue, you've got too many.
User avatar
:wumpus:
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3067
Joined: Tue Feb 10, 2004 12:53 pm
Location: The Netherlands
x 1

Post by :wumpus: »

ssylvan wrote: One special case that's very important here, and would be nice if it was easy to do, is to split object into the groups "rigid" and "skeletal animated". This is because the latter requires extra stuff (skinning) to be done in the vertex shader in addition to whatever material-specific things you wish to do.
I suppose this MaterialListener thingydoodle will get passed in the 'original' material, so if it gets passed the 'RobotHardwareSkinned' material it can return 'HardwareSkinnedVelocityMapping' and for 'TreeTrunk' it can just return 'StaticVelocityMapping' .. etc, so you wouldn't even need multiple render queues for this.
klauss
Hobgoblin
Posts: 559
Joined: Wed Oct 19, 2005 4:57 pm
Location: LS87, Buenos Aires, República Argentina.

Post by klauss »

sinbad wrote:
klauss wrote:What about generalizing render queues?
I mean, not only a handful predefined queues, why not use a user-supplied render order (a Real), and sort them out that way?
Because if you need a Real to represent a render queue, you've got too many.
It's not the ability to have tons of render queues, but rather the ability to plug a custom render queue between two standard ones what I would find interesting. Anyway, the Real would be a much more generic and straight-forward interface. Cleaner, IMO.

Say...
Q: what's between RENDER_QUEUE_BACKGROUND and RENDER_QUEUE_SKIES_EARLY?

A: (RENDER_QUEUE_BACKGROUND+RENDER_QUEUE_SKIES_EARLY)/2

;)
Oíd mortales, el grito sagrado...
Hey! What is it with that that?
Wing Commander Universe
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
Contact:

Post by sinbad »

Ah, I see - well there's 1-4 in between, but I realise that using an enum as a parameter rather than just as reference values has eliminated the benefit of leaving gaps between the numbers, since the compiler will throw it out without some nasty casting. That will be resolved in Dagon, but by using a uint8 rather than a float.
Post Reply