| | 313 | |
| | 314 | |
| | 315 | |
| | 316 | class ShadowCallback : public osg::NodeCallback |
| | 317 | { |
| | 318 | public: |
| | 319 | ShadowCallback() {} |
| | 320 | |
| | 321 | virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) |
| | 322 | { |
| | 323 | osg::notify(osg::NOTICE)<<"We're in callback"<<std::endl; |
| | 324 | |
| | 325 | osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv); |
| | 326 | if (!cv) |
| | 327 | { |
| | 328 | traverse(node,nv); |
| | 329 | return; |
| | 330 | } |
| | 331 | |
| | 332 | osgUtil::RenderBin* original_bin = cv->getCurrentRenderBin(); |
| | 333 | |
| | 334 | osgUtil::RenderBin* new_bin = original_bin->find_or_insert(999,"RenderBin"); |
| | 335 | |
| | 336 | cv->setCurrentRenderBin(new_bin); |
| | 337 | |
| | 338 | traverse(node,nv); |
| | 339 | |
| | 340 | osg::notify(osg::NOTICE)<<"new_bin->getStateGraphList().size()= "<<new_bin->getStateGraphList().size()<<std::endl; |
| | 341 | osg::notify(osg::NOTICE)<<"new_bin->getRenderBinList().size()= "<<new_bin->getRenderBinList().size()<<std::endl; |
| | 342 | osg::notify(osg::NOTICE)<<"new_bin->getRenderLeafList().size()= "<<new_bin->getRenderLeafList().size()<<std::endl; |
| | 343 | |
| | 344 | for(osgUtil::RenderBin::RenderBinList::iterator itr = new_bin->getRenderBinList().begin(); |
| | 345 | itr != new_bin->getRenderBinList().end(); |
| | 346 | ++itr) |
| | 347 | { |
| | 348 | osg::notify(osg::NOTICE)<<"bin num = "<<itr->first<<std::endl; |
| | 349 | } |
| | 350 | |
| | 351 | cv->setCurrentRenderBin(original_bin); |
| | 352 | |
| | 353 | } |
| | 354 | }; |
| | 355 | |
| | 356 | |
| | 542 | else if (cullCallback) |
| | 543 | { |
| | 544 | |
| | 545 | int shadowVolumeBin = 1000; |
| | 546 | |
| | 547 | group->setCullCallback(new ShadowCallback()); |
| | 548 | |
| | 549 | group->addChild(model.get()); |
| | 550 | |
| | 551 | { |
| | 552 | osg::ref_ptr<osg::Geode> geode = new osg::Geode; |
| | 553 | group->addChild(geode.get()); |
| | 554 | |
| | 555 | occluder->computeShadowVolumeGeometry(lightpos, *shadowVolume); |
| | 556 | shadowVolume->setDrawMode(drawMode); |
| | 557 | |
| | 558 | |
| | 559 | if (drawMode == osgShadow::ShadowVolumeGeometry::STENCIL_TWO_SIDED) |
| | 560 | { |
| | 561 | osg::notify(osg::NOTICE)<<"STENCIL_TWO_SIDED seleteced"<<std::endl; |
| | 562 | |
| | 563 | osg::StencilTwoSided* stencil = new osg::StencilTwoSided; |
| | 564 | stencil->setFunction(osg::StencilTwoSided::BACK, osg::StencilTwoSided::ALWAYS,0,~0u); |
| | 565 | stencil->setOperation(osg::StencilTwoSided::BACK, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::DECR_WRAP); |
| | 566 | stencil->setFunction(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::ALWAYS,0,~0u); |
| | 567 | stencil->setOperation(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::INCR_WRAP); |
| | 568 | |
| | 569 | |
| | 570 | osg::ColorMask* colourMask = new osg::ColorMask(false, false, false, false); |
| | 571 | |
| | 572 | osg::StateSet* ss_sv1 = geode->getOrCreateStateSet(); |
| | 573 | ss_sv1->setRenderBinDetails(shadowVolumeBin, "RenderBin"); |
| | 574 | ss_sv1->setAttributeAndModes(stencil,osg::StateAttribute::ON); |
| | 575 | ss_sv1->setAttribute(colourMask); |
| | 576 | ss_sv1->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); |
| | 577 | |
| | 578 | |
| | 579 | } |
| | 580 | else |
| | 581 | { |
| | 582 | osg::notify(osg::NOTICE)<<"STENCIL_TWO_PASSES seleteced"<<std::endl; |
| | 583 | |
| | 584 | osg::Stencil* stencil = new osg::Stencil; |
| | 585 | stencil->setFunction(osg::Stencil::ALWAYS,0,~0u); |
| | 586 | stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP); |
| | 587 | |
| | 588 | osg::ColorMask* colourMask = new osg::ColorMask(false, false, false, false); |
| | 589 | |
| | 590 | osg::StateSet* ss_sv1 = geode->getOrCreateStateSet(); |
| | 591 | ss_sv1->setRenderBinDetails(shadowVolumeBin, "RenderBin"); |
| | 592 | ss_sv1->setAttributeAndModes(stencil,osg::StateAttribute::ON); |
| | 593 | ss_sv1->setAttribute(colourMask); |
| | 594 | ss_sv1->setMode(GL_CULL_FACE,osg::StateAttribute::ON); |
| | 595 | |
| | 596 | geode->addDrawable(shadowVolume.get()); |
| | 597 | } |
| | 598 | |
| | 599 | } |
| | 600 | |
| | 601 | } |