StandardShadowMap 7.62 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
/* -*-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_STANDARDSHADOWMAP
#define OSGSHADOW_STANDARDSHADOWMAP 1

#include <osgShadow/DebugShadowMap>

namespace osgShadow {

class OSGSHADOW_EXPORT StandardShadowMap : public DebugShadowMap
{
    public :
        /** Convenient typedef used in definition of ViewData struct and methods */
        typedef StandardShadowMap ThisClass;
        /** Convenient typedef used in definition of ViewData struct and methods */
        typedef DebugShadowMap    BaseClass; 

        /** Classic OSG constructor */
        StandardShadowMap();

        /** Classic OSG cloning constructor */
        StandardShadowMap(const StandardShadowMap& ssm, 
                          const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);

        /** Declaration of standard OSG object methods */
        META_Object( osgShadow, StandardShadowMap );

        void setBaseTextureUnit( unsigned int unit )
            { _baseTextureUnit = unit; dirty(); }

        unsigned int getBaseTextureUnit( void ) const
            { return _baseTextureUnit; }

        void setShadowTextureUnit( unsigned int unit )
            { _shadowTextureUnit = unit; dirty(); }

        unsigned int getShadowTextureUnit( void ) const
            { return _shadowTextureUnit; }

        // Texture Indices are changed by search and replace on shader source
        // Carefully order these calls when changing both base and shadow indices
        // In worst case when intend to swap indices 
        // one will have to call these  methods more than once 
        // with one extra pass to change index to unused value to avoid 
        // unwanted superfluous replace:
        //
        // Example: Imagine we want to swap base(0) and shadow(1) indices:
        // We have to do an extra step to make sure both do not end up as 1
        // 
        // // initialy change base to something else than 1
        // setBaseTextureCoordIndex( 100 ); 
        // // now search and replace all gl_TexCord[1] to gl_TexCord[0]
        // setShadowTextureCoordIndex( 0 );
        // // finally change base from 100 to 0
        // setBaseTextureCoordIndex( 1 ); 

        void setBaseTextureCoordIndex( unsigned int index )
            { updateTextureCoordIndices( _baseTextureCoordIndex, index );
              _baseTextureCoordIndex = index; }       

        unsigned int getBaseTextureCoordIndex( void ) const
            { return _baseTextureCoordIndex; }

        // Texture Indices are changed by search and replace on shader source
        // Look at the comment above setBaseTextureCoordIndex

        void setShadowTextureCoordIndex( unsigned int index )
            { updateTextureCoordIndices( _shadowTextureCoordIndex, index );
              _shadowTextureCoordIndex = index; }

        unsigned int getShadowTextureCoordIndex( void ) const
            { return _shadowTextureCoordIndex; }

        void setTextureSize( const osg::Vec2s& textureSize )
            { _textureSize = textureSize; dirty(); }

        const osg::Vec2s& getTextureSize() const
            { return _textureSize; }

        void setLight( osg::Light* light )
            { _light = light; }

        osg::Light* getLight( void )
            { return _light.get(); }
        
        const osg::Light* getLight( void ) const
            { return _light.get(); }

        osg::Shader * getShadowVertexShader() 
            { return _shadowVertexShader.get(); }

        osg::Shader * getShadowFragmentShader() 
            { return _shadowFragmentShader.get(); }

        osg::Shader * getMainVertexShader( )
            { return _mainVertexShader.get(); }

        osg::Shader * getMainFragmentShader( )
            { return _mainFragmentShader.get(); }

        void setShadowVertexShader( osg::Shader * shader )
            { _shadowVertexShader = shader; }

        void setShadowFragmentShader( osg::Shader * shader ) 
            { _shadowFragmentShader = shader; }

        void setMainVertexShader( osg::Shader * shader ) 
            { _mainVertexShader = shader; }

        void setMainFragmentShader( osg::Shader * shader )
            { _mainFragmentShader = shader; }

    protected:
        /** Classic protected OSG destructor */
        virtual ~StandardShadowMap(void);

        virtual void updateTextureCoordIndices
                ( unsigned int baseTexCoordIndex, unsigned int shadowTexCoordIndex );

        virtual void searchAndReplaceShaderSource
                ( osg::Shader*, std::string fromString, std::string toString );

        osg::ref_ptr< osg::Shader >   _mainVertexShader;
        osg::ref_ptr< osg::Shader >   _mainFragmentShader;
        osg::ref_ptr< osg::Shader >   _shadowVertexShader;
        osg::ref_ptr< osg::Shader >   _shadowFragmentShader;

        osg::ref_ptr< osg::Light >    _light;
        float                         _polygonOffsetFactor;
        float                         _polygonOffsetUnits;
        osg::Vec2s                      _textureSize;
        unsigned int                  _baseTextureUnit;
        unsigned int                  _shadowTextureUnit;
        unsigned int                  _baseTextureCoordIndex;
        unsigned int                  _shadowTextureCoordIndex;

        struct OSGSHADOW_EXPORT ViewData: public BaseClass::ViewData
        {
            osg::ref_ptr< osg::Light > *  _lightPtr;
            unsigned int               *  _baseTextureUnitPtr;
            unsigned int               *  _shadowTextureUnitPtr;

            // ShadowMap texture is defined by base DebugShadowMap
            // osg::ref_ptr<osg::Texture2D>  _texture;

            // ShadowMap camera is defined by base DebugShadowMap
            // osg::ref_ptr<osg::Camera>     _camera;

            osg::ref_ptr<osg::TexGen>     _texgen;
            osg::ref_ptr<osg::StateSet>   _stateset;

            virtual void init( ThisClass * st, osgUtil::CullVisitor * cv );

            virtual void cull( );

            virtual void aimShadowCastingCamera( 
                const osg::BoundingSphere &bounds,
                const osg::Light *light,
                const osg::Vec4 &worldLightPos,
                const osg::Vec3 &worldLightDir,                                       
                const osg::Vec3 &worldLightUp = osg::Vec3(0,1,0) );

            virtual void cullShadowReceivingScene( );

            virtual void cullShadowCastingScene( );

            virtual void addShadowReceivingTexGen( );

            virtual const osg::Light* selectLight( osg::Vec4 &viewLightPos,
                osg::Vec3 &viewLightDir );

            virtual void aimShadowCastingCamera( const osg::Light *light,
                const osg::Vec4 &worldLightPos,
                const osg::Vec3 &worldLightDir,                                       
                const osg::Vec3 &worldLightUp
                = osg::Vec3(0,1,0) );
        };
        
        friend struct ViewData;

        META_ViewDependentShadowTechniqueData( ThisClass, ThisClass::ViewData )
};

} // namespace osgShadow

#endif