Show
Ignore:
Timestamp:
01/26/07 22:22:35 (7 years ago)
Author:
robert
Message:

Further work on building the rendering back end from the intial traversal of the
scene graph

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgshadow/osgshadow.cpp

    r6053 r6055  
    320320    osg::Vec4 _lightpos; 
    321321    osg::ref_ptr<osg::StateSet> _ss1; 
    322  
    323     ShadowCallback() 
     322    osg::ref_ptr<osg::StateSet> _mainShadowStateSet; 
     323    osg::ref_ptr<osg::StateSet> _shadowVolumeStateSet; 
     324    osg::ref_ptr<osg::StateSet> _shadowedSceneStateSet; 
     325 
     326    ShadowCallback(osgShadow::ShadowVolumeGeometry::DrawMode drawMode) 
    324327    { 
    325328        osg::Vec4 ambient(0.2,0.2,0.2,1.0); 
    326329        osg::Vec4 diffuse(0.8,0.8,0.8,1.0); 
    327330        osg::Vec4 zero_colour(0.0,0.0,0.0,1.0); 
     331        _lightpos.set(0.0,0.0,1.0,0.0); 
    328332     
    329333        // first group, render the depth buffer + ambient light contribution 
     
    342346            _ss1->setMode(GL_LIGHTING, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); 
    343347        } 
     348 
     349        { 
     350            _mainShadowStateSet = new osg::StateSet; 
     351 
     352            osg::Depth* depth = new osg::Depth; 
     353            depth->setWriteMask(false); 
     354            depth->setFunction(osg::Depth::LEQUAL); 
     355            _mainShadowStateSet->setAttribute(depth); 
     356            _mainShadowStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); 
     357        } 
     358 
     359        { 
     360            _shadowVolumeStateSet = new osg::StateSet; 
     361             
     362            osg::Depth* depth = new osg::Depth; 
     363            depth->setWriteMask(false); 
     364            depth->setFunction(osg::Depth::LEQUAL); 
     365            _shadowVolumeStateSet->setAttribute(depth); 
     366            _shadowVolumeStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); 
     367            _shadowVolumeStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); 
     368 
     369 
     370            if (drawMode == osgShadow::ShadowVolumeGeometry::STENCIL_TWO_SIDED) 
     371            { 
     372                osg::StencilTwoSided* stencil = new osg::StencilTwoSided; 
     373                stencil->setFunction(osg::StencilTwoSided::BACK, osg::StencilTwoSided::ALWAYS,0,~0u); 
     374                stencil->setOperation(osg::StencilTwoSided::BACK, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::DECR_WRAP); 
     375                stencil->setFunction(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::ALWAYS,0,~0u); 
     376                stencil->setOperation(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::INCR_WRAP); 
     377 
     378                osg::ColorMask* colourMask = new osg::ColorMask(false, false, false, false); 
     379 
     380                _shadowVolumeStateSet->setAttributeAndModes(stencil,osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); 
     381                _shadowVolumeStateSet->setAttribute(colourMask, osg::StateAttribute::OVERRIDE); 
     382                _shadowVolumeStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); 
     383 
     384 
     385            } 
     386            else 
     387            { 
     388                osg::Stencil* stencil = new osg::Stencil; 
     389                stencil->setFunction(osg::Stencil::ALWAYS,0,~0u); 
     390                stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP); 
     391 
     392                osg::ColorMask* colourMask = new osg::ColorMask(false, false, false, false); 
     393 
     394                _shadowVolumeStateSet->setAttributeAndModes(stencil,osg::StateAttribute::ON); 
     395                _shadowVolumeStateSet->setAttribute(colourMask); 
     396                _shadowVolumeStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::ON); 
     397            } 
     398        } 
     399 
     400 
     401        { 
     402            _shadowedSceneStateSet = new osg::StateSet; 
     403 
     404            osg::Depth* depth = new osg::Depth; 
     405            depth->setWriteMask(false); 
     406            depth->setFunction(osg::Depth::LEQUAL); 
     407            _shadowedSceneStateSet->setAttribute(depth); 
     408            _shadowedSceneStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); 
     409            _shadowedSceneStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); 
     410 
     411 
     412            osg::LightModel* lm1 = new osg::LightModel; 
     413            lm1->setAmbientIntensity(zero_colour); 
     414            _shadowedSceneStateSet->setAttribute(lm1); 
     415 
     416            osg::LightSource* lightsource = new osg::LightSource; 
     417//            lightsource->setLight(light.get()); 
     418 
     419            osg::Light* light = new osg::Light; 
     420            light->setAmbient(zero_colour); 
     421            light->setDiffuse(diffuse); 
     422            light->setPosition(_lightpos); 
     423 
     424            _shadowedSceneStateSet->setMode(GL_LIGHT0, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); 
     425            _shadowedSceneStateSet->setAttribute(light); 
     426 
     427            // set up the stencil ops so that only operator on this mirrors stencil value. 
     428            osg::Stencil* stencil = new osg::Stencil; 
     429            stencil->setFunction(osg::Stencil::EQUAL,0,~0u); 
     430            stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP); 
     431            _shadowedSceneStateSet->setAttributeAndModes(stencil,osg::StateAttribute::ON); 
     432 
     433            osg::BlendFunc* blend = new osg::BlendFunc; 
     434            blend->setFunction(osg::BlendFunc::ONE, osg::BlendFunc::ONE); 
     435            _shadowedSceneStateSet->setAttributeAndModes(blend, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); 
     436            _shadowedSceneStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); 
     437        } 
     438 
     439        _ss1->setThreadSafeRefUnref(true); 
     440        _mainShadowStateSet->setThreadSafeRefUnref(true); 
     441        _shadowVolumeStateSet->setThreadSafeRefUnref(true); 
     442        _shadowedSceneStateSet->setThreadSafeRefUnref(true); 
     443 
    344444    } 
    345445     
    346446    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) 
    347447    {  
    348         osg::notify(osg::NOTICE)<<"We're in callback"<<std::endl; 
    349          
    350448        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv); 
    351449        if (!cv)  
     
    354452            return; 
    355453        } 
     454 
     455//        osg::notify(osg::NOTICE)<<std::endl<<std::endl<<"Cull callback"<<std::endl; 
     456 
    356457         
    357458        osg::ref_ptr<osgUtil::RenderBin> original_bin = cv->getCurrentRenderBin(); 
     
    365466        cv->setCurrentRenderBin(original_bin.get()); 
    366467 
     468#if 0 
    367469        osg::notify(osg::NOTICE)<<"new_bin->getStateGraphList().size()= "<<new_bin->getStateGraphList().size()<<std::endl; 
    368470        osg::notify(osg::NOTICE)<<"new_bin->getRenderBinList().size()= "<<new_bin->getRenderBinList().size()<<std::endl; 
     
    376478            osg::notify(osg::NOTICE)<<"bin num = "<<itr->first<<std::endl; 
    377479        } 
    378          
     480#endif         
    379481         
    380482        osgUtil::RenderBin::RenderBinList::iterator itr =  new_bin->getRenderBinList().find(1000); 
     
    386488            if (shadowVolumeBin.valid()) 
    387489            { 
    388                 osg::notify(osg::NOTICE)<<"Found shadow volume bin, now removing it"<<std::endl; 
     490                // osg::notify(osg::NOTICE)<<"Found shadow volume bin, now removing it"<<std::endl; 
    389491                new_bin->getRenderBinList().erase(itr); 
    390492            } 
    391493        } 
    392494         
     495#if 0 
    393496        for(osgUtil::RenderBin::RenderBinList::iterator itr = new_bin->getRenderBinList().begin(); 
    394497            itr != new_bin->getRenderBinList().end(); 
     
    401504        osg::notify(osg::NOTICE)<<"after new_bin->getRenderBinList().size()= "<<new_bin->getRenderBinList().size()<<std::endl; 
    402505        osg::notify(osg::NOTICE)<<"after new_bin->getRenderLeafList().size()= "<<new_bin->getRenderLeafList().size()<<std::endl; 
     506#endif 
    403507 
    404508 
     
    412516        new_rs->setClearColor(orig_rs->getClearColor()); 
    413517        new_rs->setClearMask(GL_STENCIL_BUFFER_BIT); 
    414          
     518        new_rs->setDrawBuffer(orig_rs->getDrawBuffer()); 
     519        new_rs->setReadBuffer(orig_rs->getReadBuffer()); 
     520        new_rs->setColorMask(orig_rs->getColorMask()); 
     521        new_rs->setPositionalStateContainer(orig_rs->getPositionalStateContainer()); 
     522#if 1 
     523 
     524#if 0         
     525        osg::notify(osg::NOTICE)<<"orig_rs="<<orig_rs<<std::endl; 
     526        osg::notify(osg::NOTICE)<<"new_rs="<<new_rs<<std::endl; 
     527#endif         
    415528        if (shadowVolumeBin.valid()) 
    416529        { 
     530            // new_rs->setStateSet(_mainShadowStateSet.get()); 
    417531            new_rs->getRenderBinList()[0] = shadowVolumeBin; 
    418             new_rs->getRenderBinList()[1] = new_bin; 
    419         } 
    420  
     532            shadowVolumeBin->setStateSet(_shadowVolumeStateSet.get()); 
     533             
     534            osg::ref_ptr<osgUtil::RenderBin> nested_bin = new_rs->find_or_insert(1,"RenderBin"); 
     535            nested_bin->getRenderBinList()[0] = new_bin; 
     536             
     537            nested_bin->setStateSet(_shadowedSceneStateSet.get()); 
     538             
     539#if 0 
     540            osg::notify(osg::NOTICE)<<"shadowVolumeBin="<<shadowVolumeBin.get()<<std::endl; 
     541            osg::notify(osg::NOTICE)<<"nested_bin="<<nested_bin.get()<<std::endl; 
     542#endif 
     543        } 
     544#endif 
    421545 
    422546    } 
     
    614738        int shadowVolumeBin = 1000; 
    615739     
    616         group->setCullCallback(new ShadowCallback()); 
     740        group->setCullCallback(new ShadowCallback(drawMode)); 
    617741 
    618742        group->addChild(model.get()); 
     
    630754                osg::notify(osg::NOTICE)<<"STENCIL_TWO_SIDED seleteced"<<std::endl; 
    631755 
    632                 osg::StencilTwoSided* stencil = new osg::StencilTwoSided; 
    633                 stencil->setFunction(osg::StencilTwoSided::BACK, osg::StencilTwoSided::ALWAYS,0,~0u); 
    634                 stencil->setOperation(osg::StencilTwoSided::BACK, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::DECR_WRAP); 
    635                 stencil->setFunction(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::ALWAYS,0,~0u); 
    636                 stencil->setOperation(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::INCR_WRAP); 
    637  
    638  
    639                 osg::ColorMask* colourMask = new osg::ColorMask(false, false, false, false); 
    640  
    641756                osg::StateSet* ss_sv1 = geode->getOrCreateStateSet(); 
    642757                ss_sv1->setRenderBinDetails(shadowVolumeBin, "RenderBin"); 
    643                 ss_sv1->setAttributeAndModes(stencil,osg::StateAttribute::ON); 
    644                 ss_sv1->setAttribute(colourMask); 
    645                 ss_sv1->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); 
    646  
    647  
     758                geode->addDrawable(shadowVolume.get()); 
    648759            } 
    649760            else 
    650761            { 
    651762                osg::notify(osg::NOTICE)<<"STENCIL_TWO_PASSES seleteced"<<std::endl; 
    652  
    653                 osg::Stencil* stencil = new osg::Stencil; 
    654                 stencil->setFunction(osg::Stencil::ALWAYS,0,~0u); 
    655                 stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP); 
    656  
    657                 osg::ColorMask* colourMask = new osg::ColorMask(false, false, false, false); 
    658763 
    659764                osg::StateSet* ss_sv1 = geode->getOrCreateStateSet(); 
    660765                ss_sv1->setRenderBinDetails(shadowVolumeBin, "RenderBin"); 
    661                 ss_sv1->setAttributeAndModes(stencil,osg::StateAttribute::ON); 
    662                 ss_sv1->setAttribute(colourMask); 
    663                 ss_sv1->setMode(GL_CULL_FACE,osg::StateAttribute::ON); 
    664  
    665766                geode->addDrawable(shadowVolume.get()); 
    666767            }