123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- *
- * ViewDependentShadow codes Copyright (C) 2008 Wojciech Lewandowski
- * Thanks to to my company http://www.ai.com.pl for allowing me free this work.
- */
- #ifndef OSGSHADOW_VIEWDEPENDENTSHADOWTECHINIQUE
- #define OSGSHADOW_VIEWDEPENDENTSHADOWTECHINIQUE 1
- #include <osg/Identifier>
- #include <osgShadow/ShadowTechnique>
- #include <osgShadow/Export>
- #include <map>
- namespace osgShadow {
- /**
- META_ViewDependentShadowTechniqueData macro defines initViewDependentData
- method used by derived shadow techniques to initialize their specific
- ViewData objects. initViewDependentData will be called from
- ViewDependentShadowTechnique base class to init derived class
- */
- #define META_ViewDependentShadowTechniqueData( ShadowTechnique, TechniqueData )\
- virtual ViewDependentShadowTechnique::ViewData * initViewDependentData \
- ( osgUtil::CullVisitor *cv, ViewDependentShadowTechnique::ViewData * vd ) \
- { \
- TechniqueData* td = dynamic_cast<TechniqueData*>( vd ); \
- if ( !td ) td = new TechniqueData; \
- td->init( this, cv ); \
- return td; \
- }
- /**
- ViewDependentShadowTechnique is a base class for all
- View Dependent Shadow techniques. It defines fundamental object structure
- and methods to manage separate shadow resources for each view of the scene.
- By view we understand osg::View or SceneView instance and their associated
- Camera. Typical osg application has one or more such views. View Dependent
- Shadow techniques manage shadow generation for them.
- View Dependent Shadow techniques are used to optimize shadow algorithms for
- part of the scene seen on the view. If rest of the scene is behind view
- frustum, there is no sense in computing shadows for it. Since in practice we
- often use 3d databases extending far beyond current camera frustum View
- Dependent Shadow approach may produce much better shadows.
- The other goal is to provide framework for thread safe rendering of
- the shadows. It allows to use shadows with different OSG threading models.
- Conceptually ViewDependentShadowTechnique is similar to osgSim::OverlayNode.
- Its a container class for number of ViewData (or ViewData derived) objects
- doing actual shadow work for each of the scene views.
- But ViewDependentShadowTechnique is intended as foundation layer for all
- derived classes so in some way it extends osgSim::OverlayNode approach a bit.
- HOW IT WORKS:
- ViewDependendentShadowTechnique is derived from osgShadow::ShadowTechnique
- and as such overrides virtual methods of osgShadow::ShadowTechnique.
- But most of the shadow dirty work is done by ViewData objects,
- ViewDependendentShadowTechnique::cull is the only osgShadow::ShadowTechnique
- method where ViewDependendentShadowTechnique does something significant:
- What ViewDependentShadowTechnique::cull( CullVisitor & cv ) does ?
- It identifies View. CullVisitor ptr is used as View identificator.
- In practice we do not check and interpret what are actual Views and SceneViews
- set up by application. We focus on Camera and CullVisitors as a identificators
- of views. We can safely do this because each such view will have associated
- unique CullVisitor used to cull the scene in every frame.
- Based on CullVisitor ptr passed to cull method, associated Technique::ViewData
- object is created (if necessary) and then seleced. Then control is passed to
- this ViewData object. So, each view has its associated unique ViewData
- (or derived) object performing dirty work of shadow resources management and
- shadow generation for the view.
- To support creation of classes derived from ViewDependentShadowTechnique it
- was necessary to provide mechanism to override ViewData and allow for
- initialization of new derived ViewData objects. Creation and initialization
- is performed when ViewDependendentShadowTechnique::cull gets called with
- CullVistor ptr which does not yet have associated ViewData object. When it
- happens, virtual initViewDependentData method is called to give
- derived techniques a chance to allocate and iniitalize its specific
- resources as new ViewData derived instance. In practice initViewDependentData
- in derived techniques should look the same as in base class so as a convenience
- it was defined as META_ViewDependentShadowTechnique macro. Derived techniques
- use this macro to override initViewDependentData method for their usage.
- After ViewData derived object is construted and selected, control is passed
- to this object by call to virtual ViewData::cull method. The rest of work
- is the done by this object. ViewDependentShadowTechnique::ViewData is intended
- as a base class so it does nothing. In practice the rest of dirty work will
- do new ViewData classes implemented in derived techniques.
- */
- class OSGSHADOW_EXPORT ViewDependentShadowTechnique
- : public osgShadow::ShadowTechnique
- {
- public:
- /**
- osgShadow::ShadowTechnique equivalent methods for view dependent techniques
- */
- /** Classic OSG constructor */
- ViewDependentShadowTechnique( void );
- /** Classic OSG cloning constructor */
- ViewDependentShadowTechnique(
- const ViewDependentShadowTechnique& vdst,
- const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
- /** Declaration of standard OSG object methods */
- META_Object( osgShadow, ViewDependentShadowTechnique );
- /** Dirty view data bits and force update of view data resources */
- virtual void dirty();
- /** Initialize the ShadowedScene and some data structures.*/
- virtual void init();
- /** Run the update traversal of the ShadowedScene and update any local cached data structures.*/
- virtual void update(osg::NodeVisitor& nv);
- /** Run the cull traversal of the ShadowedScene and set up the rendering for this ShadowTechnique.*/
- virtual void cull(osgUtil::CullVisitor& cv);
- /** Clean scene graph from any shadow technique specific nodes, state and drawables.*/
- virtual void cleanSceneGraph();
- /** Traverse shadow scene graph.*/
- virtual void traverse(osg::NodeVisitor& nv);
- /** Resize any per context GLObject buffers to specified size. */
- virtual void resizeGLObjectBuffers(unsigned int maxSize);
- /** If State is non-zero, this function releases any associated OpenGL objects for
- * the specified graphics context. Otherwise, releases OpenGL objects
- * for all graphics contexts. */
- virtual void releaseGLObjects(osg::State* = 0) const;
- protected:
- /** Classic protected OSG destructor */
- ~ViewDependentShadowTechnique( void );
- /**
- Base container class for view dependent shadow resources.
- Techniques based on ViewDependentShadowTechnique will usually define
- similar struct and derive it from ViewData to contain their specufic resources.
- */
- struct OSGSHADOW_EXPORT ViewData: public osg::Referenced
- {
- virtual const char* className() const { return "ViewData"; }
- /**
- Method called upon ViewData instance to initialize internal variables
- */
- virtual void init
- ( ViewDependentShadowTechnique *st, osgUtil::CullVisitor *cv );
- /**
- Method called by ViewDependentShadowTechnique to allow ViewData
- do the hard work computing shadows for its associated view
- */
- virtual void cull();
- /**
- Dirty is called by parent ViewDependentShadowTechnique to force
- update of resources after some of them were modified in parent technique
- */
- virtual void dirty( bool flag );
- /**
- Simple constructor zeroing all variables.
- */
- ViewData(): _dirty( true ), _cv( NULL ), _st( NULL ) { };
- /**
- Mutex used to guard _dirty flag from override in case when parent technique calls
- dirty() simultaneously with ViewData while it is updating resources inside init method.
- */
- OpenThreads::Mutex _mutex;
- /**
- Dirty flag tells this instance to update its resources
- */
- bool _dirty;
- /**
- View's CullVisitor associated with this ViewData instance
- */
- osg::observer_ptr< osgUtil::CullVisitor > _cv;
- /**
- Parent ViewDependentShadowTechnique
- */
- osg::observer_ptr< ViewDependentShadowTechnique > _st;
- virtual void resizeGLObjectBuffers(unsigned int /*maxSize*/) {}
- /** If State is non-zero, this function releases any associated OpenGL objects for
- * the specified graphics context. Otherwise, releases OpenGL objects
- * for all graphics contexts. */
- virtual void releaseGLObjects(osg::State* = 0) const {}
- };
- /**
- Map of view dependent data per view cull visitor (CVs are used as indices)
- ViewDependentShadowTechnique uses this map to find VieData for each cull vitior
- */
- typedef std::map< osg::ref_ptr< osg::Identifier >,
- osg::ref_ptr< ViewData > > ViewDataMap;
- ViewDataMap _viewDataMap;
- /**
- Mutex used to serialize accesses to ViewDataMap
- */
- OpenThreads::Mutex _viewDataMapMutex;
- /** Return view dependent data for the cull visitor */
- virtual ViewDependentShadowTechnique::ViewData * getViewDependentData( osgUtil::CullVisitor * cv );
- /** Define view dependent data for the cull visitor */
- virtual void setViewDependentData( osgUtil::CullVisitor * cv, ViewDependentShadowTechnique::ViewData * data );
- /**
- Declare standard initViewDependentData method.
- */
- META_ViewDependentShadowTechniqueData( ViewDependentShadowTechnique, ViewData )
- };
- } // namespace osgShadow
- #endif
|