irrlicht/source/Irrlicht/CMeshSceneNode.cpp

474 lines
13 KiB
C++
Raw Normal View History

// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CMeshSceneNode.h"
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
2023-05-04 18:07:18 +02:00
#include "CBufferRenderNode.h"
#include "IVideoDriver.h"
#include "ISceneManager.h"
#include "S3DVertex.h"
#include "ICameraSceneNode.h"
#include "IMeshCache.h"
#include "IAnimatedMesh.h"
#include "IMaterialRenderer.h"
#include "IFileSystem.h"
#ifdef _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_
#include "CShadowVolumeSceneNode.h"
#else
#include "IShadowVolumeSceneNode.h"
#endif // _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_
namespace irr
{
namespace scene
{
//! constructor
CMeshSceneNode::CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::vector3df& rotation,
const core::vector3df& scale)
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
2023-05-04 18:07:18 +02:00
: IMeshSceneNode(parent, mgr, id, position, rotation, scale)
, Mesh(0), Shadow(0), ReadOnlyMaterials(false)
{
#ifdef _DEBUG
setDebugName("CMeshSceneNode");
#endif
setMesh(mesh);
}
//! destructor
CMeshSceneNode::~CMeshSceneNode()
{
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
2023-05-04 18:07:18 +02:00
setUsedBufferRenderNodes(0);
if (Shadow)
Shadow->drop();
if (Mesh)
Mesh->drop();
}
//! frame
void CMeshSceneNode::OnRegisterSceneNode()
{
Unify checks if materials should use transparent render pass with new IVideoDriver::needsTransparentRenderPass function. Fix bug that AnimatedMeshSceneNode ignored ReadOnlyMaterials flag when checking materials for transparent render passes. Make IVideoDriver::getMaterialRenderer const. Fix bugs in COctreeSceneNode, CMeshSceneNode and CAnimatedMeshSceneNode where check for transparency in OnRegisterSceneNode() and in render() where no longer identical (those got added after Irrlicht 1.8). Some notes for future: - Maybe we should have a getRenderPass instead of just needsTransparentRenderPass, but this way the code didn't need so much changes and behaves (aside from fixes) pretty much as before. - Still wondering if the default implementation in CNullDriver::needsTransparentRenderPass should always return false when SMaterial.ZWriteEnable is set to EZW_ON. This might be nicer with another material flag. Thought then we might want a material enum to choose the renderpass and that's more work. And we get some recursion as needsTransparentRenderPass might want to check result of getWriteZBuffer which calls needsTransparentRenderPass, so we might need a second function or an additional flag there. But return false when SMaterial.ZWriteEnable == EZW_ON could still be done as EZW_ON is a new flag so existing behavior shouldn't break. I just don't know right now if having an extra render pass for transparent nodes might still make sense even when zbuffer is not written or if that's really the only reason to do that. Any feedback anyone? git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6033 dfc29bdd-3216-0410-991c-e03cc46cb475
2020-01-03 12:13:57 +01:00
if (IsVisible && Mesh)
{
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
2023-05-04 18:07:18 +02:00
Box = Mesh->getBoundingBox(); // in case mesh was modified, as clipping happens when registering nodes for rendering
// Because this node supports rendering of mixed mode meshes consisting of
// transparent and solid material at the same time, we need to go through all
// materials, check of what type they are and register this node for the right
// render pass according to that.
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
2023-05-04 18:07:18 +02:00
// Also some buffers might register into their own render node
video::IVideoDriver* driver = SceneManager->getVideoDriver();
int transparentCount = 0;
int solidCount = 0;
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
2023-05-04 18:07:18 +02:00
if ( !(DebugDataVisible & scene::EDS_HALF_TRANSPARENCY) )
{
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
2023-05-04 18:07:18 +02:00
// count transparent and solid materials in this scene node
const u32 numMaterials = ReadOnlyMaterials ? Mesh->getMeshBufferCount() : Materials.size();
const bool parentRenders = NodeRegistration == ENR_DEFAULT || numMaterials < 2;
for (u32 i=0; i<numMaterials; ++i)
{
const video::SMaterial& material = ReadOnlyMaterials ? Mesh->getMeshBuffer(i)->getMaterial() : Materials[i];
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
2023-05-04 18:07:18 +02:00
if ( driver->needsTransparentRenderPass(material) )
{
BufferRenderNodes[i]->prepareRendering(ESNRP_TRANSPARENT, parentRenders);
if ( parentRenders )
{
++transparentCount;
}
}
else
{
BufferRenderNodes[i]->prepareRendering(ESNRP_SOLID, parentRenders);
if ( parentRenders )
{
++solidCount;
}
}
}
}
// register according to material types counted
if (solidCount)
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
2023-05-04 18:07:18 +02:00
SceneManager->registerNodeForRendering(this, ESNRP_SOLID);
if (transparentCount)
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
2023-05-04 18:07:18 +02:00
SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT);
if (Shadow) // update (not render) shadow node after lights have been set up
SceneManager->registerNodeForRendering(this, ESNRP_SKY_BOX);
if (DebugDataVisible) // debug data has it's own render-stage between solid and transparence
SceneManager->registerNodeForRendering(this, ESNRP_SHADOW);
ISceneNode::OnRegisterSceneNode();
}
}
//! renders the node.
void CMeshSceneNode::render()
{
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
2023-05-04 18:07:18 +02:00
if (!Mesh )
return;
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
2023-05-04 18:07:18 +02:00
const E_SCENE_NODE_RENDER_PASS renderPass = SceneManager->getSceneNodeRenderPass();
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
2023-05-04 18:07:18 +02:00
if ( renderPass == ESNRP_SKY_BOX )
{
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
2023-05-04 18:07:18 +02:00
if (Shadow )
Shadow->updateShadowVolumes();
}
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
2023-05-04 18:07:18 +02:00
else if ( renderPass == ESNRP_SHADOW )
{
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
2023-05-04 18:07:18 +02:00
// for debug purposes only
if ( DebugDataVisible )
{
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
2023-05-04 18:07:18 +02:00
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
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
2023-05-04 18:07:18 +02:00
// render with half transparency
if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY)
{
for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
{
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
2023-05-04 18:07:18 +02:00
irr::video::SMaterial mat = Materials[g];
mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
driver->setMaterial(mat);
driver->drawMeshBuffer(Mesh->getMeshBuffer(g));
}
}
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
2023-05-04 18:07:18 +02:00
video::SMaterial m;
m.Lighting = false;
m.AntiAliasing=0;
driver->setMaterial(m);
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
2023-05-04 18:07:18 +02:00
if (DebugDataVisible & scene::EDS_BBOX)
{
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
2023-05-04 18:07:18 +02:00
driver->draw3DBox(Box, video::SColor(255,255,255,255));
}
if (DebugDataVisible & scene::EDS_BBOX_BUFFERS)
{
for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
{
driver->draw3DBox(
Mesh->getMeshBuffer(g)->getBoundingBox(),
video::SColor(255,190,128,128));
}
}
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
2023-05-04 18:07:18 +02:00
if (DebugDataVisible & scene::EDS_NORMALS)
{
// draw normals
const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH);
const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR);
const u32 count = Mesh->getMeshBufferCount();
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
2023-05-04 18:07:18 +02:00
for (u32 i=0; i != count; ++i)
{
driver->drawMeshBufferNormals(Mesh->getMeshBuffer(i), debugNormalLength, debugNormalColor);
}
}
// show mesh
if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)
{
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
2023-05-04 18:07:18 +02:00
m.Wireframe = true;
driver->setMaterial(m);
for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
{
driver->drawMeshBuffer(Mesh->getMeshBuffer(g));
}
}
}
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
2023-05-04 18:07:18 +02:00
}
else // solid, transparent or unknown (none when render is called without SceneManager) render stages
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
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
2023-05-04 18:07:18 +02:00
// render buffers, or at least those which don't render in their own node
for (u32 i=0; i<BufferRenderNodes.size(); ++i)
{
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
2023-05-04 18:07:18 +02:00
CBufferRenderNode* bufRenderNode = BufferRenderNodes[i];
if ( bufRenderNode->getDoesParentRender())
{
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
2023-05-04 18:07:18 +02:00
E_SCENE_NODE_RENDER_PASS bufferRenderPass = bufRenderNode->getRenderPass();
// render() called without OnRegisterSceneNode, but still wants to render in a specific render stage
// Note: Not checking transparency every time, as check got slightly expensive (I think it's prone to cache-misses)
if ( bufferRenderPass == ESNRP_NONE && renderPass > ESNRP_NONE )
{
if ( driver->needsTransparentRenderPass(getMaterial(i)) )
{
bufferRenderPass = ESNRP_TRANSPARENT;
}
else
{
bufferRenderPass = ESNRP_SOLID;
}
}
if ( bufRenderNode->getRenderPass() == renderPass )
bufRenderNode->renderBuffer(driver);
}
}
}
}
//! Removes a child from this scene node.
//! Implemented here, to be able to remove the shadow properly, if there is one,
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
2023-05-04 18:07:18 +02:00
//! or to remove attached children.
bool CMeshSceneNode::removeChild(ISceneNode* child)
{
if (child && Shadow == child)
{
Shadow->drop();
Shadow = 0;
}
return ISceneNode::removeChild(child);
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CMeshSceneNode::getBoundingBox() const
{
return Mesh ? Mesh->getBoundingBox() : Box;
}
//! returns the material based on the zero based index i. To get the amount
//! of materials used by this scene node, use getMaterialCount().
//! This function is needed for inserting the node into the scene hierarchy on a
//! optimal position for minimizing renderstate changes, but can also be used
//! to directly modify the material of a scene node.
video::SMaterial& CMeshSceneNode::getMaterial(u32 i)
{
if (Mesh && ReadOnlyMaterials && i<Mesh->getMeshBufferCount())
{
ReadOnlyMaterial = Mesh->getMeshBuffer(i)->getMaterial();
return ReadOnlyMaterial;
}
if (i >= Materials.size())
return ISceneNode::getMaterial(i);
return Materials[i];
}
//! returns amount of materials used by this scene node.
u32 CMeshSceneNode::getMaterialCount() const
{
if (Mesh && ReadOnlyMaterials)
return Mesh->getMeshBufferCount();
return Materials.size();
}
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
2023-05-04 18:07:18 +02:00
void CMeshSceneNode::setUsedBufferRenderNodes(irr::u32 num)
{
if ( BufferRenderNodes.size() > num )
{
for ( irr::u32 i=num; i<BufferRenderNodes.size(); ++i )
BufferRenderNodes[i]->drop();
BufferRenderNodes.erase(num, BufferRenderNodes.size()-num);
}
else if ( BufferRenderNodes.size() < num )
{
for ( irr::u32 i=BufferRenderNodes.size(); i < num; ++i )
{
BufferRenderNodes.push_back( new CBufferRenderNode(*this, SceneManager, i) );
}
}
}
//! Sets a new mesh
void CMeshSceneNode::setMesh(IMesh* mesh)
{
if (mesh)
{
mesh->grab();
if (Mesh)
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
2023-05-04 18:07:18 +02:00
{
Mesh->drop();
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
2023-05-04 18:07:18 +02:00
}
Mesh = mesh;
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
2023-05-04 18:07:18 +02:00
// Note: Mesh can change amount of meshbuffers later and we don't handle that so far so that would cause trouble
// For now assuming users call setMesh again in that case
copyMaterials();
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
2023-05-04 18:07:18 +02:00
setUsedBufferRenderNodes(Mesh ? Mesh->getMeshBufferCount() : 0);
}
}
//! Creates shadow volume scene node as child of this node
//! and returns a pointer to it.
IShadowVolumeSceneNode* CMeshSceneNode::addShadowVolumeSceneNode(
const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity)
{
#ifdef _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_
if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER))
return 0;
if (!shadowMesh)
shadowMesh = Mesh; // if null is given, use the mesh of node
if (Shadow)
Shadow->drop();
Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity);
return Shadow;
#else
return 0;
#endif
}
void CMeshSceneNode::copyMaterials()
{
Materials.clear();
if (Mesh)
{
video::SMaterial mat;
for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i)
{
IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (mb)
mat = mb->getMaterial();
Materials.push_back(mat);
}
}
}
//! Writes attributes of the scene node.
void CMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
IMeshSceneNode::serializeAttributes(out, options);
if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename)
{
const io::path path = SceneManager->getFileSystem()->getRelativeFilename(
SceneManager->getFileSystem()->getAbsolutePath(SceneManager->getMeshCache()->getMeshName(Mesh).getPath()),
options->Filename);
out->addString("Mesh", path.c_str());
}
else
out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str());
out->addBool("ReadOnlyMaterials", ReadOnlyMaterials);
}
//! Reads attributes of the scene node.
void CMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
io::path oldMeshStr = SceneManager->getMeshCache()->getMeshName(Mesh);
io::path newMeshStr = in->getAttributeAsString("Mesh");
ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials");
if (newMeshStr != "" && oldMeshStr != newMeshStr)
{
IMesh* newMesh = 0;
IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());
if (newAnimatedMesh)
newMesh = newAnimatedMesh->getMesh(0);
if (newMesh)
setMesh(newMesh);
}
// optional attribute to assign the hint to the whole mesh
if (in->existsAttribute("HardwareMappingHint") &&
in->existsAttribute("HardwareMappingBufferType"))
{
scene::E_HARDWARE_MAPPING mapping = scene::EHM_NEVER;
scene::E_BUFFER_TYPE bufferType = scene::EBT_NONE;
core::stringc smapping = in->getAttributeAsString("HardwareMappingHint");
if (smapping.equals_ignore_case("static"))
mapping = scene::EHM_STATIC;
else if (smapping.equals_ignore_case("dynamic"))
mapping = scene::EHM_DYNAMIC;
else if (smapping.equals_ignore_case("stream"))
mapping = scene::EHM_STREAM;
core::stringc sbufferType = in->getAttributeAsString("HardwareMappingBufferType");
if (sbufferType.equals_ignore_case("vertex"))
bufferType = scene::EBT_VERTEX;
else if (sbufferType.equals_ignore_case("index"))
bufferType = scene::EBT_INDEX;
else if (sbufferType.equals_ignore_case("vertexindex"))
bufferType = scene::EBT_VERTEX_AND_INDEX;
IMesh* mesh = getMesh();
if (mesh)
mesh->setHardwareMappingHint(mapping, bufferType);
}
IMeshSceneNode::deserializeAttributes(in, options);
}
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
/* In this way it is possible to change the materials a mesh causing all mesh scene nodes
referencing this mesh to change too. */
void CMeshSceneNode::setReadOnlyMaterials(bool readonly)
{
ReadOnlyMaterials = readonly;
}
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
bool CMeshSceneNode::isReadOnlyMaterials() const
{
return ReadOnlyMaterials;
}
//! Creates a clone of this scene node and its children.
ISceneNode* CMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
if (!newParent)
newParent = Parent;
if (!newManager)
newManager = SceneManager;
CMeshSceneNode* nb = new CMeshSceneNode(Mesh, newParent,
newManager, ID, RelativeTranslation, RelativeRotation, RelativeScale);
nb->cloneMembers(this, newManager);
nb->ReadOnlyMaterials = ReadOnlyMaterials;
nb->Materials = Materials;
nb->Shadow = Shadow;
if ( nb->Shadow )
nb->Shadow->grab();
if (newParent)
nb->drop();
return nb;
}
} // end namespace scene
} // end namespace irr