Changeset 12886

Show
Ignore:
Timestamp:
11/18/11 09:20:04 (19 months ago)
Author:
robert
Message:

From Trajce Nikolov, "Here is extended version of the osgforest example - technique with geometry shader added, was doing it for a project so I thought might be useful to update the example as well
"

Files:
1 modified

Legend:

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

    r12885 r12886  
    141141    osg::Node* createShaderGraph(Cell* cell,osg::StateSet* stateset); 
    142142 
     143    osg::Node* createGeometryShaderGraph(Cell* cell, osg::StateSet* stateset); 
     144    void CollectTreePositions(Cell* cell, std::vector< osg::Vec3 >& positions); 
     145 
    143146    osg::Node* createHUDWithText(const std::string& text); 
    144147 
     
    202205            } 
    203206            else if (ea.getKey()=='p' || 
    204                     ea.getKey()==osgGA::GUIEventAdapter::KEY_Left || 
    205                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left) 
     207                     ea.getKey()==osgGA::GUIEventAdapter::KEY_Left || 
     208                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left) 
    206209            { 
    207210                _ForestTechniqueManager->advanceToNextTechnique(-1); 
     
    261264        } 
    262265        return true; 
    263     } 
    264     else 
    265     { 
    266             return false; 
    267     } 
     266   } 
     267   else 
     268   { 
     269        return false; 
     270   } 
    268271} 
    269272 
     
    846849osg::Geometry* shared_geometry = 0; 
    847850 
     851osg::Program* createGeometryShader() 
     852{ 
     853    static const char* vertSource = { 
     854    "#version 120\n" 
     855    "#extension GL_EXT_geometry_shader4 : enable\n" 
     856    "varying vec2 texcoord;\n" 
     857    "void main(void)\n" 
     858    "{\n" 
     859    "    gl_Position = gl_Vertex;\n" 
     860    "    texcoord = gl_MultiTexCoord0.st;\n" 
     861    "}\n" 
     862    }; 
     863 
     864    static const char* geomSource = { 
     865    "#version 120\n" 
     866    "#extension GL_EXT_geometry_shader4 : enable\n" 
     867    "varying vec2 texcoord;\n" 
     868    "varying float intensity; \n" 
     869    "varying float red_intensity; \n" 
     870    "void main(void)\n" 
     871    "{\n" 
     872    "    vec4 v = gl_PositionIn[0];\n" 
     873    "    vec4 info = gl_PositionIn[1];\n" 
     874    "    intensity = info.y;\n" 
     875    "    red_intensity = info.z;\n" 
     876    "\n" 
     877    "    float h = info.x;\n" 
     878    "    float w = h*0.35;\n" 
     879    "    vec4 e;\n" 
     880    "    e = v + vec4(-w,0.0,0.0,0.0);  gl_Position = gl_ModelViewProjectionMatrix * e; texcoord = vec2(0.0,0.0); EmitVertex();\n" 
     881    "    e = v + vec4(w,0.0,0.0,0.0);  gl_Position = gl_ModelViewProjectionMatrix * e;  texcoord = vec2(1.0,0.0); EmitVertex();\n" 
     882    "    e = v + vec4(-w,0.0,h,0.0);  gl_Position = gl_ModelViewProjectionMatrix * e;  texcoord = vec2(0.0,1.0); EmitVertex();\n" 
     883    "    e = v + vec4(w,0.0,h,0.0);  gl_Position = gl_ModelViewProjectionMatrix * e;  texcoord = vec2(1.0,1.0); EmitVertex();\n" 
     884    "    EndPrimitive();\n" 
     885    "    e = v + vec4(0.0,-w,0.0,0.0);  gl_Position = gl_ModelViewProjectionMatrix * e; texcoord = vec2(0.0,0.0); EmitVertex();\n" 
     886    "    e = v + vec4(0.0,w,0.0,0.0);  gl_Position = gl_ModelViewProjectionMatrix * e;  texcoord = vec2(1.0,0.0); EmitVertex();\n" 
     887    "    e = v + vec4(0.0,-w,h,0.0);  gl_Position = gl_ModelViewProjectionMatrix * e;  texcoord = vec2(0.0,1.0); EmitVertex();\n" 
     888    "    e = v + vec4(0.0,w,h,0.0);  gl_Position = gl_ModelViewProjectionMatrix * e;  texcoord = vec2(1.0,1.0); EmitVertex();\n" 
     889    "    EndPrimitive();\n" 
     890    "}\n" 
     891    }; 
     892 
     893 
     894    static const char* fragSource = { 
     895        "uniform sampler2D baseTexture; \n" 
     896        "varying vec2 texcoord; \n" 
     897        "varying float intensity; \n" 
     898        "varying float red_intensity; \n" 
     899        "\n" 
     900        "void main(void) \n" 
     901        "{ \n" 
     902        "   vec4 finalColor = texture2D( baseTexture, texcoord); \n" 
     903        "   vec4 color = finalColor * intensity;\n" 
     904        "   color.w = finalColor.w;\n" 
     905        "   color.x *= red_intensity;\n" 
     906        "   gl_FragColor = color;\n" 
     907        "}\n" 
     908    }; 
     909 
     910 
     911    osg::Program* pgm = new osg::Program; 
     912    pgm->setName( "osgshader2 demo" ); 
     913 
     914    pgm->addShader( new osg::Shader( osg::Shader::VERTEX,   vertSource ) ); 
     915    pgm->addShader( new osg::Shader( osg::Shader::FRAGMENT, fragSource ) ); 
     916 
     917    pgm->addShader( new osg::Shader( osg::Shader::GEOMETRY, geomSource ) ); 
     918    pgm->setParameter( GL_GEOMETRY_VERTICES_OUT_EXT, 8 ); 
     919    pgm->setParameter( GL_GEOMETRY_INPUT_TYPE_EXT, GL_LINES ); 
     920    pgm->setParameter( GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP); 
     921 
     922    return pgm; 
     923} 
     924 
     925void ForestTechniqueManager::CollectTreePositions(Cell* cell, std::vector< osg::Vec3 >& positions) 
     926{ 
     927    bool needGroup = !(cell->_cells.empty()); 
     928    bool needTrees = !(cell->_trees.empty()); 
     929 
     930    if (needTrees) 
     931    { 
     932        for(TreeList::iterator itr=cell->_trees.begin(); 
     933            itr!=cell->_trees.end(); 
     934            ++itr) 
     935        { 
     936            Tree& tree = **itr; 
     937            positions.push_back(tree._position); 
     938        } 
     939    } 
     940 
     941    if (needGroup) 
     942    { 
     943        for(Cell::CellList::iterator itr=cell->_cells.begin(); 
     944            itr!=cell->_cells.end(); 
     945            ++itr) 
     946        { 
     947            CollectTreePositions(itr->get(),positions); 
     948        } 
     949 
     950    } 
     951} 
     952 
     953osg::Node* ForestTechniqueManager::createGeometryShaderGraph(Cell* cell, osg::StateSet* dstate) 
     954{ 
     955    bool needGroup = !(cell->_cells.empty()); 
     956    bool needTrees = !(cell->_trees.empty()); 
     957 
     958    osg::Geode* geode = 0; 
     959    osg::Group* group = 0; 
     960 
     961    if (needTrees) 
     962    { 
     963        geode = new osg::Geode; 
     964        geode->setStateSet(dstate); 
     965 
     966        osg::Geometry* geometry = new osg::Geometry; 
     967        geode->addDrawable(geometry); 
     968 
     969        osg::Vec3Array* v = new osg::Vec3Array; 
     970 
     971        for(TreeList::iterator itr=cell->_trees.begin(); 
     972            itr!=cell->_trees.end(); 
     973            ++itr) 
     974        { 
     975            Tree& tree = **itr; 
     976            v->push_back(tree._position); 
     977            v->push_back(osg::Vec3(/*tree._height*/30.0,(double)random(0.75f,1.15f),(double)random(1.0f,1.250f))); 
     978        } 
     979        geometry->setVertexArray( v ); 
     980        geometry->addPrimitiveSet( new osg::DrawArrays( GL_LINES, 0, v->size() ) ); 
     981 
     982        osg::StateSet* sset = geode->getOrCreateStateSet(); 
     983        sset->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); 
     984        sset->setAttribute( createGeometryShader() ); 
     985 
     986        osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0); 
     987        sset->addUniform(baseTextureSampler); 
     988 
     989    } 
     990 
     991    if (needGroup) 
     992    { 
     993        group = new osg::Group; 
     994        for(Cell::CellList::iterator itr=cell->_cells.begin(); 
     995            itr!=cell->_cells.end(); 
     996            ++itr) 
     997        { 
     998            group->addChild(createGeometryShaderGraph(itr->get(),dstate)); 
     999        } 
     1000 
     1001        if (geode) group->addChild(geode); 
     1002 
     1003    } 
     1004    if (group) return group; 
     1005    else return geode; 
     1006} 
     1007 
     1008 
     1009 
    8481010osg::Node* ForestTechniqueManager::createShaderGraph(Cell* cell,osg::StateSet* stateset) 
    8491011{ 
     
    9921154        osg::Group* group = new osg::Group; 
    9931155        group->addChild(createBillboardGraph(cell.get(),dstate)); 
    994         group->addChild(createHUDWithText("Using osg::Billboard's to create a forest\n\nPress left cursor key to select OpenGL shader based forest\nPress right cursor key to select double quad based forest")); 
     1156        group->addChild(createHUDWithText("Using osg::Billboard's to create a forest\n\nPress left cursor key to select osg::Vertex/Geometry/FragmentProgram shader based forest\nPress right cursor key to select double quad based forest")); 
    9951157        _techniqueSwitch->addChild(group); 
    9961158        std::cout<<"done."<<std::endl; 
     
    11331295 
    11341296        group->addChild(createShaderGraph(cell.get(),stateset)); 
    1135         group->addChild(createHUDWithText("Using OpenGL Shader to create a forest\n\nPress left cursor key to select osg::Vertex/FragmentProgram based forest\nPress right cursor key to select osg::Billboard based forest")); 
     1297        group->addChild(createHUDWithText("Using OpenGL Shader to create a forest\n\nPress left cursor key to select osg::Vertex/FragmentProgram based forest\nPress right cursor key to select osg::Vertex/Geometry/FragmentProgram based forest")); 
    11361298        _techniqueSwitch->addChild(group); 
    11371299        std::cout<<"done."<<std::endl; 
    11381300    } 
    11391301 
     1302    { 
     1303        std::cout<<"Creating Geometry Shader based forest..."; 
     1304 
     1305        osg::StateSet* stateset = new osg::StateSet(*dstate, osg::CopyOp::DEEP_COPY_ALL); 
     1306 
     1307        osg::Group* group = new osg::Group; 
     1308        group->addChild(createGeometryShaderGraph(cell.get(), stateset)); 
     1309        group->addChild(createHUDWithText("Using osg::Vertex/Geometry/FragmentProgram to create a forest\n\nPress left cursor key to select OpenGL Shader based forest\nPress right cursor key to select osg::Billboard based forest")); 
     1310 
     1311        _techniqueSwitch->addChild(group); 
     1312        std::cout<<"done."<<std::endl; 
     1313    } 
     1314 
    11401315    _currentTechnique = 0; 
    11411316    _techniqueSwitch->setSingleChildOn(_currentTechnique);