/* -*-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 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; } /** 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 */ 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 _texture; // ShadowMap camera is defined by base DebugShadowMap // osg::ref_ptr _camera; osg::ref_ptr _texgen; osg::ref_ptr _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) ); virtual void resizeGLObjectBuffers(unsigned int maxSize); virtual void releaseGLObjects(osg::State* = 0) const; }; friend struct ViewData; META_ViewDependentShadowTechniqueData( ThisClass, ThisClass::ViewData ) }; } // namespace osgShadow #endif