| 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|---|
| 2 | * |
|---|
| 3 | * This library is open source and may be redistributed and/or modified under |
|---|
| 4 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|---|
| 5 | * (at your option) any later version. The full license is in LICENSE file |
|---|
| 6 | * included with this distribution, and on the openscenegraph.org website. |
|---|
| 7 | * |
|---|
| 8 | * This library is distributed in the hope that it will be useful, |
|---|
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | * OpenSceneGraph Public License for more details. |
|---|
| 12 | * |
|---|
| 13 | * ViewDependentShadow codes Copyright (C) 2008 Wojciech Lewandowski |
|---|
| 14 | * Thanks to to my company http://www.ai.com.pl for allowing me free this work. |
|---|
| 15 | */ |
|---|
| 16 | |
|---|
| 17 | #ifndef OSGSHADOW_VIEWDEPENDENTSHADOWTECHINIQUE |
|---|
| 18 | #define OSGSHADOW_VIEWDEPENDENTSHADOWTECHINIQUE 1 |
|---|
| 19 | |
|---|
| 20 | #include <osgShadow/ShadowTechnique> |
|---|
| 21 | #include <map> |
|---|
| 22 | #include <osgShadow/Export> |
|---|
| 23 | |
|---|
| 24 | namespace osgShadow { |
|---|
| 25 | /** |
|---|
| 26 | META_ViewDependentShadowTechniqueData macro defines initViewDependentData |
|---|
| 27 | method used by derived shadow techniques to initialize their specific |
|---|
| 28 | ViewData objects. initViewDependentData will be called from |
|---|
| 29 | ViewDependentShadowTechnique base class to init derived class |
|---|
| 30 | */ |
|---|
| 31 | #define META_ViewDependentShadowTechniqueData( ShadowTechnique, TechniqueData )\ |
|---|
| 32 | virtual ViewDependentShadowTechnique::ViewData * initViewDependentData \ |
|---|
| 33 | ( osgUtil::CullVisitor *cv, ViewDependentShadowTechnique::ViewData * vd ) \ |
|---|
| 34 | { \ |
|---|
| 35 | TechniqueData* td = dynamic_cast<TechniqueData*>( vd ); \ |
|---|
| 36 | if ( !td ) td = new TechniqueData; \ |
|---|
| 37 | td->init( this, cv ); \ |
|---|
| 38 | return td; \ |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | /** |
|---|
| 42 | ViewDependentShadowTechnique is a base class for all |
|---|
| 43 | View Dependent Shadow techniques. It defines fundamental object structure |
|---|
| 44 | and methods to manage separate shadow resources for each view of the scene. |
|---|
| 45 | By view we understand osg::View or SceneView instance and their associated |
|---|
| 46 | Camera. Typical osg application has one or more such views. View Dependent |
|---|
| 47 | Shadow techniques manage shadow generation for them. |
|---|
| 48 | |
|---|
| 49 | View Dependent Shadow techniques are used to optimize shadow algorithms for |
|---|
| 50 | part of the scene seen on the view. If rest of the scene is behind view |
|---|
| 51 | frustum, there is no sense in computing shadows for it. Since in practice we |
|---|
| 52 | often use 3d databases extending far beyond current camera frustum View |
|---|
| 53 | Dependent Shadow approach may produce much better shadows. |
|---|
| 54 | |
|---|
| 55 | The other goal is to provide framework for thread safe rendering of |
|---|
| 56 | the shadows. It allows to use shadows with different OSG threading models. |
|---|
| 57 | |
|---|
| 58 | Conceptually ViewDependentShadowTechnique is similar to osgSim::OverlayNode. |
|---|
| 59 | Its a container class for number of ViewData (or ViewData derived) objects |
|---|
| 60 | doing actual shadow work for each of the scene views. |
|---|
| 61 | |
|---|
| 62 | But ViewDependentShadowTechnique is intended as foundation layer for all |
|---|
| 63 | derived classes so in some way it extends osgSim::OverlayNode approach a bit. |
|---|
| 64 | |
|---|
| 65 | HOW IT WORKS: |
|---|
| 66 | |
|---|
| 67 | ViewDependendentShadowTechnique is derived from osgShadow::ShadowTechnique |
|---|
| 68 | and as such overrides virtual methods of osgShadow::ShadowTechnique. |
|---|
| 69 | But most of the shadow dirty work is done by ViewData objects, |
|---|
| 70 | ViewDependendentShadowTechnique::cull is the only osgShadow::ShadowTechnique |
|---|
| 71 | method where ViewDependendentShadowTechnique does something significant: |
|---|
| 72 | |
|---|
| 73 | What ViewDependentShadowTechnique::cull( CullVisitor & cv ) does ? |
|---|
| 74 | It identifies View. CullVisitor ptr is used as View identificator. |
|---|
| 75 | In practice we do not check and interpret what are actual Views and SceneViews |
|---|
| 76 | set up by application. We focus on Camera and CullVisitors as a identificators |
|---|
| 77 | of views. We can safely do this because each such view will have associated |
|---|
| 78 | unique CullVisitor used to cull the scene in every frame. |
|---|
| 79 | |
|---|
| 80 | Based on CullVisitor ptr passed to cull method, associated Technique::ViewData |
|---|
| 81 | object is created (if neccessary) and then seleced. Then control is passed to |
|---|
| 82 | this ViewData object. So, each view has its associated unique ViewData |
|---|
| 83 | (or derived) object performing dirty work of shadow resources management and |
|---|
| 84 | shadow generation for the view. |
|---|
| 85 | |
|---|
| 86 | To support creation of classes derived from ViewDependentShadowTechnique it |
|---|
| 87 | was neccessary to provide mechanism to override ViewData and allow for |
|---|
| 88 | initialization of new derived ViewData objects. Creation and initialization |
|---|
| 89 | is performed when ViewDependendentShadowTechnique::cull gets called with |
|---|
| 90 | CullVistor ptr which does not yet have associated ViewData object. When it |
|---|
| 91 | happens, virtual initViewDependentData method is called to give |
|---|
| 92 | derived techniques a chance to allocate and iniitalize its specific |
|---|
| 93 | resources as new ViewData derived instance. In practice initViewDependentData |
|---|
| 94 | in derived techniques should look the same as in base class so as a convenience |
|---|
| 95 | it was defined as META_ViewDependentShadowTechnique macro. Derived techniques |
|---|
| 96 | use this macro to override initViewDependentData method for their usage. |
|---|
| 97 | |
|---|
| 98 | After ViewData derived object is construted and selected, control is passed |
|---|
| 99 | to this object by call to virtual ViewData::cull method. The rest of work |
|---|
| 100 | is the done by this object. ViewDependentShadowTechnique::ViewData is intended |
|---|
| 101 | as a base class so it does nothing. In practice the rest of dirty work will |
|---|
| 102 | do new ViewData classes implemented in derived techniques. |
|---|
| 103 | */ |
|---|
| 104 | class OSGSHADOW_EXPORT ViewDependentShadowTechnique |
|---|
| 105 | : public osgShadow::ShadowTechnique |
|---|
| 106 | { |
|---|
| 107 | public: |
|---|
| 108 | /** |
|---|
| 109 | osgShadow::ShadowTechnique equivalent methods for view dependent techniques |
|---|
| 110 | */ |
|---|
| 111 | |
|---|
| 112 | /** Classic OSG constructor */ |
|---|
| 113 | ViewDependentShadowTechnique( void ); |
|---|
| 114 | |
|---|
| 115 | /** Classic OSG cloning constructor */ |
|---|
| 116 | ViewDependentShadowTechnique( |
|---|
| 117 | const ViewDependentShadowTechnique& vdst, |
|---|
| 118 | const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY ); |
|---|
| 119 | |
|---|
| 120 | |
|---|
| 121 | /** Declaration of standard OSG object methods */ |
|---|
| 122 | META_Object( osgShadow, ViewDependentShadowTechnique ); |
|---|
| 123 | |
|---|
| 124 | /** Dirty view data bits and force update of view data resources */ |
|---|
| 125 | virtual void dirty(); |
|---|
| 126 | |
|---|
| 127 | /** Initialize the ShadowedScene and some data structures.*/ |
|---|
| 128 | virtual void init(); |
|---|
| 129 | |
|---|
| 130 | /** Run the update traversal of the ShadowedScene and update any local cached data structures.*/ |
|---|
| 131 | virtual void update(osg::NodeVisitor& nv); |
|---|
| 132 | |
|---|
| 133 | /** Run the cull traversal of the ShadowedScene and set up the rendering for this ShadowTechnique.*/ |
|---|
| 134 | virtual void cull(osgUtil::CullVisitor& cv); |
|---|
| 135 | |
|---|
| 136 | /** Clean scene graph from any shadow technique specific nodes, state and drawables.*/ |
|---|
| 137 | virtual void cleanSceneGraph(); |
|---|
| 138 | |
|---|
| 139 | /** Traverse shadow scene graph.*/ |
|---|
| 140 | virtual void traverse(osg::NodeVisitor& nv); |
|---|
| 141 | |
|---|
| 142 | protected: |
|---|
| 143 | /** Classic protected OSG destructor */ |
|---|
| 144 | ~ViewDependentShadowTechnique( void ); |
|---|
| 145 | |
|---|
| 146 | /** |
|---|
| 147 | Base container class for view dependent shadow resources. |
|---|
| 148 | Techniques based on ViewDependentShadowTechnique will usually define |
|---|
| 149 | similar struct and derive it from ViewData to contain their specufic resources. |
|---|
| 150 | */ |
|---|
| 151 | struct OSGSHADOW_EXPORT ViewData: public osg::Referenced |
|---|
| 152 | { |
|---|
| 153 | virtual const char* className() const { return "ViewData"; } |
|---|
| 154 | |
|---|
| 155 | /** |
|---|
| 156 | Method called upon ViewData instance to initialize internal variables |
|---|
| 157 | */ |
|---|
| 158 | virtual void init |
|---|
| 159 | ( ViewDependentShadowTechnique *st, osgUtil::CullVisitor *cv ); |
|---|
| 160 | |
|---|
| 161 | /** |
|---|
| 162 | Method called by ViewDependentShadowTechnique to allow ViewData |
|---|
| 163 | do the hard work computing shadows for its associated view |
|---|
| 164 | */ |
|---|
| 165 | virtual void cull(); |
|---|
| 166 | |
|---|
| 167 | /** |
|---|
| 168 | Dirty is called by parent ViewDependentShadowTechnique to force |
|---|
| 169 | update of resources after some of them were modified in parent technique |
|---|
| 170 | */ |
|---|
| 171 | virtual void dirty( bool flag ); |
|---|
| 172 | |
|---|
| 173 | /** |
|---|
| 174 | Simple constructor zeroing all variables. |
|---|
| 175 | */ |
|---|
| 176 | ViewData(): _dirty( true ), _cv( NULL ), _st( NULL ) { }; |
|---|
| 177 | |
|---|
| 178 | /** |
|---|
| 179 | Mutex used to guard _dirty flag from override in case when parent technique calls |
|---|
| 180 | dirty() simultaneously with ViewData while it is updating resources inside init method. |
|---|
| 181 | */ |
|---|
| 182 | OpenThreads::Mutex _mutex; |
|---|
| 183 | |
|---|
| 184 | /** |
|---|
| 185 | Dirty flag tells this instance to update its resources |
|---|
| 186 | */ |
|---|
| 187 | bool _dirty; |
|---|
| 188 | |
|---|
| 189 | /** |
|---|
| 190 | View's CullVisitor associated with this ViewData instance |
|---|
| 191 | */ |
|---|
| 192 | osg::observer_ptr< osgUtil::CullVisitor > _cv; |
|---|
| 193 | |
|---|
| 194 | /** |
|---|
| 195 | Parent ViewDependentShadowTechnique |
|---|
| 196 | */ |
|---|
| 197 | osg::observer_ptr< ViewDependentShadowTechnique > _st; |
|---|
| 198 | |
|---|
| 199 | }; |
|---|
| 200 | |
|---|
| 201 | /** |
|---|
| 202 | Map of view dependent data per view cull visitor (CVs are used as indices) |
|---|
| 203 | ViewDependentShadowTechnique uses this map to find VieData for each cull vitior |
|---|
| 204 | */ |
|---|
| 205 | |
|---|
| 206 | typedef std::map< osg::ref_ptr< osgUtil::CullVisitor >, |
|---|
| 207 | osg::ref_ptr< ViewData > > ViewDataMap; |
|---|
| 208 | |
|---|
| 209 | ViewDataMap _viewDataMap; |
|---|
| 210 | |
|---|
| 211 | |
|---|
| 212 | /** |
|---|
| 213 | Mutex used to serialize accesses to ViewDataMap |
|---|
| 214 | */ |
|---|
| 215 | OpenThreads::Mutex _viewDataMapMutex; |
|---|
| 216 | |
|---|
| 217 | /** Return view dependent data for the cull visitor */ |
|---|
| 218 | virtual ViewDependentShadowTechnique::ViewData * getViewDependentData( osgUtil::CullVisitor * cv ); |
|---|
| 219 | |
|---|
| 220 | /** Define view dependent data for the cull visitor */ |
|---|
| 221 | virtual void setViewDependentData( osgUtil::CullVisitor * cv, ViewDependentShadowTechnique::ViewData * data ); |
|---|
| 222 | |
|---|
| 223 | /** |
|---|
| 224 | Declare standard initViewDependentData method. |
|---|
| 225 | */ |
|---|
| 226 | META_ViewDependentShadowTechniqueData( ViewDependentShadowTechnique, ViewData ) |
|---|
| 227 | }; |
|---|
| 228 | |
|---|
| 229 | |
|---|
| 230 | } // namespace osgShadow |
|---|
| 231 | |
|---|
| 232 | #endif |
|---|