Added support for proxy meshes as source of the shadow volume. This enables the use of a simplified version of a mesh for the generation of the shadow volume, which can significantly improve the render performance with shadow volumes. Patch provided by tonic.
git-svn-id: http://svn.code.sf.net/p/irrlicht/code/trunk@1477 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
parent
ceea796f8f
commit
e0168a9a89
@ -91,6 +91,7 @@ namespace scene
|
||||
creation is easier, but with this method there occur ugly
|
||||
looking artifacs when the camera is inside the shadow volume.
|
||||
These error do not occur with the ZFail method.
|
||||
\param shadowMesh: Optional custom mesh for shadow volume.
|
||||
\param id: Id of the shadow scene node. This id can be used to
|
||||
identify the node later.
|
||||
\param zfailmethod: If set to true, the shadow will use the
|
||||
@ -100,8 +101,8 @@ namespace scene
|
||||
\return Pointer to the created shadow scene node. This pointer
|
||||
should not be dropped. See IReferenceCounted::drop() for more
|
||||
information. */
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id=-1,
|
||||
bool zfailmethod=true, f32 infinity=10000.0f) = 0;
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh=0,
|
||||
s32 id=-1, bool zfailmethod=true, f32 infinity=10000.0f) = 0;
|
||||
|
||||
|
||||
//! Get a pointer to a joint in the mesh (if the mesh is a bone based mesh).
|
||||
|
@ -22,8 +22,13 @@ namespace scene
|
||||
IShadowVolumeSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id)
|
||||
: ISceneNode(parent, mgr, id) {}
|
||||
|
||||
//! sets the mesh from which the shadow volume should be generated.
|
||||
virtual void setMeshToRenderFrom(const IMesh* mesh) = 0;
|
||||
//! Sets the mesh from which the shadow volume should be generated.
|
||||
/** To optimize shadow rendering, use a simpler mesh for shadows.
|
||||
*/
|
||||
virtual void setShadowMesh(const IMesh* mesh) = 0;
|
||||
|
||||
//! Updates the shadow volumes for current light positions.
|
||||
virtual void updateShadowVolumes() = 0;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
@ -270,7 +270,7 @@ void CAnimatedMeshSceneNode::render()
|
||||
|
||||
|
||||
if (Shadow && PassCount==1)
|
||||
Shadow->setMeshToRenderFrom(m);
|
||||
Shadow->updateShadowVolumes();
|
||||
|
||||
// for debug purposes only:
|
||||
|
||||
@ -559,8 +559,8 @@ u32 CAnimatedMeshSceneNode::getMaterialCount() const
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode(s32 id,
|
||||
bool zfailmethod, f32 infinity)
|
||||
IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode(const IMesh* shadowMesh,
|
||||
s32 id, bool zfailmethod, f32 infinity)
|
||||
{
|
||||
if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER))
|
||||
return 0;
|
||||
@ -571,7 +571,10 @@ IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode(s32 id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
Shadow = new CShadowVolumeSceneNode(this, SceneManager, id, zfailmethod, infinity);
|
||||
if (!shadowMesh)
|
||||
shadowMesh = Mesh; // if null is given, use the mesh of node
|
||||
|
||||
Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity);
|
||||
return Shadow;
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,8 @@ namespace scene
|
||||
|
||||
//! Creates shadow volume scene node as child of this node
|
||||
//! and returns a pointer to it.
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id,
|
||||
bool zfailmethod=true, f32 infinity=10000.0f);
|
||||
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh,
|
||||
s32 id, bool zfailmethod=true, f32 infinity=10000.0f);
|
||||
|
||||
//! Returns a pointer to a child node, which has the same transformation as
|
||||
//! the corrsesponding joint, if the mesh in this scene node is a skinned mesh.
|
||||
|
@ -15,27 +15,28 @@ namespace scene
|
||||
|
||||
|
||||
//! constructor
|
||||
CShadowVolumeSceneNode::CShadowVolumeSceneNode(ISceneNode* parent,
|
||||
ISceneManager* mgr, s32 id,
|
||||
bool zfailmethod, f32 infinity)
|
||||
: IShadowVolumeSceneNode(parent, mgr, id), Indices(0), Vertices(0),
|
||||
Adjacency(0), FaceData(0), UseZFailMethod(zfailmethod),
|
||||
CShadowVolumeSceneNode::CShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent,
|
||||
ISceneManager* mgr, s32 id, bool zfailmethod, f32 infinity)
|
||||
: IShadowVolumeSceneNode(parent, mgr, id), Vertices(0), Indices(0),
|
||||
Adjacency(0), Edges(0), FaceData(0), ShadowMesh(0),
|
||||
IndexCountAllocated(0), VertexCountAllocated(0),
|
||||
IndexCount(0), VertexCount(0), ShadowVolumesUsed(0),
|
||||
Edges(0), EdgeCount(0), Infinity(infinity)
|
||||
IndexCount(0), VertexCount(0), EdgeCount(0), ShadowVolumesUsed(0),
|
||||
Infinity(infinity), UseZFailMethod(zfailmethod)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CShadowVolumeSceneNode");
|
||||
#endif
|
||||
|
||||
setShadowMesh(shadowMesh);
|
||||
setAutomaticCulling(scene::EAC_OFF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! destructor
|
||||
CShadowVolumeSceneNode::~CShadowVolumeSceneNode()
|
||||
{
|
||||
if (ShadowMesh)
|
||||
ShadowMesh->drop();
|
||||
|
||||
delete [] Edges;
|
||||
|
||||
for (u32 i=0; i<ShadowVolumes.size(); ++i)
|
||||
@ -48,7 +49,6 @@ CShadowVolumeSceneNode::~CShadowVolumeSceneNode()
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CShadowVolumeSceneNode::createShadowVolume(const core::vector3df& light)
|
||||
{
|
||||
SShadowVolume* svp = 0;
|
||||
@ -251,17 +251,26 @@ void CShadowVolumeSceneNode::createZPassVolume(s32 faceCount,
|
||||
}
|
||||
|
||||
|
||||
//! sets the mesh from which the shadow volume should be generated.
|
||||
void CShadowVolumeSceneNode::setMeshToRenderFrom(const IMesh* mesh)
|
||||
void CShadowVolumeSceneNode::setShadowMesh(const IMesh* mesh)
|
||||
{
|
||||
ShadowVolumesUsed = 0;
|
||||
if (ShadowMesh)
|
||||
ShadowMesh->drop();
|
||||
ShadowMesh = mesh;
|
||||
if (ShadowMesh)
|
||||
ShadowMesh->grab();
|
||||
}
|
||||
|
||||
s32 oldIndexCount = IndexCount;
|
||||
s32 oldVertexCount = VertexCount;
|
||||
|
||||
void CShadowVolumeSceneNode::updateShadowVolumes()
|
||||
{
|
||||
const s32 oldIndexCount = IndexCount;
|
||||
const s32 oldVertexCount = VertexCount;
|
||||
|
||||
VertexCount = 0;
|
||||
IndexCount = 0;
|
||||
ShadowVolumesUsed = 0;
|
||||
|
||||
const IMesh* const mesh = ShadowMesh;
|
||||
if (!mesh)
|
||||
return;
|
||||
|
||||
@ -270,7 +279,7 @@ void CShadowVolumeSceneNode::setMeshToRenderFrom(const IMesh* mesh)
|
||||
u32 i;
|
||||
s32 totalVertices = 0;
|
||||
s32 totalIndices = 0;
|
||||
u32 bufcnt = mesh->getMeshBufferCount();
|
||||
const u32 bufcnt = mesh->getMeshBufferCount();
|
||||
|
||||
for (i=0; i<bufcnt; ++i)
|
||||
{
|
||||
@ -350,9 +359,10 @@ void CShadowVolumeSceneNode::setMeshToRenderFrom(const IMesh* mesh)
|
||||
void CShadowVolumeSceneNode::OnRegisterSceneNode()
|
||||
{
|
||||
if (IsVisible)
|
||||
{
|
||||
SceneManager->registerNodeForRendering(this, scene::ESNRP_SHADOW);
|
||||
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,14 +18,19 @@ namespace scene
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
CShadowVolumeSceneNode(ISceneNode* parent, ISceneManager* mgr,
|
||||
CShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent, ISceneManager* mgr,
|
||||
s32 id, bool zfailmethod=true, f32 infinity=10000.0f);
|
||||
|
||||
//! destructor
|
||||
virtual ~CShadowVolumeSceneNode();
|
||||
|
||||
//! sets the mesh from which the shadow volume should be generated.
|
||||
virtual void setMeshToRenderFrom(const IMesh* mesh);
|
||||
//! Sets the mesh from which the shadow volume should be generated.
|
||||
/** To optimize shadow rendering, use a simpler mesh for shadows.
|
||||
*/
|
||||
virtual void setShadowMesh(const IMesh* mesh);
|
||||
|
||||
//! Updates the shadow volumes for current light positions.
|
||||
virtual void updateShadowVolumes();
|
||||
|
||||
//! pre render method
|
||||
virtual void OnRegisterSceneNode();
|
||||
@ -58,24 +63,30 @@ namespace scene
|
||||
|
||||
core::aabbox3d<f32> Box;
|
||||
|
||||
u16* Indices;
|
||||
// a shadow volume for every light
|
||||
core::array<SShadowVolume> ShadowVolumes;
|
||||
|
||||
core::vector3df* Vertices;
|
||||
u16* Indices;
|
||||
u16* Adjacency;
|
||||
bool* FaceData; // used for zfail method, if face is front facing
|
||||
bool UseZFailMethod;
|
||||
u16* Edges;
|
||||
// used for zfail method, if face is front facing
|
||||
bool* FaceData;
|
||||
|
||||
const scene::IMesh* ShadowMesh;
|
||||
|
||||
s32 IndexCountAllocated;
|
||||
s32 VertexCountAllocated;
|
||||
s32 IndexCount;
|
||||
s32 VertexCount;
|
||||
|
||||
core::array<SShadowVolume> ShadowVolumes; // a shadow volume for every light
|
||||
s32 ShadowVolumesUsed;
|
||||
|
||||
u16* Edges;
|
||||
s32 EdgeCount;
|
||||
|
||||
s32 ShadowVolumesUsed;
|
||||
|
||||
f32 Infinity;
|
||||
|
||||
bool UseZFailMethod;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
Loading…
x
Reference in New Issue
Block a user