Add IMeshSceneNode::setNodeRegistration to allow registering MeshSceneNodes to the SceneManager per buffer instead of per node

So far SceneManager always sorted Nodes per render stage.
Now we allow sorting per mesh-buffer per render stage by creating a new node for each mesh-buffer.
It's only supported for CMeshSceneNode so far.

This allows to enable better transparency sorting for meshes which have transparent buffers.
Previously those always got rendered in the order in which they got added and ignored mesh-buffer bounding-boxes, but just used the bbox of the full mesh. Now they can use the bbox for each meshbuffer which can sometimes avoid render errors.

Also depending on the scene this can be quite a bit faster because it can help reduce texture changes. We sort solid nodes per texture, but only per node. So nodes with several textures had a texture switch between rendering each meshbuffer. And those are rather expensive in Irrlicht right now (and we support no bindless textures yet...)

Lastly it's now also used to buffer the render-stage. Checking this twice (once in registering the node and once in render) constantly showed up in the profiler. Which was a bit surprising really, but anyway - now it's gone.

I tried to keep it working for all cases we had before (all kind of situations, like when people may want to call render() outside the SceneManager). But not (yet) supporting the case of changing the meshbuffers (adding or removing some) without calling setMesh() again. Reason is that this wasn't well supported before either (node materials never updated). So for now I just assume people will call setMesh() again when they change the mesh.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6483 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien
2023-05-04 16:07:18 +00:00
parent 9679fa7006
commit c4504c1d48
12 changed files with 752 additions and 481 deletions

View File

@ -15,6 +15,20 @@ namespace scene
class IShadowVolumeSceneNode;
class IMesh;
//! Option for nodes how to register themeselves at the SceneManager
enum ENodeRegistration
{
//! Each node registers once and renders all it's mesh-buffers
ENR_DEFAULT,
//! Register a new node per mesh-buffer at the SceneManager
//! It allows the SceneManager to sort in each render stage per buffer instead of per node.
//! This can be useful when having several transparent buffers in a mesh.
//! Depending on the scene (and hardware) this can have a positive or negative effect on performance.
//! It can avoid texture-switches, but adds nodes to sort and more matrix transformations are set.
ENR_PER_MESH_BUFFER
};
//! A scene node displaying a static mesh
class IMeshSceneNode : public ISceneNode
@ -28,9 +42,11 @@ public:
const core::vector3df& position = core::vector3df(0,0,0),
const core::vector3df& rotation = core::vector3df(0,0,0),
const core::vector3df& scale = core::vector3df(1,1,1))
: ISceneNode(parent, mgr, id, position, rotation, scale) {}
: ISceneNode(parent, mgr, id, position, rotation, scale)
, NodeRegistration(ENR_DEFAULT)
{}
//! Sets a new mesh to display
//! Sets a new mesh to display or update mesh when it changed
/** \param mesh Mesh to display. */
virtual void setMesh(IMesh* mesh) = 0;
@ -73,6 +89,23 @@ public:
/** This flag can be set by setReadOnlyMaterials().
\return Whether the materials are read-only. */
virtual bool isReadOnlyMaterials() const = 0;
//! Set how the node registers itself to the SceneManager
/** Note: Derived classes can ignore this flag, so think of it as a hint. */
virtual void setNodeRegistration(ENodeRegistration nodeRegistration)
{
NodeRegistration = nodeRegistration;
}
//! How does a node register itself to the SceneManager
/** Note: Derived classes may ignore this flag */
virtual ENodeRegistration getNodeRegistration() const
{
return NodeRegistration;
}
protected:
ENodeRegistration NodeRegistration;
};
} // end namespace scene

View File

@ -66,7 +66,7 @@ namespace scene
//! In this pass, lights are transformed into camera space and added to the driver
ESNRP_LIGHT =2,
//! This is used for sky boxes.
//! This is mostly used for sky boxes. Stage between light and solid.
ESNRP_SKY_BOX =4,
//! All normal objects can use this for registering themselves.