Hey! I was away for a day, I come back and there's actually a discussion going on! Nice

.
Here's what I 've done:
I added the new enum I talked about: E_SCENE_RENDER_PASS.
I have added 2 new functions in ISceneManager:
Code: Select all
//! Returns the current rendering pass.
virtual E_SCENE_RENDER_PASS getSceneRenderPass() const = 0;
//! Returns the total number of render passes of the last frame.
virtual u32 getSceneRenderPassesCount() const = 0;
And 2 functions in ISceneNode:
Code: Select all
//! Registers the node for a render pass.
//! All nodes, by default, are registered for the first pass (ESRP_DEFAULT).
//! Here you can register the node for additional render passes.
//! \note You can't register for the special pass values: ESRP_ALL, ESRP_NONE and ESRP_LAST.
//! \param pass: The render pass to register for.
virtual void registerRenderPass(E_SCENE_RENDER_PASS pass);
//! Unregisters the node from a render pass.
//! You can't unregister the node if it's only registered to a single pass.
//! \note Unregistering from the special ESRP_ALL pass, unregisters from all
//! passes, and registers for ESRP_DEFAULT. Sort of a reset...
//! \param pass: The render pass to unregister from.
virtual void unregisterRenderPass(E_SCENE_RENDER_PASS pass)
What does this allow you to do now?
Well, in its current state, not much

. But this will improve

.
As you see, you can register a node for multiple passes by using something like this:
Code: Select all
ISceneNode* myNode = smgr->add.....Node(...);
// every scene node is automatically registered for the ESRP_DEFAULT render pass.
// to add it to a new render pass:
myNode->registerRenderPass(ESRP_PASS_1);
// and if you don't want it to render in the default pass:
myNode->unregisterRenderPass(ESRP_DEFAULT);
If all you want to do is change the ordering that scene nodes are rendered, this should do it.
But if you want to use a different material (a.k.a. rendering properties) for different passes, then you can only make it work with custom scene nodes. In YourCustomSceneNode::render() function, you would call driver->setMaterial() using a different material each time. To get the current render pass, use smgr->getSceneRenderPass().
I have a couple of ideas to further enhance this, but they 're not that trivial to implement and I wouldn't do it, unless the Irrlicht team agreed with it (too much work to do for me alone).
The most "correct" way would be to register a material for each pass, for each node. Then, for example, the above code could change to this:
Code: Select all
ISceneNode* myNode = smgr->add.....Node(...);
IMaterial* myMaterial1 = ...;
IMaterial* myMaterial2 = ...;
// to add it to a new render pass using myMaterial1:
myNode->registerRenderPass(ESRP_PASS_1, myMaterial1);
// to add it to a new render pass using myMaterial2:
myNode->registerRenderPass(ESRP_PASS_2, myMaterial2);
See where I 'm going? This would allow us to alter the rendering of the builtin scene nodes too

.
But this would mean to update all existing builtin scene nodes to use the material of the current render pass. Not *that* much of work, but my intention is not to create a huge patch that will never be accepted for inclusion to the core. I don't want to fork Irrlicht

.
Another benefit, which requires the renderpass-material assignment described above, is that it decouples us from the texture units limits. Let me explain:
Until Irrlicht 1.0, it allowed up to 2 texture units per-material. Ewww!
Now, 4 texture units per-material are allowed. This is an improvement,
but still a limitation.
I have created a shader to render a splatting terrain but this limit allows me to use only three different textures for the whole terrain (the fourth is used as alpha map).
Wouldn't it be nice if Irrlicht would allow me to assign 16

textures per-material? BUT HOW? you may wonder...
Simple: Irrlicht would see that we have exceeded the texture units count our graphics card supports and would clone the material 3 times, assigning 4 textures to each material and automatically adding this scene node to 3 additional render passes using the 3 new materials. And this would be a runtime decision, mind you. Meaning that if the user's card supports 8 texture units, Irrlicht would clone the material once and split the texture to 2 8-texture batches and render the scene node in 2 passes.
Or it could be done by incorporating render pass "knowledge" inside SMaterial. So the driver, when applying the material, would see what textures to fetch for the current pass.
Well, enough rant for one post. Let's see how this goes

.