Show
Ignore:
Timestamp:
10/21/14 17:10:27 (34 hours ago)
Author:
robert
Message:

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgVolume/MultipassTechnique.cpp

    r13948 r13949  
    4949} 
    5050 
     51osg::StateSet* MultipassTechnique::createStateSet(osg::StateSet* statesetPrototype, osg::Program* programPrototype, osg::Shader* shaderToAdd1, osg::Shader* shaderToAdd2) 
     52{ 
     53    osg::ref_ptr<osg::StateSet> stateset = osg::clone(statesetPrototype, osg::CopyOp::SHALLOW_COPY); 
     54    osg::ref_ptr<osg::Program> program = osg::clone(programPrototype, osg::CopyOp::SHALLOW_COPY); 
     55    stateset->setAttribute(program.get()); 
     56    if (shaderToAdd1) program->addShader(shaderToAdd1); 
     57    if (shaderToAdd2) program->addShader(shaderToAdd2); 
     58 
     59    return stateset.release(); 
     60} 
     61 
    5162void MultipassTechnique::init() 
    5263{ 
     
    7384    OSG_NOTICE<<"MultipassTechnique::init() Need to set up"<<std::endl; 
    7485 
    75     CollectPropertiesVisitor cpv; 
     86    CollectPropertiesVisitor cpv(false); 
    7687    if (_volumeTile->getLayer()->getProperty()) 
    7788    { 
     
    143154 
    144155    _transform = new osg::MatrixTransform; 
     156    _transform->addChild(geode.get()); 
    145157 
    146158    // handle locators 
     
    216228        } 
    217229 
    218 #if 1 
    219230        osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen; 
    220231        texgen->setMode(osg::TexGen::OBJECT_LINEAR); 
     
    232243 
    233244        stateset->setTextureAttributeAndModes(texgenTextureUnit, texgen.get(), osg::StateAttribute::ON); 
    234 #endif 
    235245    } 
    236246 
     
    318328    } 
    319329 
     330    // creates CullFace attributes to apply to front/back StateSet configurations. 
     331    osg::ref_ptr<osg::CullFace> front_CullFace = new osg::CullFace(osg::CullFace::BACK); 
     332    osg::ref_ptr<osg::CullFace> back_CullFace = new osg::CullFace(osg::CullFace::FRONT); 
     333 
     334 
    320335 
    321336    osg::ref_ptr<osg::Shader> computeRayColorShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_compute_ray_color.frag"); 
     
    328343#endif 
    329344 
    330     // set up the renderin of the front faces 
    331     { 
    332         osg::ref_ptr<osg::Group> front_face_group = new osg::Group; 
    333         front_face_group->addChild(geode.get()); 
    334         _transform->addChild(front_face_group.get()); 
    335  
    336         osg::ref_ptr<osg::StateSet> front_face_stateset = front_face_group->getOrCreateStateSet(); 
    337         front_face_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON); 
    338  
    339         osg::ref_ptr<osg::Program> program = new osg::Program; 
    340         front_face_stateset->setAttribute(program); 
    341  
    342         // get vertex shaders from source 
    343         osg::ref_ptr<osg::Shader> vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_multipass_front.vert"); 
    344         if (vertexShader.valid()) 
    345         { 
    346             program->addShader(vertexShader.get()); 
    347         } 
     345    osg::ref_ptr<osg::Shader> main_vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_multipass.vert"); 
    348346#if 0 
    349         else 
    350         { 
    351             #include "Shaders/volume_color_depth_vert.cpp" 
    352             program->addShader(new osg::Shader(osg::Shader::VERTEX, volume_color_depth_vert)); 
    353         } 
     347    if (!main_vertexShader) 
     348    { 
     349        #include "Shaders/volume_multipass_vert.cpp" 
     350        main_vertexShader = new osg::Shader(osg::Shader::VERTEX, volume_multipass_vert)); 
     351    } 
    354352#endif 
    355         // get fragment shaders from source 
    356         osg::ref_ptr<osg::Shader> fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_front.frag"); 
    357         if (fragmentShader.valid()) 
    358         { 
    359             program->addShader(fragmentShader.get()); 
    360         } 
     353 
     354    osg::ref_ptr<osg::Shader> front_main_fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_front.frag"); 
    361355#if 0 
    362         else 
    363         { 
    364             #include "Shaders/volume_color_depth_frag.cpp" 
    365             program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_color_depth_frag)); 
    366         } 
     356    if (!front_main_fragmentShader) 
     357    { 
     358        #include "Shaders/volume_multipass_front_frag.cpp" 
     359        front_main_fragmentShader = new osg::Shader(osg::Shader::VERTEX, volume_multipass_front_frag)); 
     360    } 
    367361#endif 
    368362 
    369         if (computeRayColorShader.valid()) 
    370         { 
    371             program->addShader(computeRayColorShader.get()); 
    372         } 
    373     } 
    374  
    375  
    376     // set up the rendering of the back faces 
    377     { 
    378         osg::ref_ptr<osg::Group> back_face_group = new osg::Group; 
    379         back_face_group->addChild(geode.get()); 
    380         _transform->addChild(back_face_group.get()); 
    381  
    382         osg::ref_ptr<osg::StateSet> back_face_stateset = back_face_group->getOrCreateStateSet(); 
    383         back_face_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::FRONT), osg::StateAttribute::ON); 
    384  
    385         osg::ref_ptr<osg::Program> program = new osg::Program; 
    386         back_face_stateset->setAttribute(program); 
    387  
    388         // get vertex shaders from source 
    389         osg::ref_ptr<osg::Shader> vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_multipass_back.vert"); 
    390         if (vertexShader.valid()) 
    391         { 
    392             program->addShader(vertexShader.get()); 
    393         } 
     363 
     364    osg::ref_ptr<osg::Shader> back_main_fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_back.frag"); 
    394365#if 0 
    395         else 
    396         { 
    397             #include "Shaders/volume_color_depth_vert.cpp" 
    398             program->addShader(new osg::Shader(osg::Shader::VERTEX, volume_color_depth_vert)); 
    399         } 
     366    if (!back_main_fragmentShader) 
     367    { 
     368        #include "Shaders/volume_multipass_back_frag.cpp" 
     369        back_main_fragmentShader = new osg::Shader(osg::Shader::VERTEX, volume_multipass_back_frag)); 
     370    } 
    400371#endif 
    401         // get fragment shaders from source 
    402         osg::ref_ptr<osg::Shader> fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_back.frag"); 
    403         if (fragmentShader.valid()) 
    404         { 
    405             program->addShader(fragmentShader.get()); 
    406         } 
    407 #if 0 
    408         else 
    409         { 
    410             #include "Shaders/volume_color_depth_frag.cpp" 
    411             program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_color_depth_frag)); 
    412         } 
    413 #endif 
    414         if (computeRayColorShader.valid()) 
    415         { 
    416             program->addShader(computeRayColorShader.get()); 
    417         } 
    418  
     372 
     373    // clear any previous settings 
     374    _stateSetMap.clear(); 
     375 
     376    osg::ref_ptr<osg::StateSet> front_stateset_prototype = new osg::StateSet; 
     377    osg::ref_ptr<osg::Program> front_program_prototype = new osg::Program; 
     378    { 
     379        front_stateset_prototype->setAttributeAndModes(front_CullFace.get(), osg::StateAttribute::ON); 
     380 
     381        front_program_prototype->addShader(main_vertexShader.get()); 
     382        front_program_prototype->addShader(front_main_fragmentShader.get()); 
     383        front_program_prototype->addShader(computeRayColorShader.get()); 
     384    } 
     385 
     386    osg::ref_ptr<osg::StateSet> back_stateset_prototype = new osg::StateSet; 
     387    osg::ref_ptr<osg::Program> back_program_prototype = new osg::Program; 
     388    { 
     389        back_stateset_prototype->setAttributeAndModes(back_CullFace.get(), osg::StateAttribute::ON); 
     390 
     391        back_program_prototype->addShader(main_vertexShader.get()); 
     392        back_program_prototype->addShader(back_main_fragmentShader.get()); 
     393        back_program_prototype->addShader(computeRayColorShader.get()); 
     394    } 
     395 
     396    // STANDARD_SHADERS 
     397    { 
     398        // STANDARD_SHADERS without TransferFunction 
     399        { 
     400            osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_standard.frag"); 
     401            #if 0 
     402            if (!accumulateSamplesShader) 
     403            { 
     404                #include "Shaders/volume_accumulateSamples_standard_frag.cpp"; 
     405                accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_frag); 
     406            } 
     407            #endif 
     408 
     409            // front 
     410            _stateSetMap[STANDARD_SHADERS|FRONT_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get()); 
     411 
     412            // back 
     413            _stateSetMap[STANDARD_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); 
     414        } 
     415 
     416        // STANDARD_SHADERS with TransferFunction 
     417        if (tf) 
     418        { 
     419            osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_standard_tf.frag"); 
     420            #if 0 
     421            if (!accumulateSamplesShader) 
     422            { 
     423                #include "Shaders/volume_accumulateSamples_standard_tf_frag.cpp"; 
     424                accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_tf_frag); 
     425            } 
     426            #endif 
     427 
     428 
     429            // front 
     430            _stateSetMap[STANDARD_SHADERS|FRONT_SHADERS|TF_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get()); 
     431 
     432            // back 
     433            _stateSetMap[STANDARD_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); 
     434        } 
     435    } 
     436 
     437    // ISO_SHADERS 
     438    if (cpv._isoProperty.valid()) 
     439    { 
     440        // ISO_SHADERS without TransferFunction 
     441        { 
     442            osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_iso.frag"); 
     443            #if 0 
     444            if (!accumulateSamplesShader) 
     445            { 
     446                #include "Shaders/volume_accumulateSamples_iso_frag.cpp"; 
     447                accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_iso_frag); 
     448            } 
     449            #endif 
     450 
     451            // front 
     452            _stateSetMap[ISO_SHADERS|FRONT_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get()); 
     453 
     454            // back 
     455            _stateSetMap[ISO_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); 
     456        } 
     457 
     458        // ISO_SHADERS with TransferFunction 
     459        if (tf) 
     460        { 
     461            osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_iso_tf.frag"); 
     462            #if 0 
     463            if (!accumulateSamplesShader) 
     464            { 
     465                #include "Shaders/volume_accumulateSamples_standard_iso_tf_frag.cpp"; 
     466                accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_iso_tf_frag); 
     467            } 
     468            #endif 
     469 
     470 
     471            // front 
     472            _stateSetMap[ISO_SHADERS|FRONT_SHADERS|TF_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get()); 
     473 
     474            // back 
     475            _stateSetMap[ISO_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); 
     476        } 
     477    } 
     478 
     479    // MIP_SHADERS 
     480    if (cpv._mipProperty.valid()) 
     481    { 
     482        // MIP_SHADERS without TransferFunction 
     483        { 
     484            osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_mip.frag"); 
     485            #if 0 
     486            if (!accumulateSamplesShader) 
     487            { 
     488                #include "Shaders/volume_accumulateSamples_mip_frag.cpp"; 
     489                accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_mip_frag); 
     490            } 
     491            #endif 
     492 
     493            // front 
     494            _stateSetMap[MIP_SHADERS|FRONT_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get()); 
     495 
     496            // back 
     497            _stateSetMap[MIP_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); 
     498        } 
     499 
     500        // MIP_SHADERS with TransferFunction 
     501        if (tf) 
     502        { 
     503            osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_mip_tf.frag"); 
     504            #if 0 
     505            if (!accumulateSamplesShader) 
     506            { 
     507                #include "Shaders/volume_accumulateSamples_standard_mip_tf_frag.cpp"; 
     508                accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_mip_tf_frag); 
     509            } 
     510            #endif 
     511 
     512 
     513            // front 
     514            _stateSetMap[MIP_SHADERS|FRONT_SHADERS|TF_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get()); 
     515 
     516            // back 
     517            _stateSetMap[MIP_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); 
     518        } 
     519    } 
     520 
     521    // LIT_SHADERS 
     522    if (cpv._lightingProperty.valid()) 
     523    { 
     524        // LIT_SHADERS without TransferFunction 
     525        { 
     526            osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_lit.frag"); 
     527            #if 0 
     528            if (!accumulateSamplesShader) 
     529            { 
     530                #include "Shaders/volume_accumulateSamples_lit_frag.cpp"; 
     531                accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_lit_frag); 
     532            } 
     533            #endif 
     534 
     535            // front 
     536            _stateSetMap[LIT_SHADERS|FRONT_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get()); 
     537 
     538            // back 
     539            _stateSetMap[LIT_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); 
     540        } 
     541 
     542        // MIP_SHADERS with TransferFunction 
     543        if (tf) 
     544        { 
     545            osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_lit_tf.frag"); 
     546            #if 0 
     547            if (!accumulateSamplesShader) 
     548            { 
     549                #include "Shaders/volume_accumulateSamples_standard_lit_tf_frag.cpp"; 
     550                accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_lit_tf_frag); 
     551            } 
     552            #endif 
     553 
     554 
     555            // front 
     556            _stateSetMap[LIT_SHADERS|FRONT_SHADERS|TF_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get()); 
     557 
     558            // back 
     559            _stateSetMap[LIT_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get()); 
     560        } 
    419561    } 
    420562 
     
    442584    if (postTraversal) 
    443585    { 
    444         if (_whenMovingStateSet.valid() && isMoving(cv)) 
    445         { 
    446             OSG_NOTICE<<"Using MovingStateSet"<<std::endl; 
    447             cv->pushStateSet(_whenMovingStateSet.get()); 
     586 
     587        int shaderMask = 0; 
     588        if (_volumeTile->getLayer()->getProperty()) 
     589        { 
     590            CollectPropertiesVisitor cpv; 
     591            _volumeTile->getLayer()->getProperty()->accept(cpv); 
     592 
     593            if (cpv._tfProperty.valid()) 
     594            { 
     595                shaderMask |= TF_SHADERS; 
     596            } 
     597 
     598            if (cpv._isoProperty.valid()) 
     599            { 
     600                shaderMask |= ISO_SHADERS; 
     601            } 
     602            else if (cpv._mipProperty.valid()) 
     603            { 
     604                shaderMask |= MIP_SHADERS; 
     605            } 
     606            else if (cpv._lightingProperty.valid()) 
     607            { 
     608                shaderMask |= LIT_SHADERS; 
     609            } 
     610            else 
     611            { 
     612                shaderMask |= STANDARD_SHADERS; 
     613            } 
     614        } 
     615 
     616        int shaderMaskFront = shaderMask | FRONT_SHADERS; 
     617        int shaderMaskBack = shaderMask | BACK_SHADERS; 
     618 
     619        OSG_NOTICE<<"shaderMaskFront "<<shaderMaskFront<<std::endl; 
     620        OSG_NOTICE<<"shaderMaskBack  "<<shaderMaskBack<<std::endl; 
     621 
     622 
     623        osg::ref_ptr<osg::StateSet> front_stateset = _stateSetMap[shaderMaskFront]; 
     624        osg::ref_ptr<osg::StateSet> back_stateset = _stateSetMap[shaderMaskBack]; 
     625        osg::ref_ptr<osg::StateSet> moving_stateset = (_whenMovingStateSet.valid() && isMoving(cv)) ? _whenMovingStateSet : 0; 
     626 
     627        if (moving_stateset.valid()) 
     628        { 
     629            // OSG_NOTICE<<"Using MovingStateSet"<<std::endl; 
     630            cv->pushStateSet(moving_stateset.get()); 
     631        } 
     632 
     633        if (front_stateset.valid()) 
     634        { 
     635            OSG_NOTICE<<"Have front stateset"<<std::endl; 
     636            cv->pushStateSet(front_stateset.get()); 
    448637            _transform->accept(*cv); 
    449638            cv->popStateSet(); 
    450639        } 
    451         else 
    452         { 
    453             OSG_NOTICE<<"NOT using MovingStateSet"<<std::endl; 
     640 
     641        if (back_stateset.valid()) 
     642        { 
     643            OSG_NOTICE<<"Have back stateset"<<std::endl; 
     644            cv->pushStateSet(back_stateset.get()); 
    454645            _transform->accept(*cv); 
     646            cv->popStateSet(); 
     647        } 
     648 
     649        if (moving_stateset.valid()) 
     650        { 
     651            // OSG_NOTICE<<"Using MovingStateSet"<<std::endl; 
     652            cv->popStateSet(); 
    455653        } 
    456654    }