From 95befaf1ede8087b09e7ffdfe31a557b78909ae5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 8 Feb 2007 17:23:40 +0000 Subject: [PATCH] Flesh out more of basic ShadowTechnique and ShadowedScene API. --- examples/osgshadow/osgshadow.cpp | 17 ++++++++++- include/osgShadow/ShadowTechnique | 17 +++++++++++ include/osgShadow/ShadowedScene | 13 ++++---- src/osgShadow/ShadowTechnique.cpp | 49 +++++++++++++++++++++++++++++-- src/osgShadow/ShadowedScene.cpp | 48 ++++++++++++++++++++---------- 5 files changed, 120 insertions(+), 24 deletions(-) diff --git a/examples/osgshadow/osgshadow.cpp b/examples/osgshadow/osgshadow.cpp index a4b63fdfb..7ee216ab7 100644 --- a/examples/osgshadow/osgshadow.cpp +++ b/examples/osgshadow/osgshadow.cpp @@ -23,6 +23,8 @@ #include #include +#include +#include #include #include @@ -566,6 +568,9 @@ int main(int argc, char** argv) while (arguments.read("--two-sided")) drawMode = osgShadow::ShadowVolumeGeometry::STENCIL_TWO_SIDED; while (arguments.read("--two-pass")) drawMode = osgShadow::ShadowVolumeGeometry::STENCIL_TWO_PASS; + bool ShadowVolume = false; + while (arguments.read("--ShadowVolume")) ShadowVolume = true; + // set up the camera manipulators. { @@ -680,7 +685,17 @@ int main(int argc, char** argv) osg::ref_ptr light = new osg::Light; light->setPosition(lightpos); - if (!doShadow) + if (ShadowVolume) + { + osg::ref_ptr shadowedScene = new osgShadow::ShadowedScene; + + shadowedScene->setShadowTechnique(new osgShadow::ShadowVolume); + + shadowedScene->addChild(model.get()); + + group->addChild(shadowedScene.get()); + } + else if (!doShadow) { group->addChild(model.get()); diff --git a/include/osgShadow/ShadowTechnique b/include/osgShadow/ShadowTechnique index 01ebf7ed4..e60fad867 100644 --- a/include/osgShadow/ShadowTechnique +++ b/include/osgShadow/ShadowTechnique @@ -35,11 +35,28 @@ class OSGSHADOW_EXPORT ShadowTechnique : public osg::Object ShadowTechnique(const ShadowTechnique& es, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); META_Object(osgShadow, ShadowTechnique); + + ShadowedScene* getShadowedScene() { return _shadowedScene; } + virtual void init(); + + virtual void update(osg::NodeVisitor& nv); + + virtual void cull(osg::NodeVisitor& nv); + + virtual void traverse(osg::NodeVisitor& nv); + + virtual void dirty() { _dirty = true; } + protected : virtual ~ShadowTechnique() {} + friend class ShadowedScene; + + ShadowedScene* _shadowedScene; + bool _dirty; + }; } diff --git a/include/osgShadow/ShadowedScene b/include/osgShadow/ShadowedScene index 29f5ad226..8ab5867a6 100644 --- a/include/osgShadow/ShadowedScene +++ b/include/osgShadow/ShadowedScene @@ -26,7 +26,8 @@ namespace osgShadow { /** ShadowedScene provides a mechansim for decorating a scene that the needs to have shadows cast upon it.*/ class OSGSHADOW_EXPORT ShadowedScene : public osg::Group { - public : + public: + ShadowedScene(); ShadowedScene(const ShadowedScene& es, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); @@ -44,11 +45,13 @@ class OSGSHADOW_EXPORT ShadowedScene : public osg::Group void setShadowTechnique(ShadowTechnique* technique); ShadowTechnique* getShadowTechnique() { return _shadowTechnique.get(); } const ShadowTechnique* getShadowTechnique() const { return _shadowTechnique.get(); } - - - protected : - virtual ~ShadowedScene() {} + /** Dirty any cache data structures held in the attached ShadowTechnqiue.*/ + void dirty(); + + protected: + + virtual ~ShadowedScene(); unsigned int _recievesShadowTraversalMask; unsigned int _castsShadowTraversalMask; diff --git a/src/osgShadow/ShadowTechnique.cpp b/src/osgShadow/ShadowTechnique.cpp index 49a464277..fd934539e 100644 --- a/src/osgShadow/ShadowTechnique.cpp +++ b/src/osgShadow/ShadowTechnique.cpp @@ -12,14 +12,59 @@ */ #include +#include +#include using namespace osgShadow; -ShadowTechnique::ShadowTechnique() +ShadowTechnique::ShadowTechnique(): + _shadowedScene(0), + _dirty(true) { } ShadowTechnique::ShadowTechnique(const ShadowTechnique& copy, const osg::CopyOp& copyop): - osg::Object(copy,copyop) + osg::Object(copy,copyop), + _shadowedScene(0), + _dirty(true) { } + +void ShadowTechnique::init() +{ + osg::notify(osg::NOTICE)<osg::Group::traverse(nv); +} + +void ShadowTechnique::cull(osg::NodeVisitor& nv) +{ + osg::notify(osg::NOTICE)<osg::Group::traverse(nv); +} + +void ShadowTechnique::traverse(osg::NodeVisitor& nv) +{ + if (!_shadowedScene) return; + + if (nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR) + { + if (_dirty) init(); + + update(nv); + } + else if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR) + { + cull(nv); + } + else + { + _shadowedScene->osg::Group::traverse(nv); + } +} diff --git a/src/osgShadow/ShadowedScene.cpp b/src/osgShadow/ShadowedScene.cpp index 68ffb694c..fc4989dd7 100644 --- a/src/osgShadow/ShadowedScene.cpp +++ b/src/osgShadow/ShadowedScene.cpp @@ -32,26 +32,42 @@ ShadowedScene::ShadowedScene(const ShadowedScene& copy, const osg::CopyOp& copyo setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); } +ShadowedScene::~ShadowedScene() +{ + setShadowTechnique(0); +} + void ShadowedScene::traverse(osg::NodeVisitor& nv) { - if (nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR) + if (_shadowTechnique.valid()) { - Group::traverse(nv); - return; + _shadowTechnique->traverse(nv); } - - if (nv.getVisitorType() != osg::NodeVisitor::CULL_VISITOR) + else { - Group::traverse(nv); - return; + osg::Group::traverse(nv); + } +} + +void ShadowedScene::setShadowTechnique(ShadowTechnique* technique) +{ + if (_shadowTechnique == technique) return; + + if (_shadowTechnique.valid()) _shadowTechnique->_shadowedScene = 0; + + _shadowTechnique = technique; + + if (_shadowTechnique.valid()) + { + _shadowTechnique->_shadowedScene = this; + _shadowTechnique->dirty(); + } +} + +void ShadowedScene::dirty() +{ + if (_shadowTechnique.valid()) + { + _shadowTechnique->dirty(); } - - osgUtil::CullVisitor* cv = dynamic_cast(&nv); - if (!cv) - { - Group::traverse(nv); - return; - } - - Group::traverse(nv); }