Changeset 13041 for OpenSceneGraph/trunk/src/osgShadow/DebugShadowMap.cpp
- Timestamp:
- 03/21/12 18:36:20 (14 months ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osgShadow/DebugShadowMap.cpp
r12292 r13041 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 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 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 5 * (at your option) any later version. The full license is in LICENSE file 6 6 * included with this distribution, and on the openscenegraph.org website. 7 * 7 * 8 8 * This library is distributed in the hope that it will be useful, 9 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 11 * OpenSceneGraph Public License for more details. 12 12 * … … 36 36 #define DEFAULT_DEBUG_HUD_ORIGIN_Y 8 37 37 38 DebugShadowMap::DebugShadowMap(): 38 DebugShadowMap::DebugShadowMap(): 39 39 BaseClass(), 40 40 _hudSize( 2, 2 ), 41 41 _hudOrigin( -1, -1 ), 42 42 _viewportSize( DEFAULT_DEBUG_HUD_SIZE_X, DEFAULT_DEBUG_HUD_SIZE_Y ), 43 _viewportOrigin( DEFAULT_DEBUG_HUD_ORIGIN_X, DEFAULT_DEBUG_HUD_ORIGIN_Y ), 43 _viewportOrigin( DEFAULT_DEBUG_HUD_ORIGIN_X, DEFAULT_DEBUG_HUD_ORIGIN_Y ), 44 44 _orthoSize( 2, 2 ), 45 45 _orthoOrigin( -1, -1 ), 46 46 _doDebugDraw( false ) 47 47 { 48 48 49 49 // Why this fancy 24 bit depth to 24 bit rainbow colors shader ? 50 50 // 51 // Depth values cannot be easily cast on color component because they are: 52 // a) 24 or 32 bit and we loose lots of precision when cast on 8 bit 51 // Depth values cannot be easily cast on color component because they are: 52 // a) 24 or 32 bit and we loose lots of precision when cast on 8 bit 53 53 // b) depth value distribution is non linear due to projection division 54 54 // when cast on componenent color there is usually very minor shade variety 55 55 // and its often difficult to notice that there is anything in the buffer 56 // 57 // Shader looks complex but it is used only for debug head-up rectangle 58 // so performance impact is not significant. 59 56 // 57 // Shader looks complex but it is used only for debug head-up rectangle 58 // so performance impact is not significant. 59 60 60 _depthColorFragmentShader = new osg::Shader( osg::Shader::FRAGMENT, 61 #if 0 61 #if 0 62 62 "uniform sampler2D texture; \n" 63 63 " \n" … … 66 66 " float f = texture2D( texture, vec3( gl_TexCoord[0].xy, 1.0).xy ).r; \n" 67 67 " gl_FragColor = vec4( 0.0, 1.0 - f, 0.5 - f, 0.5 ); \n" 68 "} \n" 69 #else 68 "} \n" 69 #else 70 70 "uniform sampler2D texture; \n" 71 71 " \n" … … 75 75 " \n" 76 76 " f = 256.0 * f; \n" 77 " float fC = floor( f ) / 256.0; \n" 77 " float fC = floor( f ) / 256.0; \n" 78 78 " \n" 79 79 " f = 256.0 * fract( f ); \n" 80 " float fS = floor( f ) / 256.0; \n" 80 " float fS = floor( f ) / 256.0; \n" 81 81 " \n" 82 82 " f = 256.0 * fract( f ); \n" … … 89 89 " abs( fC - 0.333333 ), \n" 90 90 " abs( fC - 0.666667 ) ); \n" 91 " \n" 91 " \n" 92 92 " rgb = min( vec3( 1.0, 1.0, 1.0 ), 3.0 * rgb ); \n" 93 93 " \n" 94 94 " float fMax = max( max( rgb.r, rgb.g ), rgb.b ); \n" 95 " fMax = 1.0 / fMax; \n" 95 " fMax = 1.0 / fMax; \n" 96 96 " \n" 97 97 " vec3 color = fMax * rgb; \n" 98 98 " \n" 99 99 " gl_FragColor = vec4( fS + fH * color, 1 ) * gl_Color; \n" 100 "} \n" 101 #endif 102 ); // end _depthColorFragmentShader 100 "} \n" 101 #endif 102 ); // end _depthColorFragmentShader 103 103 } 104 104 … … 109 109 _hudOrigin( copy._hudOrigin ), 110 110 _viewportSize( copy._viewportSize ), 111 _viewportOrigin( copy._viewportOrigin ), 111 _viewportOrigin( copy._viewportOrigin ), 112 112 _orthoSize( copy._viewportOrigin ), 113 113 _orthoOrigin( copy._viewportOrigin ), … … 120 120 } 121 121 122 DebugShadowMap::~DebugShadowMap() 122 DebugShadowMap::~DebugShadowMap() 123 123 { 124 124 } … … 145 145 result = bb.center() != bb_prev.center() || bb.radius() != bb_prev.radius(); 146 146 if( result ) 147 std::cout << "Box<" << name << "> (" 147 std::cout << "Box<" << name << "> (" 148 148 << ( bb._max._v[0] + bb._min._v[0] ) * 0.5 << " " 149 << ( bb._max._v[1] + bb._min._v[1] ) * 0.5 << " " 149 << ( bb._max._v[1] + bb._min._v[1] ) * 0.5 << " " 150 150 << ( bb._max._v[2] + bb._min._v[2] ) * 0.5 << ") [" 151 151 << ( bb._max._v[0] - bb._min._v[0] ) << " " … … 171 171 172 172 if( result ) { 173 std::cout << "Polytope<" << name 173 std::cout << "Polytope<" << name 174 174 << "> size(" << p.getPlaneList().size() << ")" 175 175 << std::endl; … … 180 180 if( p.getPlaneList()[i] != p_prev.getPlaneList()[i] ) 181 181 { 182 std::cout << "Plane<" << i 183 << "> (" 182 std::cout << "Plane<" << i 183 << "> (" 184 184 << p.getPlaneList()[i].asVec4()[0] << ", " 185 185 << p.getPlaneList()[i].asVec4()[1] << ", " 186 186 << p.getPlaneList()[i].asVec4()[2] << ", " 187 187 << p.getPlaneList()[i].asVec4()[3] << ")" 188 << std::endl; 188 << std::endl; 189 189 } 190 190 } … … 209 209 210 210 if( result ) 211 std::cout << "Matrix<" << name << "> " << std::endl 211 std::cout << "Matrix<" << name << "> " << std::endl 212 212 <<"[ " << m(0,0) << " " << m(0,1) << " " << m(0,2) << " " << m(0,3) << " ] " << std::endl 213 213 <<"[ " << m(1,0) << " " << m(1,1) << " " << m(1,2) << " " << m(1,3) << " ] " << std::endl … … 221 221 222 222 void DebugShadowMap::ViewData::setDebugPolytope 223 ( const char * name, const ConvexPolyhedron & polytope, 223 ( const char * name, const ConvexPolyhedron & polytope, 224 224 osg::Vec4 colorOutline, osg::Vec4 colorInside ) 225 225 { 226 226 if( !getDebugDraw() ) return; 227 227 228 if( &polytope == NULL ) { // delete 228 if( &polytope == NULL ) { // delete 229 229 PolytopeGeometry & pg = _polytopeGeometryMap[ std::string( name ) ]; 230 230 for( unsigned int i = 0; i < VECTOR_LENGTH( pg._geometry ) ; i++ ) … … 257 257 } 258 258 259 if( _geode[i].valid() && 259 if( _geode[i].valid() && 260 260 !_geode[i]->containsDrawable( pg._geometry[i].get() ) ) { 261 osg::Geode::DrawableList & dl = 261 osg::Geode::DrawableList & dl = 262 262 const_cast< osg::Geode::DrawableList &> 263 263 ( _geode[i]->getDrawableList() ); 264 264 dl.insert( dl.begin(), pg._geometry[i].get() ); 265 } 266 } 265 } 266 } 267 267 } 268 268 } … … 275 275 276 276 const int num = 2; // = VECTOR_LENGTH( PolytopeGeometry::_geometry ); 277 278 osg::Matrix 279 transform[ num ] = 280 { viewCam->getViewMatrix() * 277 278 osg::Matrix 279 transform[ num ] = 280 { viewCam->getViewMatrix() * 281 281 // use near far clamped projection ( precomputed in cullDebugGeometry ) 282 282 ( _viewCamera==viewCam ? _viewProjection : viewCam->getProjectionMatrix() ), 283 shadowCam->getViewMatrix() * shadowCam->getProjectionMatrix() }, 284 inverse[ num ] = 283 shadowCam->getViewMatrix() * shadowCam->getProjectionMatrix() }, 284 inverse[ num ] = 285 285 { osg::Matrix::inverse( transform[0] ), 286 286 osg::Matrix::inverse( transform[1] ) }; … … 293 293 frustum[i].transform( inverse[i], transform[i] ); 294 294 #else 295 frustum[i].transform 295 frustum[i].transform 296 296 ( osg::Matrix::inverse( camera[i]->getProjectionMatrix() ), 297 297 camera[i]->getProjectionMatrix() ); 298 frustum[i].transform 298 frustum[i].transform 299 299 ( osg::Matrix::inverse( camera[i]->getViewMatrix() ), 300 300 camera[i]->getViewMatrix() ); 301 #endif 301 #endif 302 302 }; 303 303 #else … … 321 321 { 322 322 323 ConvexPolyhedron cp( pg._polytope ); 323 ConvexPolyhedron cp( pg._polytope ); 324 324 cp.cut( frustum[i] ); 325 325 cp.transform( transform[i], inverse[i] ); … … 332 332 333 333 void DebugShadowMap::ViewData::cullDebugGeometry( ) 334 { 334 { 335 335 if( !getDebugDraw() ) return; 336 336 if( !_camera.valid() ) return; 337 337 338 // View camera may use clamping projection matrix after traversal. 338 // View camera may use clamping projection matrix after traversal. 339 339 // Since we need to know exact matrix for drawing the frusta, 340 // we have to compute it here in exactly the same way as cull visitor 340 // we have to compute it here in exactly the same way as cull visitor 341 341 // will after cull traversal completes view camera subgraph. 342 342 { … … 347 347 348 348 // Redo steps from CullVisitor::popProjectionMatrix() 349 // which clamps projection matrix when Camera & Projection 349 // which clamps projection matrix when Camera & Projection 350 350 // completes traversal of their children 351 351 352 // We have to do this now manually 353 // because we did not complete camera traversal yet but 352 // We have to do this now manually 353 // because we did not complete camera traversal yet but 354 354 // we need to know how this clamped projection matrix will be 355 355 356 356 _cv->computeNearPlane(); 357 357 358 358 osgUtil::CullVisitor::value_type n = _cv->getCalculatedNearPlane(); 359 359 osgUtil::CullVisitor::value_type f = _cv->getCalculatedFarPlane(); … … 363 363 } 364 364 } 365 365 366 366 updateDebugGeometry( _viewCamera.get(), _camera.get() ); 367 368 #if 1 // Add geometries of polytopes to main cam Render Stage 367 368 #if 1 // Add geometries of polytopes to main cam Render Stage 369 369 _transform[0]->accept( *_cv ); 370 370 #else … … 401 401 { 402 402 // view can be a slave that covers only a fraction of the screen 403 // so adjust debug hud location to proper viewport location 403 // so adjust debug hud location to proper viewport location 404 404 _viewportOrigin[0] += vp->x(); 405 405 _viewportOrigin[1] += vp->y(); … … 414 414 _orthoSize = st->_orthoSize; 415 415 _orthoOrigin = st->_orthoOrigin; 416 416 417 417 _depthColorFragmentShader = st->_depthColorFragmentShader; 418 418 … … 421 421 _geode[0] = new osg::Geode; 422 422 _geode[1] = new osg::Geode; 423 423 424 424 _cameraDebugHUD = NULL;//Force debug HUD rebuild ( if needed ) 425 425 } … … 427 427 428 428 // Callback used by debugging hud to display Shadow Map to color buffer 429 // Had to do it this way because OSG does not allow to use 430 // the same GL Texture Id with different glTexParams. 431 // Callback simply turns compare mode off via GL while rendering hud and 432 // restores it before rendering the scene with shadows. 433 class DebugShadowMap::DrawableDrawWithDepthShadowComparisonOffCallback: 429 // Had to do it this way because OSG does not allow to use 430 // the same GL Texture Id with different glTexParams. 431 // Callback simply turns compare mode off via GL while rendering hud and 432 // restores it before rendering the scene with shadows. 433 class DebugShadowMap::DrawableDrawWithDepthShadowComparisonOffCallback: 434 434 public osg::Drawable::DrawCallback 435 435 { 436 436 public: 437 DrawableDrawWithDepthShadowComparisonOffCallback( osg::Texture *pTex ) 437 DrawableDrawWithDepthShadowComparisonOffCallback( osg::Texture *pTex ) 438 438 : _pTexture( pTex ) 439 439 { … … 451 451 452 452 // Turn it back on 453 glTexParameteri( _pTexture->getTextureTarget(), GL_TEXTURE_COMPARE_MODE_ARB, 454 GL_COMPARE_R_TO_TEXTURE_ARB ); 453 glTexParameteri( _pTexture->getTextureTarget(), GL_TEXTURE_COMPARE_MODE_ARB, 454 GL_COMPARE_R_TO_TEXTURE_ARB ); 455 455 } 456 456 … … 460 460 void DebugShadowMap::ViewData::dump( const std::string & filename ) 461 461 { 462 osg::ref_ptr< osg::Group > root = new osg::Group; 462 osg::ref_ptr< osg::Group > root = new osg::Group; 463 463 osgUtil::CullVisitor * cv = _cv.get(); 464 464 … … 487 487 { 488 488 489 ConvexPolyhedron cp( pg._polytope ); 489 ConvexPolyhedron cp( pg._polytope ); 490 490 491 491 pg._geometry[i] = cp.buildGeometry … … 505 505 506 506 void DebugShadowMap::ViewData::createDebugHUD( ) 507 { 507 { 508 508 _cameraDebugHUD = new osg::Camera; 509 509 … … 519 519 } 520 520 521 { // Initialize hud camera 521 { // Initialize hud camera 522 522 osg::Camera * camera = _cameraDebugHUD.get(); 523 523 camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); … … 527 527 _viewportSize[0], _viewportSize[1] ); 528 528 529 camera->setProjectionMatrixAsOrtho( 530 _orthoOrigin[0], _orthoOrigin[0] + _orthoSize[0], 529 camera->setProjectionMatrixAsOrtho( 530 _orthoOrigin[0], _orthoOrigin[0] + _orthoSize[0], 531 531 _orthoOrigin[1], _orthoOrigin[1] + _orthoSize[1], 532 -10, 10 ); 532 -10, 10 ); 533 533 534 534 camera->setClearMask(GL_DEPTH_BUFFER_BIT); … … 541 541 _cameraDebugHUD->addChild(geode); 542 542 543 // finally create and attach hud geometry 543 // finally create and attach hud geometry 544 544 osg::Geometry* geometry = osg::createTexturedQuadGeometry 545 545 ( osg::Vec3(_hudOrigin[0],_hudOrigin[1],0), 546 osg::Vec3(_hudSize[0],0,0), 546 osg::Vec3(_hudSize[0],0,0), 547 547 osg::Vec3(0,_hudSize[1],0) ); 548 548 549 549 osg::StateSet* stateset = _cameraDebugHUD->getOrCreateStateSet(); 550 550 stateset->setTextureAttribute(0,_texture.get(),osg::StateAttribute::ON ); … … 554 554 ( new osg::Depth( osg::Depth::ALWAYS, 0, 1, false ) ); 555 555 stateset->setMode(GL_BLEND,osg::StateAttribute::ON); 556 556 557 557 osg::Program* program = new osg::Program; 558 558 program->addShader( _depthColorFragmentShader.get() ); … … 573 573 stateset->setMode(GL_BLEND, osg::StateAttribute::ON); 574 574 stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); 575 stateset->setAttribute( new osg::Program() ); 575 stateset->setAttribute( new osg::Program() ); 576 576 stateset->setAttributeAndModes 577 577 ( new osg::Depth( osg::Depth::LEQUAL, 0, 1, false ) ); … … 586 586 587 587 _transform[1]->setMatrix 588 ( osg::Matrix::translate( 1, 1, 0 ) * 588 ( osg::Matrix::translate( 1, 1, 0 ) * 589 589 osg::Matrix::scale( 0.5, 0.5, 1 ) * 590 osg::Matrix::scale( _hudSize[0], _hudSize[1], 1 ) * 590 osg::Matrix::scale( _hudSize[0], _hudSize[1], 1 ) * 591 591 osg::Matrix::translate( _hudOrigin[0], _hudOrigin[1], 0 ) ); 592 592 … … 598 598 ( const osg::Matrix & mvpwView, 599 599 const osg::Matrix & mvpwShadow, 600 const osg::Vec3d & vWorld, 600 const osg::Vec3d & vWorld, 601 601 const osg::Vec3d & vDelta ) 602 602 { … … 609 609 osg::Vec3d dV = vV1 - vV0; 610 610 osg::Vec3d dS = vS1 - vS0; 611 611 612 612 return osg::Vec3( dS[0] / dV[0], dS[1] / dV[1], dS[2] / dV[2] ); 613 613 } 614 614 615 615 void DebugShadowMap::ViewData::displayShadowTexelToPixelErrors 616 ( const osg::Camera* viewCamera, 617 const osg::Camera* shadowCamera, 616 ( const osg::Camera* viewCamera, 617 const osg::Camera* shadowCamera, 618 618 const ConvexPolyhedron* hull ) 619 619 { … … 628 628 shadowCamera->getViewport()->computeWindowMatrix(); 629 629 630 osg::BoundingBox bb = 630 osg::BoundingBox bb = 631 631 hull->computeBoundingBox( viewCamera->getViewMatrix() ); 632 632 … … 644 644 << "ne=(" << vne[0] << "," << vne[1] << "," << vne[2] << ") " 645 645 << "fe=(" << vfe[0] << "," << vfe[1] << "," << vfe[2] << ") " 646 << "me=(" << vme[0] << "," << vme[1] << "," << vme[2] << ") " 646 << "me=(" << vme[0] << "," << vme[1] << "," << vme[2] << ") " 647 647 << "\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" 648 648 << "\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"
