Hi Wojtek,  I've gone for the solution of forward declaring this
classes in the headers, this now checked into SVN.

On Fri, Jan 23, 2009 at 9:56 AM, Wojciech Lewandowski
<[email protected]> wrote:
> Hi Robert and Roger,
>
> I suppose good solution for this problem would be defining them as a
> subclasses of DebugShadowMap and ShadowMap. This will correspond to actual
> scope of their usage.
>
> Cheers,
> Wojtek
>
> ----- Original Message ----- From: "Robert Osfield"
> <[email protected]>
> To: "OpenSceneGraph Submissions" <[email protected]>
> Sent: Friday, January 23, 2009 10:28 AM
> Subject: Re: [osg-submissions] A small fix in for osgShadow
>
>
>> Hi Roger,
>>
>> Moving a class definition into a function implementation makes me
>> nervous about the possibile consequence for older compilers handling
>> this.  I don't know whether it would be supported or not, but... given
>> it's not a technique used in the rest the OSG I don't have a prior art
>> to confirm that it's OK to roll out.
>>
>> Would enclosing the class in a local namespace be sufficient?
>>
>> Robert.
>>
>> On Thu, Jan 22, 2009 at 2:23 PM, Roger James
>> <[email protected]> wrote:
>>>
>>> Robert,
>>>
>>> This fix moves a couple of debug callback functions that have the same
>>> name
>>> from the global context into the local function context where they are
>>> used.
>>> This avoids some obscure problems when they used in DLLs generated by MS
>>> VC8.1.
>>>
>>> Roger
>>>
>>> /* -*-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.
>>> */
>>>
>>> #include <osgShadow/DebugShadowMap>
>>> #include <osgShadow/ConvexPolyhedron>
>>> #include <osgUtil/RenderLeaf>
>>> #include <osg/Geometry>
>>> #include <osg/PrimitiveSet>
>>> #include <osg/MatrixTransform>
>>> #include <osg/Depth>
>>> #include <iostream>
>>> #include <iomanip>
>>>
>>> using namespace osgShadow;
>>>
>>>
>>> #define VECTOR_LENGTH( v ) ( sizeof(v)/sizeof(v[0]) )
>>>
>>> #define DEFAULT_DEBUG_HUD_SIZE_X 256
>>> #define DEFAULT_DEBUG_HUD_SIZE_Y 256
>>> #define DEFAULT_DEBUG_HUD_ORIGIN_X 8
>>> #define DEFAULT_DEBUG_HUD_ORIGIN_Y 8
>>>
>>> DebugShadowMap::DebugShadowMap():
>>>   BaseClass(),
>>>   _hudSize( 2, 2 ),
>>>   _hudOrigin( -1, -1 ),
>>>   _viewportSize( DEFAULT_DEBUG_HUD_SIZE_X, DEFAULT_DEBUG_HUD_SIZE_Y ),
>>>   _viewportOrigin( DEFAULT_DEBUG_HUD_ORIGIN_X, DEFAULT_DEBUG_HUD_ORIGIN_Y
>>> ),
>>>   _orthoSize( 2, 2 ),
>>>   _orthoOrigin( -1, -1 ),
>>>   _doDebugDraw( false )
>>> {
>>>
>>>   // Why this fancy 24 bit depth to 24 bit rainbow colors shader ?
>>>   //
>>>   // Depth values cannot be easily cast on color component because they
>>> are:
>>>   // a) 24 or 32 bit and we loose lots of precision when cast on 8 bit
>>>   // b) depth value distribution is non linear due to projection division
>>>   // when cast on componenent color there is usually very minor shade
>>> variety
>>>   // and its often difficult to notice that there is anything in the
>>> buffer
>>>   //
>>>   // Shader looks complex but it is used only for debug head-up rectangle
>>>   // so performance impact is not significant.
>>>
>>>   _depthColorFragmentShader = new osg::Shader( osg::Shader::FRAGMENT,
>>> #if 0
>>>       "uniform sampler2D texture;
>>>   \n"
>>>       "
>>>   \n"
>>>       "void main(void)
>>>    \n"
>>>       "{
>>>    \n"
>>>       "    float f = texture2D( texture, vec3( gl_TexCoord[0].xy, 1.0).xy
>>> ).r; \n"
>>>       "    gl_FragColor =  vec4( 0.0, 1.0 - f,  0.5 - f, 0.5 );
>>>   \n"
>>>       "}
>>>    \n"
>>> #else
>>>       "uniform sampler2D texture;
>>>   \n"
>>>       "
>>>   \n"
>>>       "void main(void)
>>>    \n"
>>>       "{
>>>    \n"
>>>       "    float f = texture2D( texture, vec3( gl_TexCoord[0].xy, 1.0).xy
>>> ).r; \n"
>>>       "
>>>   \n"
>>>       "    f = 256.0 * f;
>>>   \n"
>>>       "    float fC = floor( f ) / 256.0;
>>>   \n"
>>>       "
>>>   \n"
>>>       "    f = 256.0 * fract( f );
>>>    \n"
>>>       "    float fS = floor( f ) / 256.0;
>>>   \n"
>>>       "
>>>   \n"
>>>       "    f = 256.0 * fract( f );
>>>    \n"
>>>       "    float fH = floor( f ) / 256.0;
>>>   \n"
>>>       "
>>>   \n"
>>>       "    fS *= 0.5;
>>>   \n"
>>>       "    fH = ( fH  * 0.34 + 0.66 ) * ( 1.0 - fS );
>>>   \n"
>>>       "
>>>   \n"
>>>       "    vec3 rgb = vec3( ( fC > 0.5 ? ( 1.0 - fC ) : fC ),
>>>   \n"
>>>       "                     abs( fC - 0.333333 ),
>>>   \n"
>>>       "                     abs( fC - 0.666667 ) );
>>>   \n"
>>>       "
>>>   \n"
>>>       "    rgb = min( vec3( 1.0, 1.0, 1.0 ), 3.0 * rgb );
>>>   \n"
>>>       "
>>>   \n"
>>>       "    float fMax = max( max( rgb.r, rgb.g ), rgb.b );
>>>    \n"
>>>       "    fMax = 1.0 / fMax;
>>>   \n"
>>>       "
>>>   \n"
>>>       "    vec3 color = fMax * rgb;
>>>   \n"
>>>       "
>>>   \n"
>>>       "    gl_FragColor =  vec4( fS + fH * color, 1 ) * gl_Color;
>>>   \n"
>>>       "}
>>>    \n"
>>> #endif
>>>   ); // end _depthColorFragmentShader
>>> }
>>>
>>> DebugShadowMap::DebugShadowMap
>>> (const DebugShadowMap& copy, const osg::CopyOp& copyop) :
>>>   BaseClass(copy,copyop),
>>>   _hudSize( copy._hudSize ),
>>>   _hudOrigin( copy._hudOrigin ),
>>>   _viewportSize( copy._viewportSize ),
>>>   _viewportOrigin( copy._viewportOrigin ),
>>>   _orthoSize( copy._viewportOrigin ),
>>>   _orthoOrigin( copy._viewportOrigin ),
>>>   _doDebugDraw( copy._doDebugDraw )
>>> {
>>>   if( copy._depthColorFragmentShader.valid() )
>>>       _depthColorFragmentShader =
>>>           dynamic_cast<osg::Shader*>
>>>               ( copy._depthColorFragmentShader->clone(copyop) );
>>> }
>>>
>>> DebugShadowMap::~DebugShadowMap()
>>> {
>>> }
>>>
>>> void DebugShadowMap::ViewData::cull( void )
>>> {
>>>   if( getDebugDraw() && !_cameraDebugHUD.valid() )
>>>       createDebugHUD();
>>>
>>>   BaseClass::ViewData::cull( );
>>>
>>>   cullDebugGeometry( );
>>> }
>>>
>>> bool DebugShadowMap::ViewData::DebugBoundingBox
>>>   ( const osg::BoundingBox & bb, const char * name )
>>> {
>>>   bool result = false;
>>> #if defined( _DEBUG    ) || defined( DEBUG )
>>>   if( !name ) name = "";
>>>
>>>   osg::BoundingBox & bb_prev = _boundingBoxMap[ std::string( name ) ];
>>>
>>>   result = bb.center() != bb_prev.center() || bb.radius() !=
>>> bb_prev.radius();
>>>   if( result )
>>>       std::cout << "Box<" << name << "> ("
>>>                 << ( bb._max._v[0] + bb._min._v[0] ) * 0.5 << " "
>>>                 << ( bb._max._v[1] + bb._min._v[1] ) * 0.5 << " "
>>>                 << ( bb._max._v[2] + bb._min._v[2] ) * 0.5 << ") ["
>>>                 << ( bb._max._v[0] - bb._min._v[0] ) << " "
>>>                 << ( bb._max._v[1] - bb._min._v[1] ) << " "
>>>                 << ( bb._max._v[2] - bb._min._v[2] ) << "] "
>>>                 << std::endl;
>>>
>>>   bb_prev = bb;
>>> #endif
>>>   return result;
>>> }
>>>
>>> bool DebugShadowMap::ViewData::DebugPolytope
>>> ( const osg::Polytope & p, const char * name )
>>> {
>>>   bool result = false;
>>> #if defined( _DEBUG    ) || defined( DEBUG )
>>>   if( !name ) name = "";
>>>
>>>   osg::Polytope & p_prev = _polytopeMap[ std::string( name ) ];
>>>
>>>   result = ( p.getPlaneList() != p_prev.getPlaneList() );
>>>
>>>   if( result ) {
>>>       std::cout << "Polytope<" << name
>>>                 << "> size(" << p.getPlaneList().size() << ")"
>>>                 << std::endl;
>>>
>>>       if( p.getPlaneList().size() == p_prev.getPlaneList().size() ) {
>>>           for( unsigned i = 0; i < p.getPlaneList().size(); ++i )
>>>           {
>>>               if( p.getPlaneList()[i] != p_prev.getPlaneList()[i] )
>>>               {
>>>                   std::cout << "Plane<" << i
>>>                       << "> ("
>>>                       << p.getPlaneList()[i].asVec4()[0] << ", "
>>>                       << p.getPlaneList()[i].asVec4()[1] << ", "
>>>                       << p.getPlaneList()[i].asVec4()[2] << ", "
>>>                       << p.getPlaneList()[i].asVec4()[3] << ")"
>>>                       << std::endl;
>>>               }
>>>           }
>>>       }
>>>   }
>>>
>>>   p_prev = p;
>>> #endif
>>>   return result;
>>> }
>>>
>>> bool DebugShadowMap::ViewData::DebugMatrix
>>>   ( const osg::Matrix & m, const char * name )
>>> {
>>>   bool result = false;
>>> #if defined( _DEBUG    ) || defined( DEBUG )
>>>   if( !name ) name = "";
>>>
>>>   osg::Matrix & m_prev = _matrixMap[ std::string( name ) ];
>>>
>>>   result = ( m != m_prev );
>>>
>>>   if( result )
>>>       std::cout << "Matrix<" << name << "> " << std::endl
>>>           <<"[ " << m(0,0) << " " << m(0,1) << " " << m(0,2) << " " <<
>>> m(0,3) << " ]  " << std::endl
>>>           <<"[ " << m(1,0) << " " << m(1,1) << " " << m(1,2) << " " <<
>>> m(1,3) << " ]  " << std::endl
>>>           <<"[ " << m(2,0) << " " << m(2,1) << " " << m(2,2) << " " <<
>>> m(2,3) << " ]  " << std::endl
>>>           <<"[ " << m(3,0) << " " << m(3,1) << " " << m(3,2) << " " <<
>>> m(3,3) << " ]  " << std::endl;
>>>
>>>   m_prev = m;
>>> #endif
>>>   return result;
>>> }
>>>
>>> void DebugShadowMap::ViewData::setDebugPolytope
>>>   ( const char * name, const ConvexPolyhedron & polytope,
>>>     osg::Vec4 colorOutline, osg::Vec4 colorInside )
>>> {
>>>   if( !getDebugDraw() ) return;
>>>
>>>   if( &polytope == NULL ) { // delete
>>>       PolytopeGeometry & pg = _polytopeGeometryMap[ std::string( name )
>>> ];
>>>       for( unsigned int i = 0; i < VECTOR_LENGTH( pg._geometry ) ; i++ )
>>>       {
>>>           if( pg._geometry[i].valid() ) {
>>>               if( _geode[i].valid() &&
>>>                   _geode[i]->containsDrawable( pg._geometry[i].get() ) )
>>>                       _geode[i]->removeDrawable( pg._geometry[i].get() );
>>>
>>>               pg._geometry[i] = NULL;
>>>           }
>>>       }
>>>       _polytopeGeometryMap.erase( std::string( name ) );
>>>   } else { // update
>>>       PolytopeGeometry & pg = _polytopeGeometryMap[ std::string( name )
>>> ];
>>>
>>>       pg._polytope = polytope;
>>>       if( colorOutline.a() > 0 )
>>>           pg._colorOutline = colorOutline;
>>>       if( colorInside.a() > 0 )
>>>           pg._colorInside = colorInside;
>>>
>>>       for( unsigned int i = 0; i < VECTOR_LENGTH( pg._geometry ) ; i++ )
>>>       {
>>>           if( !pg._geometry[i].valid() ) {
>>>               pg._geometry[i] = new osg::Geometry;
>>>               pg._geometry[i]->setDataVariance( osg::Object::DYNAMIC );
>>>               pg._geometry[i]->setUseDisplayList( false );
>>>               pg._geometry[i]->setSupportsDisplayList( false );
>>>           }
>>>
>>>           if( _geode[i].valid() &&
>>>                 !_geode[i]->containsDrawable( pg._geometry[i].get() ) ) {
>>>                       osg::Geode::DrawableList & dl =
>>>                          const_cast< osg::Geode::DrawableList &>
>>>                             ( _geode[i]->getDrawableList() );
>>>                       dl.insert( dl.begin(), pg._geometry[i].get() );
>>>           }
>>>       }
>>>   }
>>> }
>>>
>>> void DebugShadowMap::ViewData::updateDebugGeometry
>>>   ( const osg::Camera * viewCam, const osg::Camera * shadowCam )
>>> {
>>>   if( !getDebugDraw() ) return;
>>>   if( _polytopeGeometryMap.empty() ) return;
>>>
>>>   const int num = 2; // = VECTOR_LENGTH( PolytopeGeometry::_geometry );
>>>
>>>   osg::Matrix
>>>       transform[ num ] =
>>>           { viewCam->getViewMatrix() *
>>>               // use near far clamped projection ( precomputed in
>>> cullDebugGeometry )
>>>               ( viewCam == _viewCamera ? _viewProjection :
>>> viewCam->getProjectionMatrix() ),
>>>             shadowCam->getViewMatrix() * shadowCam->getProjectionMatrix()
>>> },
>>>       inverse[ num ] =
>>>           { osg::Matrix::inverse( transform[0] ),
>>>             osg::Matrix::inverse( transform[1] ) };
>>>
>>> #if 0
>>>   ConvexPolyhedron frustum[ num ];
>>>   for( int i = 0; i < num; i++ ) {
>>>       frustum[i].setToUnitFrustum( );
>>> #if 1
>>>       frustum[i].transform( inverse[i], transform[i] );
>>> #else
>>>       frustum[i].transform
>>>           ( osg::Matrix::inverse( camera[i]->getProjectionMatrix() ),
>>>             camera[i]->getProjectionMatrix() );
>>>       frustum[i].transform
>>>           ( osg::Matrix::inverse( camera[i]->getViewMatrix() ),
>>>             camera[i]->getViewMatrix() );
>>> #endif
>>>   };
>>> #else
>>>   osg::Polytope frustum[ num ];
>>>   for( int i = 0; i < num; i++ ) {
>>>       frustum[i].setToUnitFrustum( );
>>>       frustum[i].transformProvidingInverse( transform[i] );
>>>   }
>>> #endif
>>>
>>>   transform[0] = viewCam->getViewMatrix();
>>>   inverse[0] = viewCam->getInverseViewMatrix();
>>>
>>>   for( PolytopeGeometryMap::iterator itr = _polytopeGeometryMap.begin();
>>>        itr != _polytopeGeometryMap.end();
>>>        ++itr )
>>>   {
>>>       PolytopeGeometry & pg = itr->second;
>>>
>>>       for( int i = 0; i < num ; i++ )
>>>       {
>>>
>>>           ConvexPolyhedron cp( pg._polytope );
>>>           cp.cut( frustum[i] );
>>>           cp.transform( transform[i], inverse[i] );
>>>
>>>           pg._geometry[i] = cp.buildGeometry
>>>               ( pg._colorOutline, pg._colorInside, pg._geometry[i].get()
>>> );
>>>       }
>>>   }
>>> }
>>>
>>> void DebugShadowMap::ViewData::cullDebugGeometry( )
>>> {
>>>   if( !getDebugDraw() ) return;
>>>   if( !_camera.valid() ) return;
>>>
>>>   // View camera may use clamping projection matrix after traversal.
>>>   // Since we need to know exact matrix for drawing the frusta,
>>>   // we have to compute it here in exactly the same way as cull visitor
>>>   // will after cull traversal completes view camera subgraph.
>>>   {
>>>       _viewProjection = *_cv->getProjectionMatrix();
>>>       _viewCamera = _cv->getRenderStage()->getCamera();
>>>
>>>       if( _cv->getComputeNearFarMode() ) {
>>>
>>>           // Redo steps from CullVisitor::popProjectionMatrix()
>>>           // which clamps projection matrix when Camera & Projection
>>>           // completes traversal of their children
>>>
>>>           // We have to do this now manually
>>>           // because we did not complete camera traversal yet but
>>>           // we need to know how this clamped projection matrix will be
>>>
>>>           _cv->computeNearPlane();
>>>
>>>           osgUtil::CullVisitor::value_type n =
>>> _cv->getCalculatedNearPlane();
>>>           osgUtil::CullVisitor::value_type f =
>>> _cv->getCalculatedFarPlane();
>>>
>>>           if( n < f )
>>>               _cv->clampProjectionMatrix( _viewProjection, n, f );
>>>       }
>>>   }
>>>
>>>   updateDebugGeometry( _viewCamera, _camera.get() );
>>>
>>> #if 1 // Add geometries of polytopes to main cam Render Stage
>>>   _transform[0]->accept( *_cv );
>>> #else
>>>   for( PolytopeGeometryMap::iterator itr = _polytopeGeometryMap.begin();
>>>        itr != _polytopeGeometryMap.end();
>>>        ++itr )
>>>   {
>>>       PolytopeGeometry & pg = itr->second;
>>>       _cv->pushStateSet( _geode[0]->getStateSet() );
>>>       _cv->addDrawableAndDepth( pg._geometry[0].get(), NULL, FLT_MAX );
>>>       _cv->popStateSet( );
>>>   }
>>> #endif
>>>
>>>   // Add geometries of polytopes to hud cam Render Stage
>>>   _cameraDebugHUD->accept( *_cv );
>>> }
>>>
>>> void DebugShadowMap::ViewData::init( ThisClass *st, osgUtil::CullVisitor
>>> *cv
>>> )
>>> {
>>>   BaseClass::ViewData::init( st, cv );
>>>
>>>   _doDebugDrawPtr           = &st->_doDebugDraw;
>>>
>>>   _hudSize                  = st->_hudSize;
>>>   _hudOrigin                = st->_hudOrigin;
>>>   _viewportSize             = st->_viewportSize;
>>>   _viewportOrigin           = st->_viewportOrigin;
>>>   _orthoSize                = st->_orthoSize;
>>>   _orthoOrigin              = st->_orthoOrigin;
>>>
>>>   _depthColorFragmentShader = st->_depthColorFragmentShader;
>>>
>>>   // create placeholder geodeds for polytope geometries
>>>   // rest of their initialization will be performed during camera hud
>>> init
>>>   _geode[0] = new osg::Geode;
>>>   _geode[1] = new osg::Geode;
>>>
>>>   _cameraDebugHUD           = NULL;//Force debug HUD rebuild ( if needed
>>> )
>>> }
>>>
>>> void DebugShadowMap::ViewData::createDebugHUD( )
>>> {
>>>       // Callback used by debugging hud to display Shadow Map to color
>>> buffer
>>>       // Had to do it this way because OSG does not allow to use
>>>       // the same GL Texture Id with different glTexParams.
>>>       // Callback simply turns compare mode off via GL while rendering
>>> hud
>>> and
>>>       // restores it before rendering the scene with shadows.
>>>       class DrawableDrawWithDepthShadowComparisonOffCallback:
>>>               public osg::Drawable::DrawCallback
>>>       {
>>>       public:
>>>               DrawableDrawWithDepthShadowComparisonOffCallback(
>>> osg::Texture2D *pTex )
>>>                       : _pTexture( pTex )
>>>               {
>>>               }
>>>
>>>               virtual void drawImplementation
>>>                       ( osg::RenderInfo & ri,const osg::Drawable*
>>> drawable
>>> ) const
>>>               {
>>>                       ri.getState()->applyTextureAttribute( 0,
>>> _pTexture.get() );
>>>
>>>                       // Turn off depth comparison mode
>>>                       glTexParameteri( GL_TEXTURE_2D,
>>> GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE );
>>>
>>>                       drawable->drawImplementation(ri);
>>>
>>>                       // Turn it back on
>>>                       glTexParameteri( GL_TEXTURE_2D,
>>> GL_TEXTURE_COMPARE_MODE_ARB,
>>>                               GL_COMPARE_R_TO_TEXTURE_ARB );
>>>               }
>>>
>>>               osg::ref_ptr< osg::Texture2D > _pTexture;
>>>       };
>>>
>>>   _cameraDebugHUD = new osg::Camera;
>>>
>>>   { // Make sure default HUD layout makes sense
>>>       if( _hudSize[0] <= 0 ) _hudSize[0] = DEFAULT_DEBUG_HUD_SIZE_X;
>>>       if( _hudSize[1] <= 0 ) _hudSize[1] = DEFAULT_DEBUG_HUD_SIZE_Y;
>>>
>>>       if( _viewportSize[0] <= 0 ) _viewportSize[0] = _hudSize[0];
>>>       if( _viewportSize[1] <= 0 ) _viewportSize[1] = _hudSize[1];
>>>
>>>       if( _orthoSize[0] <= 0 ) _orthoSize[0] = _viewportSize[0];
>>>       if( _orthoSize[1] <= 0 ) _orthoSize[1] = _viewportSize[1];
>>>   }
>>>
>>>   { // Initialize hud camera
>>>       osg::Camera * camera = _cameraDebugHUD.get();
>>>
>>> camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
>>>       camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
>>>       camera->setViewMatrix(osg::Matrix::identity());
>>>       camera->setViewport( _viewportOrigin[0], _viewportOrigin[1],
>>>                            _viewportSize[0], _viewportSize[1] );
>>>
>>>       camera->setProjectionMatrixAsOrtho(
>>>               _orthoOrigin[0], _orthoOrigin[0] + _orthoSize[0],
>>>               _orthoOrigin[1], _orthoOrigin[1] + _orthoSize[1],
>>>               -10, 10 );
>>>
>>>       camera->setClearMask(GL_DEPTH_BUFFER_BIT);
>>>       camera->setRenderOrder(osg::Camera::POST_RENDER);
>>>   }
>>>
>>>   { // Add geode and drawable with BaseClass display
>>>       // create geode to contain hud drawables
>>>       osg::Geode* geode = new osg::Geode;
>>>       _cameraDebugHUD->addChild(geode);
>>>
>>>       // finally create and attach hud geometry
>>>       osg::Geometry* geometry = osg::createTexturedQuadGeometry
>>>           ( osg::Vec3(_hudOrigin[0],_hudOrigin[1],0),
>>>             osg::Vec3(_hudSize[0],0,0),
>>>             osg::Vec3(0,_hudSize[1],0) );
>>>
>>>       osg::StateSet* stateset = _cameraDebugHUD->getOrCreateStateSet();
>>>
>>>
>>>
>>> stateset->setTextureAttributeAndModes(0,_texture.get(),osg::StateAttribute::ON
>>> );
>>>       stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
>>> //        stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
>>>       stateset->setAttributeAndModes
>>>           ( new osg::Depth( osg::Depth::ALWAYS, 0, 1, false ) );
>>>       stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
>>>
>>>       osg::Program* program = new osg::Program;
>>>       program->addShader( _depthColorFragmentShader.get() );
>>>       stateset->setAttribute( program );
>>>       stateset->addUniform( new osg::Uniform( "texture" , 0 ) );
>>>
>>>       geometry->setDrawCallback
>>>           ( new DrawableDrawWithDepthShadowComparisonOffCallback(
>>> _texture.get() ) );
>>>
>>>       geode->addDrawable( geometry );
>>>   }
>>>
>>>   { // Create transforms and geodes to manage polytope drawing
>>>       osg::StateSet * stateset = new osg::StateSet;
>>>       stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
>>>       stateset->setTextureMode(0, GL_TEXTURE_2D,
>>> osg::StateAttribute::OFF);
>>>       stateset->setTextureMode(1, GL_TEXTURE_2D,
>>> osg::StateAttribute::OFF);
>>>       stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
>>>       stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
>>>       stateset->setAttribute( new osg::Program() );
>>>       stateset->setAttributeAndModes
>>>           ( new osg::Depth( osg::Depth::LEQUAL, 0, 1, false ) );
>>>
>>>       for( int i = 0; i < 2; i++ ) {
>>>           _geode[i]->setStateSet( stateset );
>>>           _transform[i] = new osg::MatrixTransform;
>>>           _transform[i]->addChild( _geode[i].get() );
>>>           _transform[i]->setMatrix( osg::Matrix::identity() );
>>>           _transform[i]->setReferenceFrame(
>>> osg::MatrixTransform::ABSOLUTE_RF );
>>>       }
>>>
>>>       _transform[1]->setMatrix
>>>           ( osg::Matrix::translate( 1, 1, 0 ) *
>>>             osg::Matrix::scale( 0.5, 0.5, 1 ) *
>>>             osg::Matrix::scale( _hudSize[0], _hudSize[1], 1 ) *
>>>             osg::Matrix::translate( _hudOrigin[0], _hudOrigin[1], 0 ) );
>>>
>>>       _cameraDebugHUD->addChild( _transform[1].get() );
>>>   }
>>> }
>>>
>>> osg::Vec3d DebugShadowMap::ViewData::computeShadowTexelToPixelError
>>>    ( const osg::Matrix & mvpwView,
>>>      const osg::Matrix & mvpwShadow,
>>>      const osg::Vec3d & vWorld,
>>>      const osg::Vec3d & vDelta )
>>> {
>>>   osg::Vec3d vS0 = mvpwShadow * vWorld;
>>>   osg::Vec3d vS1 = mvpwShadow * ( vWorld + vDelta );
>>>
>>>   osg::Vec3d vV0 = mvpwView * vWorld;
>>>   osg::Vec3d vV1 = mvpwView * ( vWorld + vDelta );
>>>
>>>   osg::Vec3d dV = vV1 - vV0;
>>>   osg::Vec3d dS = vS1 - vS0;
>>>
>>>   return osg::Vec3( dS[0] / dV[0], dS[1] / dV[1], dS[2] / dV[2] );
>>> }
>>>
>>> void DebugShadowMap::ViewData::displayShadowTexelToPixelErrors
>>>  ( const osg::Camera* viewCamera,
>>>   const osg::Camera* shadowCamera,
>>>   const ConvexPolyhedron* hull )
>>> {
>>>   osg::Matrix mvpwMain  =
>>>       viewCamera->getViewMatrix() *
>>>       viewCamera->getProjectionMatrix() *
>>>       viewCamera->getViewport()->computeWindowMatrix();
>>>
>>>   osg::Matrix mvpwShadow  =
>>>       shadowCamera->getViewMatrix() *
>>>       shadowCamera->getProjectionMatrix() *
>>>       shadowCamera->getViewport()->computeWindowMatrix();
>>>
>>>   osg::BoundingBox bb =
>>>       hull->computeBoundingBox( viewCamera->getViewMatrix() );
>>>
>>>   osg::Matrix m = viewCamera->getInverseViewMatrix();
>>>
>>>   osg::Vec3d vn = osg::Vec3d( 0, 0, bb._max[2] ) * m;
>>>   osg::Vec3d vf = osg::Vec3d( 0, 0, bb._min[2] ) * m;
>>>   osg::Vec3d vm = osg::Vec3d( 0, 0, ( bb._max[2] + bb._min[2] ) * 0.5 ) *
>>> m;
>>>
>>>   osg::Vec3d vne = computeShadowTexelToPixelError( mvpwMain, mvpwShadow,
>>> vn
>>> );
>>>   osg::Vec3d vfe = computeShadowTexelToPixelError( mvpwMain, mvpwShadow,
>>> vf
>>> );
>>>   osg::Vec3d vme = computeShadowTexelToPixelError( mvpwMain, mvpwShadow,
>>> vm
>>> );
>>>
>>>   std::cout << std::setprecision( 3 ) << " "
>>>       << "ne=(" << vne[0] << "," << vne[1] << "," << vne[2] << ")  "
>>>       << "fe=(" << vfe[0] << "," << vfe[1] << "," << vfe[2] << ")  "
>>>       << "me=(" << vme[0] << "," << vme[1] << "," << vme[2] << ")  "
>>>       <<
>>>
>>> "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
>>>       <<
>>>
>>> "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
>>>       <<
>>>
>>> "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
>>>       << std::flush;
>>> }
>>>
>>>
>>> /* -*-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.
>>> */
>>>
>>> #include <osgShadow/ShadowMap>
>>> #include <osgShadow/ShadowedScene>
>>> #include <osg/Notify>
>>> #include <osg/ComputeBoundsVisitor>
>>> #include <osg/PolygonOffset>
>>> #include <osg/CullFace>
>>> #include <osg/io_utils>
>>>
>>> using namespace osgShadow;
>>>
>>> #include <iostream>
>>> //for debug
>>> #include <osg/LightSource>
>>> #include <osg/PolygonMode>
>>> #include <osg/Geometry>
>>> #include <osgDB/ReadFile>
>>> #include <osgText/Text>
>>>
>>> #define IMPROVE_TEXGEN_PRECISION 1
>>>
>>> //////////////////////////////////////////////////////////////////
>>> // fragment shader
>>> //
>>> static const char fragmentShaderSource_noBaseTexture[] =
>>>   "uniform sampler2DShadow osgShadow_shadowTexture; \n"
>>>   "uniform vec2 osgShadow_ambientBias; \n"
>>>   "\n"
>>>   "void main(void) \n"
>>>   "{ \n"
>>>   "    gl_FragColor = gl_Color * (osgShadow_ambientBias.x + shadow2DProj(
>>> osgShadow_shadowTexture, gl_TexCoord[0] ) * osgShadow_ambientBias.y); \n"
>>>   "}\n";
>>>
>>> //////////////////////////////////////////////////////////////////
>>> // fragment shader
>>> //
>>> static const char fragmentShaderSource_withBaseTexture[] =
>>>   "uniform sampler2D osgShadow_baseTexture; \n"
>>>   "uniform sampler2DShadow osgShadow_shadowTexture; \n"
>>>   "uniform vec2 osgShadow_ambientBias; \n"
>>>   "\n"
>>>   "void main(void) \n"
>>>   "{ \n"
>>>   "    vec4 color = gl_Color * texture2D( osgShadow_baseTexture,
>>> gl_TexCoord[0].xy ); \n"
>>>   "    gl_FragColor = color * (osgShadow_ambientBias.x + shadow2DProj(
>>> osgShadow_shadowTexture, gl_TexCoord[1] ) * osgShadow_ambientBias.y); \n"
>>>   "}\n";
>>>
>>> //////////////////////////////////////////////////////////////////
>>> // fragment shader
>>> //
>>> static const char fragmentShaderSource_debugHUD_texcoord[] =
>>>   "uniform sampler2D osgShadow_shadowTexture; \n"
>>>   " \n"
>>>   "void main(void) \n"
>>>   "{ \n"
>>>   "   vec4 texCoord = gl_TexCoord[1].xyzw; \n"
>>>   "   float value = texCoord.z / texCoord.w; \n"
>>>   "   gl_FragColor = vec4( value, value, value, 1.0 ); \n"
>>>   "} \n";
>>>
>>> static const char fragmentShaderSource_debugHUD[] =
>>>   "uniform sampler2D osgShadow_shadowTexture; \n"
>>>   " \n"
>>>   "void main(void) \n"
>>>   "{ \n"
>>>   "   vec4 texResult = texture2D(osgShadow_shadowTexture,
>>> gl_TexCoord[0].st
>>> ); \n"
>>>   "   float value = texResult.r; \n"
>>>   "   gl_FragColor = vec4( value, value, value, 0.8 ); \n"
>>>   "} \n";
>>>
>>> ShadowMap::ShadowMap():
>>>   _baseTextureUnit(0),
>>>   _shadowTextureUnit(1),
>>>   _polyOffset(1.0,1.0),
>>>   _ambientBias(0.5f,0.5f),
>>>   _textureSize(1024,1024)
>>> {
>>> }
>>>
>>> ShadowMap::ShadowMap(const ShadowMap& copy, const osg::CopyOp& copyop):
>>> ShadowTechnique(copy,copyop),
>>>   _baseTextureUnit(copy._baseTextureUnit),
>>>   _shadowTextureUnit(copy._shadowTextureUnit),
>>>   _polyOffset(copy._polyOffset),
>>>   _ambientBias(copy._ambientBias),
>>>   _textureSize(copy._textureSize)
>>> {
>>> }
>>>
>>> void ShadowMap::setTextureUnit(unsigned int unit)
>>> {
>>>   _shadowTextureUnit = unit;
>>> }
>>>
>>> void ShadowMap::setPolygonOffset(const osg::Vec2& polyOffset)
>>> {
>>>   _polyOffset = polyOffset;
>>> }
>>>
>>> void ShadowMap::setAmbientBias(const osg::Vec2& ambientBias)
>>> {
>>>   _ambientBias = ambientBias;
>>>   if (_ambientBiasUniform.valid())
>>> _ambientBiasUniform->set(_ambientBias);
>>> }
>>>
>>> void ShadowMap::setTextureSize(const osg::Vec2s& textureSize)
>>> {
>>>   _textureSize = textureSize;
>>>   dirty();
>>> }
>>>
>>> void ShadowMap::setLight(osg::Light* light)
>>> {
>>>   _light = light;
>>> }
>>>
>>>
>>> void ShadowMap::setLight(osg::LightSource* ls)
>>> {
>>>   _ls = ls;
>>>   _light = _ls->getLight();
>>> }
>>>
>>> void ShadowMap::createUniforms()
>>> {
>>>   _uniformList.clear();
>>>
>>>   osg::Uniform* baseTextureSampler = new
>>> osg::Uniform("osgShadow_baseTexture",(int)_baseTextureUnit);
>>>   _uniformList.push_back(baseTextureSampler);
>>>
>>>   osg::Uniform* shadowTextureSampler = new
>>> osg::Uniform("osgShadow_shadowTexture",(int)_shadowTextureUnit);
>>>   _uniformList.push_back(shadowTextureSampler);
>>>
>>>   _ambientBiasUniform = new
>>> osg::Uniform("osgShadow_ambientBias",_ambientBias);
>>>   _uniformList.push_back(_ambientBiasUniform.get());
>>>
>>> }
>>>
>>> void ShadowMap::createShaders()
>>> {
>>>   // if we are not given shaders, use the default
>>>   if( _shaderList.empty() )
>>>   {
>>>       if (_shadowTextureUnit==0)
>>>       {
>>>           osg::Shader* fragment_shader = new
>>> osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_noBaseTexture);
>>>           _shaderList.push_back(fragment_shader);
>>>       }
>>>       else
>>>       {
>>>           osg::Shader* fragment_shader = new
>>> osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_withBaseTexture);
>>>           _shaderList.push_back(fragment_shader);
>>>
>>>       }
>>>   }
>>> }
>>>
>>> void ShadowMap::init()
>>> {
>>>   if (!_shadowedScene) return;
>>>
>>>   _texture = new osg::Texture2D;
>>>   _texture->setTextureSize(_textureSize.x(), _textureSize.y());
>>>   _texture->setInternalFormat(GL_DEPTH_COMPONENT);
>>>   _texture->setShadowComparison(true);
>>>   _texture->setShadowTextureMode(osg::Texture2D::LUMINANCE);
>>>
>>> _texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
>>>
>>> _texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
>>>
>>>   // the shadow comparison should fail if object is outside the texture
>>>
>>>
>>>
>>> _texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
>>>
>>>
>>>
>>> _texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
>>>   _texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
>>>
>>>   // set up the render to texture camera.
>>>   {
>>>       // create the camera
>>>       _camera = new osg::Camera;
>>>
>>>
>>>  _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);
>>>
>>>       _camera->setCullCallback(new CameraCullCallback(this));
>>>
>>>       _camera->setClearMask(GL_DEPTH_BUFFER_BIT);
>>>       //_camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
>>>       _camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
>>>
>>> _camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
>>>
>>>       // set viewport
>>>       _camera->setViewport(0,0,_textureSize.x(),_textureSize.y());
>>>
>>>       // set the camera to render before the main camera.
>>>       _camera->setRenderOrder(osg::Camera::PRE_RENDER);
>>>
>>>       // tell the camera to use OpenGL frame buffer object where
>>> supported.
>>>
>>>
>>> _camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
>>>
>>>  //_camera->setRenderTargetImplementation(osg::Camera::SEPERATE_WINDOW);
>>>
>>>       // attach the texture and use it as the color buffer.
>>>       _camera->attach(osg::Camera::DEPTH_BUFFER, _texture.get());
>>>
>>>       osg::StateSet* stateset = _camera->getOrCreateStateSet();
>>>
>>>
>>> #if 1
>>>       // cull front faces so that only backfaces contribute to depth map
>>>
>>>
>>>       osg::ref_ptr<osg::CullFace> cull_face = new osg::CullFace;
>>>       cull_face->setMode(osg::CullFace::FRONT);
>>>       stateset->setAttribute(cull_face.get(), osg::StateAttribute::ON |
>>> osg::StateAttribute::OVERRIDE);
>>>       stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON |
>>> osg::StateAttribute::OVERRIDE);
>>>
>>>       // negative polygonoffset - move the backface nearer to the eye
>>> point
>>> so that backfaces
>>>       // shadow themselves
>>>       float factor = -_polyOffset[0];
>>>       float units =  -_polyOffset[1];
>>>
>>>       osg::ref_ptr<osg::PolygonOffset> polygon_offset = new
>>> osg::PolygonOffset;
>>>       polygon_offset->setFactor(factor);
>>>       polygon_offset->setUnits(units);
>>>       stateset->setAttribute(polygon_offset.get(),
>>> osg::StateAttribute::ON
>>> | osg::StateAttribute::OVERRIDE);
>>>       stateset->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON |
>>> osg::StateAttribute::OVERRIDE);
>>> #else
>>>       // disabling cull faces so that only front and backfaces contribute
>>> to depth map
>>>       stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF |
>>> osg::StateAttribute::OVERRIDE);
>>>
>>>       // negative polygonoffset - move the backface nearer to the eye
>>> point
>>>       // so that front faces do not shadow themselves.
>>>       float factor = _polyOffset[0];
>>>       float units =  _polyOffset[1];
>>>
>>>       osg::ref_ptr<osg::PolygonOffset> polygon_offset = new
>>> osg::PolygonOffset;
>>>       polygon_offset->setFactor(factor);
>>>       polygon_offset->setUnits(units);
>>>       stateset->setAttribute(polygon_offset.get(),
>>> osg::StateAttribute::ON
>>> | osg::StateAttribute::OVERRIDE);
>>>       stateset->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON |
>>> osg::StateAttribute::OVERRIDE);
>>> #endif
>>>   }
>>>
>>>   {
>>>       _stateset = new osg::StateSet;
>>>
>>>
>>>
>>> _stateset->setTextureAttributeAndModes(_shadowTextureUnit,_texture.get(),osg::StateAttribute::ON
>>> | osg::StateAttribute::OVERRIDE);
>>>
>>>
>>>
>>> _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
>>>
>>>
>>>
>>> _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
>>>
>>>
>>>
>>> _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
>>>
>>>
>>>
>>> _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
>>>
>>>       _texgen = new osg::TexGen;
>>>
>>>       // add Program, when empty of Shaders then we are using fixed
>>> functionality
>>>       _program = new osg::Program;
>>>       _stateset->setAttribute(_program.get());
>>>
>>>       // create default shaders if needed
>>>       createShaders();
>>>
>>>       // add the shader list to the program
>>>       for(ShaderList::const_iterator itr=_shaderList.begin();
>>>           itr!=_shaderList.end();
>>>           ++itr)
>>>       {
>>>           _program->addShader(itr->get());
>>>       }
>>>
>>>       // create own uniforms
>>>       createUniforms();
>>>
>>>       // add the uniform list to the stateset
>>>       for(UniformList::const_iterator itr=_uniformList.begin();
>>>           itr!=_uniformList.end();
>>>           ++itr)
>>>       {
>>>           _stateset->addUniform(itr->get());
>>>       }
>>>
>>>       {
>>>           // fake texture for baseTexture, add a fake texture
>>>           // we support by default at least one texture layer
>>>           // without this fake texture we can not support
>>>           // textured and not textured scene
>>>
>>>           // TODO: at the moment the PSSM supports just one texture layer
>>> in the GLSL shader, multitexture are
>>>           //       not yet supported !
>>>
>>>           osg::Image* image = new osg::Image;
>>>           // allocate the image data, noPixels x 1 x 1 with 4 rgba floats
>>> -
>>> equivilant to a Vec4!
>>>           int noPixels = 1;
>>>           image->allocateImage(noPixels,1,1,GL_RGBA,GL_FLOAT);
>>>           image->setInternalTextureFormat(GL_RGBA);
>>>           // fill in the image data.
>>>           osg::Vec4* dataPtr = (osg::Vec4*)image->data();
>>>           osg::Vec4 color(1,1,1,1);
>>>           *dataPtr = color;
>>>           // make fake texture
>>>           osg::Texture2D* fakeTex = new osg::Texture2D;
>>>
>>>  fakeTex->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_EDGE);
>>>
>>>  fakeTex->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_EDGE);
>>>
>>>  fakeTex->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
>>>
>>>  fakeTex->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
>>>           fakeTex->setImage(image);
>>>           // add fake texture
>>>
>>>
>>>
>>> _stateset->setTextureAttribute(_baseTextureUnit,fakeTex,osg::StateAttribute::ON);
>>>
>>>
>>>
>>> _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_1D,osg::StateAttribute::OFF);
>>>
>>>
>>>
>>> _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_2D,osg::StateAttribute::ON);
>>>
>>>
>>>
>>> _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_3D,osg::StateAttribute::OFF);
>>>       }
>>>   }
>>>
>>>   _dirty = false;
>>> }
>>>
>>>
>>> void ShadowMap::update(osg::NodeVisitor& nv)
>>> {
>>>   _shadowedScene->osg::Group::traverse(nv);
>>> }
>>>
>>> void ShadowMap::cull(osgUtil::CullVisitor& cv)
>>> {
>>>   // record the traversal mask on entry so we can reapply it later.
>>>   unsigned int traversalMask = cv.getTraversalMask();
>>>
>>>   osgUtil::RenderStage* orig_rs = cv.getRenderStage();
>>>
>>>   // do traversal of shadow recieving scene which does need to be
>>> decorated
>>> by the shadow map
>>>   {
>>>       cv.pushStateSet(_stateset.get());
>>>
>>>       _shadowedScene->osg::Group::traverse(cv);
>>>
>>>       cv.popStateSet();
>>>
>>>   }
>>>
>>>   // need to compute view frustum for RTT camera.
>>>   // 1) get the light position
>>>   // 2) get the center and extents of the view frustum
>>>
>>>   const osg::Light* selectLight = 0;
>>>   osg::Vec4 lightpos;
>>>   osg::Vec3 lightDir;
>>>
>>>   //MR testing giving a specific light
>>>   osgUtil::PositionalStateContainer::AttrMatrixList& aml =
>>> orig_rs->getPositionalStateContainer()->getAttrMatrixList();
>>>   for(osgUtil::PositionalStateContainer::AttrMatrixList::iterator itr =
>>> aml.begin();
>>>       itr != aml.end();
>>>       ++itr)
>>>   {
>>>       const osg::Light* light = dynamic_cast<const
>>> osg::Light*>(itr->first.get());
>>>       if (light)
>>>       {
>>>           if( _light.valid()) {
>>>               if( _light.get() == light )
>>>                   selectLight = light;
>>>               else
>>>                   continue;
>>>           }
>>>           else
>>>               selectLight = light;
>>>
>>>           osg::RefMatrix* matrix = itr->second.get();
>>>           if (matrix)
>>>           {
>>>               lightpos = light->getPosition() * (*matrix);
>>>               lightDir = osg::Matrix::transform3x3(
>>> light->getDirection(),
>>> *matrix );
>>>           }
>>>           else
>>>           {
>>>               lightpos = light->getPosition();
>>>               lightDir = light->getDirection();
>>>           }
>>>
>>>       }
>>>   }
>>>
>>>   osg::Matrix eyeToWorld;
>>>   eyeToWorld.invert(*cv.getModelViewMatrix());
>>>
>>>   lightpos = lightpos * eyeToWorld;
>>>   lightDir = osg::Matrix::transform3x3( lightDir, eyeToWorld );
>>>   lightDir.normalize();
>>>
>>>   if (selectLight)
>>>   {
>>>
>>>       // set to ambient on light to black so that the ambient bias
>>> uniform
>>> can take it's affect
>>>
>>>
>>>
>>> const_cast<osg::Light*>(selectLight)->setAmbient(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
>>>
>>>       //std::cout<<"----- VxOSG::ShadowMap selectLight spot cutoff
>>> "<<selectLight->getSpotCutoff()<<std::endl;
>>>
>>>       float fov = selectLight->getSpotCutoff() * 2;
>>>       if(fov < 180.0f)   // spotlight, then we don't need the bounding
>>> box
>>>       {
>>>           osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z());
>>>           _camera->setProjectionMatrixAsPerspective(fov, 1.0, 0.1,
>>> 1000.0);
>>>
>>>
>>>
>>> _camera->setViewMatrixAsLookAt(position,position+lightDir,osg::Vec3(0.0f,1.0f,0.0f));
>>>       }
>>>       else
>>>       {
>>>           // get the bounds of the model.
>>>           osg::ComputeBoundsVisitor
>>> cbbv(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
>>>
>>>
>>> cbbv.setTraversalMask(getShadowedScene()->getCastsShadowTraversalMask());
>>>
>>>           _shadowedScene->osg::Group::traverse(cbbv);
>>>
>>>           osg::BoundingBox bb = cbbv.getBoundingBox();
>>>
>>>           if (lightpos[3]!=0.0)   // point light
>>>           {
>>>               osg::Vec3 position(lightpos.x(), lightpos.y(),
>>> lightpos.z());
>>>
>>>               float centerDistance = (position-bb.center()).length();
>>>
>>>               float znear = centerDistance-bb.radius();
>>>               float zfar  = centerDistance+bb.radius();
>>>               float zNearRatio = 0.001f;
>>>               if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
>>>
>>>               float top   = (bb.radius()/centerDistance)*znear;
>>>               float right = top;
>>>
>>>
>>>  _camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
>>>
>>>
>>>
>>> _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f));
>>>           }
>>>           else    // directional light
>>>           {
>>>               // make an orthographic projection
>>>               osg::Vec3 lightDir(lightpos.x(), lightpos.y(),
>>> lightpos.z());
>>>               lightDir.normalize();
>>>
>>>               // set the position far away along the light direction
>>>               osg::Vec3 position = bb.center() + lightDir * bb.radius() *
>>> 2;
>>>
>>>               float centerDistance = (position-bb.center()).length();
>>>
>>>               float znear = centerDistance-bb.radius();
>>>               float zfar  = centerDistance+bb.radius();
>>>               float zNearRatio = 0.001f;
>>>               if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
>>>
>>>               float top   = bb.radius();
>>>               float right = top;
>>>
>>>               _camera->setProjectionMatrixAsOrtho(-right, right, -top,
>>> top,
>>> znear, zfar);
>>>
>>>
>>>
>>> _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f));
>>>           }
>>>
>>>
>>>       }
>>>
>>>       cv.setTraversalMask( traversalMask &
>>>           getShadowedScene()->getCastsShadowTraversalMask() );
>>>
>>>       // do RTT camera traversal
>>>       _camera->accept(cv);
>>>
>>>       _texgen->setMode(osg::TexGen::EYE_LINEAR);
>>>
>>> #if IMPROVE_TEXGEN_PRECISION
>>>       // compute the matrix which takes a vertex from local coords into
>>> tex
>>> coords
>>>       // We actually use two matrices one used to define texgen
>>>       // and second that will be used as modelview when appling to OpenGL
>>>       _texgen->setPlanesFromMatrix( _camera->getProjectionMatrix() *
>>>                                     osg::Matrix::translate(1.0,1.0,1.0) *
>>>                                     osg::Matrix::scale(0.5f,0.5f,0.5f) );
>>>
>>>       // Place texgen with modelview which removes big offsets (making it
>>> float friendly)
>>>       osg::RefMatrix * refMatrix = new osg::RefMatrix
>>>           ( _camera->getInverseViewMatrix() * *cv.getModelViewMatrix() );
>>>
>>>       cv.getRenderStage()->getPositionalStateContainer()->
>>>            addPositionedTextureAttribute( _shadowTextureUnit, refMatrix,
>>> _texgen.get() );
>>> #else
>>>       // compute the matrix which takes a vertex from local coords into
>>> tex
>>> coords
>>>       // will use this later to specify osg::TexGen..
>>>       osg::Matrix MVPT = _camera->getViewMatrix() *
>>>              _camera->getProjectionMatrix() *
>>>              osg::Matrix::translate(1.0,1.0,1.0) *
>>>              osg::Matrix::scale(0.5f,0.5f,0.5f);
>>>
>>>       _texgen->setPlanesFromMatrix(MVPT);
>>>
>>>
>>>
>>>
>>> orig_rs->getPositionalStateContainer()->addPositionedTextureAttribute(_shadowTextureUnit,
>>> cv.getModelViewMatrix(), _texgen.get());
>>> #endif
>>>   } // if(selectLight)
>>>
>>>
>>>   // reapply the original traversal mask
>>>   cv.setTraversalMask( traversalMask );
>>> }
>>>
>>> void ShadowMap::cleanSceneGraph()
>>> {
>>> }
>>>
>>> ///////////////////// Debug Methods
>>>
>>>
>>> ////////////////////////////////////////////////////////////////////////////////
>>> osg::ref_ptr<osg::Camera> ShadowMap::makeDebugHUD()
>>> {
>>>
>>> ////////////////////////////////////////////////////////////////////////////////
>>> // Callback used by debugging hud to display Shadow Map in color buffer
>>> // OSG does not allow to use the same GL Texture Id with different
>>> glTexParams.
>>> // Callback simply turns shadow compare mode off via GL while rendering
>>> hud
>>> and
>>> // restores it afterwards.
>>>
>>> ////////////////////////////////////////////////////////////////////////////////
>>>       class DrawableDrawWithDepthShadowComparisonOffCallback:
>>>               public osg::Drawable::DrawCallback
>>>       {
>>>       public:
>>>               //
>>>               DrawableDrawWithDepthShadowComparisonOffCallback
>>>                       ( osg::Texture2D * texture, unsigned stage = 0 )
>>>                               : _texture( texture ), _stage( stage )
>>>               {
>>>               }
>>>
>>>               virtual void drawImplementation
>>>                       ( osg::RenderInfo & ri,const osg::Drawable*
>>> drawable
>>> ) const
>>>               {
>>>                       if( _texture.valid() ) {
>>>                               // make sure proper texture is currently
>>> applied
>>>                               ri.getState()->applyTextureAttribute(
>>> _stage,
>>> _texture.get() );
>>>
>>>                               // Turn off depth comparison mode
>>>                               glTexParameteri( GL_TEXTURE_2D,
>>> GL_TEXTURE_COMPARE_MODE_ARB,
>>>                                                                GL_NONE );
>>>                       }
>>>
>>>                       drawable->drawImplementation(ri);
>>>
>>>                       if( _texture.valid() ) {
>>>                               // Turn it back on
>>>                               glTexParameteri( GL_TEXTURE_2D,
>>> GL_TEXTURE_COMPARE_MODE_ARB,
>>>
>>> GL_COMPARE_R_TO_TEXTURE_ARB );
>>>                       }
>>>               }
>>>
>>>               osg::ref_ptr< osg::Texture2D > _texture;
>>>               unsigned                       _stage;
>>>       };
>>>
>>>   // Make sure we attach initialized texture to HUD
>>>   if( !_texture.valid() )    init();
>>>
>>>   osg::ref_ptr<osg::Camera> camera = new osg::Camera;
>>>
>>>   osg::Vec2 size(1280, 1024);
>>>   // set the projection matrix
>>>
>>> camera->setProjectionMatrix(osg::Matrix::ortho2D(0,size.x(),0,size.y()));
>>>
>>>   // set the view matrix
>>>   camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
>>>   camera->setViewMatrix(osg::Matrix::identity());
>>>
>>>   // only clear the depth buffer
>>>   camera->setClearMask(GL_DEPTH_BUFFER_BIT);
>>>   camera->setClearColor(osg::Vec4(0.2f, 0.3f, 0.5f, 0.2f));
>>>   //camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
>>>
>>>   // draw subgraph after main camera view.
>>>   camera->setRenderOrder(osg::Camera::POST_RENDER);
>>>
>>>   // we don't want the camera to grab event focus from the viewers main
>>> camera(s).
>>>   camera->setAllowEventFocus(false);
>>>
>>>   osg::Geode* geode = new osg::Geode;
>>>
>>>   osg::Vec3 position(10.0f,size.y()-100.0f,0.0f);
>>>   osg::Vec3 delta(0.0f,-120.0f,0.0f);
>>>   float length = 300.0f;
>>>
>>>   // turn the text off to avoid linking with osgText
>>> #if 0
>>>   std::string timesFont("fonts/arial.ttf");
>>>
>>>   {
>>>       osgText::Text* text = new  osgText::Text;
>>>       geode->addDrawable( text );
>>>
>>>       text->setFont(timesFont);
>>>       text->setPosition(position);
>>>       text->setText("Shadow Map HUD");
>>>
>>>       position += delta;
>>>   }
>>> #endif
>>>
>>>   osg::Vec3 widthVec(length, 0.0f, 0.0f);
>>>   osg::Vec3 depthVec(0.0f,length, 0.0f);
>>>   osg::Vec3 centerBase( 10.0f + length/2, size.y()-length/2, 0.0f);
>>>   centerBase += delta;
>>>
>>>   osg::Geometry *geometry = osg::createTexturedQuadGeometry
>>>       ( centerBase-widthVec*0.5f-depthVec*0.5f, widthVec, depthVec );
>>>
>>>   geode->addDrawable( geometry );
>>>
>>>   geometry->setDrawCallback
>>>       ( new DrawableDrawWithDepthShadowComparisonOffCallback(
>>> _texture.get() ) );
>>>
>>>   osg::StateSet* stateset = geode->getOrCreateStateSet();
>>>
>>>   stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
>>>   stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
>>>   stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
>>>
>>>   // test with regular texture
>>>   //stateset->setTextureAttributeAndModes(0, new
>>> osg::Texture2D(osgDB::readImageFile("Images/lz.rgb")));
>>>
>>>
>>>
>>>
>>> stateset->setTextureAttributeAndModes(0,_texture.get(),osg::StateAttribute::ON);
>>>
>>>   //test to check the texture coordinates generated during shadow pass
>>> #if 0
>>>
>>>
>>>
>>> stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
>>>
>>>
>>>
>>> stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
>>>
>>>
>>>
>>> stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
>>>
>>>
>>>
>>> stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
>>>
>>>   // create TexGen node
>>>   osg::ref_ptr<osg::TexGenNode> texGenNode = new osg::TexGenNode;
>>>   texGenNode->setTextureUnit(_shadowTextureUnit);
>>>   texGenNode->setTexGen(_texgen.get());
>>>   camera->addChild(texGenNode.get());
>>> #endif
>>>   //shader for correct display
>>>
>>>   osg::ref_ptr<osg::Program> program = new osg::Program;
>>>   stateset->setAttribute(program.get());
>>>
>>>   osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT,
>>> fragmentShaderSource_debugHUD);
>>>   program->addShader(fragment_shader);
>>>
>>>   camera->addChild(geode);
>>>
>>>   return camera;
>>> }
>>>
>>> //////////////////////// End Debug Section
>>>
>>>
>>> _______________________________________________
>>> osg-submissions mailing list
>>> [email protected]
>>>
>>> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>>>
>>>
>> _______________________________________________
>> osg-submissions mailing list
>> [email protected]
>>
>> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to