Show
Ignore:
Timestamp:
06/22/05 13:01:22 (10 years ago)
Author:
robert
Message:

Added experimental OpenGL shader path for positioning of trees (doens't work yet though..)

Files:
1 modified

Legend:

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

    r4175 r4350  
    102102 
    103103    osg::Geometry* createOrthogonalQuads( const osg::Vec3& pos, float w, float h, osg::UByte4 color ); 
     104    osg::Geometry* createOrthogonalQuadsNoColor( const osg::Vec3& pos, float w, float h ); 
    104105 
    105106    osg::Node* createBillboardGraph(Cell* cell,osg::StateSet* stateset); 
     
    108109 
    109110    osg::Node* createTransformGraph(Cell* cell,osg::StateSet* stateset); 
     111 
     112    osg::Node* createShaderGraph(Cell* cell,osg::StateSet* stateset); 
    110113     
    111114    osg::Node* createHUDWithText(const std::string& text); 
     
    713716} 
    714717 
     718osg::Geometry* ForestTechniqueManager::createOrthogonalQuadsNoColor( const osg::Vec3& pos, float w, float h) 
     719{ 
     720    // set up the coords 
     721    osg::Vec3Array& v = *(new osg::Vec3Array(8)); 
     722    osg::Vec2Array& t = *(new osg::Vec2Array(8)); 
     723     
     724    float rotation = random(0.0f,osg::PI/2.0f); 
     725    float sw = sinf(rotation)*w*0.5f; 
     726    float cw = cosf(rotation)*w*0.5f; 
     727 
     728    v[0].set(pos.x()-sw,pos.y()-cw,pos.z()+0.0f); 
     729    v[1].set(pos.x()+sw,pos.y()+cw,pos.z()+0.0f); 
     730    v[2].set(pos.x()+sw,pos.y()+cw,pos.z()+h); 
     731    v[3].set(pos.x()-sw,pos.y()-cw,pos.z()+h); 
     732 
     733    v[4].set(pos.x()-cw,pos.y()+sw,pos.z()+0.0f); 
     734    v[5].set(pos.x()+cw,pos.y()-sw,pos.z()+0.0f); 
     735    v[6].set(pos.x()+cw,pos.y()-sw,pos.z()+h); 
     736    v[7].set(pos.x()-cw,pos.y()+sw,pos.z()+h); 
     737 
     738    t[0].set(0.0f,0.0f); 
     739    t[1].set(1.0f,0.0f); 
     740    t[2].set(1.0f,1.0f); 
     741    t[3].set(0.0f,1.0f); 
     742 
     743    t[4].set(0.0f,0.0f); 
     744    t[5].set(1.0f,0.0f); 
     745    t[6].set(1.0f,1.0f); 
     746    t[7].set(0.0f,1.0f); 
     747 
     748    osg::Geometry *geom = new osg::Geometry; 
     749 
     750    geom->setVertexArray( &v ); 
     751 
     752    geom->setTexCoordArray( 0, &t ); 
     753 
     754    geom->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,8) ); 
     755 
     756    return geom; 
     757} 
     758 
     759class ShaderGeometry : public osg::Drawable 
     760{ 
     761    public: 
     762        ShaderGeometry() { setUseDisplayList(false); } 
     763 
     764        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ 
     765        ShaderGeometry(const ShaderGeometry& ShaderGeometry,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): 
     766            osg::Drawable(ShaderGeometry,copyop) {} 
     767 
     768        META_Object(osg,ShaderGeometry) 
     769 
     770        typedef std::vector<osg::Vec4> PositionSizeList; 
     771         
     772        virtual void drawImplementation(osg::State& state) const 
     773        { 
     774            for(PositionSizeList::const_iterator itr = _trees.begin(); 
     775                itr != _trees.end(); 
     776                ++itr) 
     777            { 
     778#if 0 
     779                glColor4fv(itr->ptr()); 
     780                _geometry->drawImplementation(state); 
     781#else 
     782                glPushMatrix(); 
     783                glTranslatef((*itr)[0], (*itr)[1], (*itr)[2]); 
     784                glScalef( (*itr)[3],(*itr)[3],(*itr)[3] ); 
     785                _geometry->drawImplementation(state); 
     786                glPopMatrix(); 
     787#endif 
     788            } 
     789        } 
     790 
     791        virtual osg::BoundingBox computeBound() const 
     792        { 
     793            osg::BoundingBox geom_box = _geometry->getBound(); 
     794            osg::BoundingBox bb; 
     795            for(PositionSizeList::const_iterator itr = _trees.begin(); 
     796                itr != _trees.end(); 
     797                ++itr) 
     798            { 
     799                bb.expandBy(geom_box.corner(0)*(*itr)[3] + 
     800                            osg::Vec3( (*itr)[0], (*itr)[1], (*itr)[2] )); 
     801                bb.expandBy(geom_box.corner(7)*(*itr)[3] + 
     802                            osg::Vec3( (*itr)[0], (*itr)[1], (*itr)[2] )); 
     803            } 
     804            return bb; 
     805        } 
     806         
     807        void setGeometry(osg::Geometry* geometry) 
     808        { 
     809            _geometry = geometry; 
     810        } 
     811         
     812        void addTree(ForestTechniqueManager::Tree& tree) 
     813        { 
     814            _trees.push_back(osg::Vec4(tree._position.x(), tree._position.y(), tree._position.z(), tree._height)); 
     815        } 
     816         
     817        osg::ref_ptr<osg::Geometry> _geometry; 
     818 
     819        PositionSizeList _trees; 
     820 
     821    protected: 
     822     
     823        virtual ~ShaderGeometry() {} 
     824         
     825}; 
     826 
     827osg::Geometry* shared_geometry = 0; 
     828 
     829osg::Node* ForestTechniqueManager::createShaderGraph(Cell* cell,osg::StateSet* stateset) 
     830{ 
     831    if (shared_geometry==0) 
     832    { 
     833        shared_geometry = createOrthogonalQuadsNoColor(osg::Vec3(0.0f,0.0f,0.0f),1.0f,1.0f); 
     834        //shared_geometry->setUseDisplayList(false); 
     835    } 
     836 
     837 
     838    bool needGroup = !(cell->_cells.empty()); 
     839    bool needTrees = !(cell->_trees.empty()); 
     840     
     841    osg::Geode* geode = 0; 
     842    osg::Group* group = 0; 
     843     
     844    if (needTrees) 
     845    { 
     846        geode = new osg::Geode; 
     847         
     848        ShaderGeometry* shader_geometry = new ShaderGeometry; 
     849        shader_geometry->setGeometry(shared_geometry); 
     850         
     851         
     852        for(TreeList::iterator itr=cell->_trees.begin(); 
     853            itr!=cell->_trees.end(); 
     854            ++itr) 
     855        { 
     856            Tree& tree = **itr; 
     857            shader_geometry->addTree(tree); 
     858 
     859        } 
     860 
     861        geode->setStateSet(stateset); 
     862        geode->addDrawable(shader_geometry); 
     863    } 
     864     
     865    if (needGroup) 
     866    { 
     867        group = new osg::Group; 
     868        for(Cell::CellList::iterator itr=cell->_cells.begin(); 
     869            itr!=cell->_cells.end(); 
     870            ++itr) 
     871        { 
     872            group->addChild(createShaderGraph(itr->get(),stateset)); 
     873        } 
     874         
     875        if (geode) group->addChild(geode); 
     876         
     877    } 
     878    if (group) return group; 
     879    else return geode; 
     880} 
     881 
    715882osg::Node* ForestTechniqueManager::createHUDWithText(const std::string& str) 
    716883{ 
     
    805972        osg::Group* group = new osg::Group; 
    806973        group->addChild(createBillboardGraph(cell.get(),dstate)); 
    807         group->addChild(createHUDWithText("Using osg::Billboard's to create a forest\n\nPress left cursor key to select osg::MatrixTransform based forest\nPress right cursor key to select double quad based forest")); 
     974        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")); 
    808975        _techniqueSwitch->addChild(group); 
    809976        std::cout<<"done."<<std::endl; 
     
    823990        osg::Group* group = new osg::Group; 
    824991        group->addChild(createTransformGraph(cell.get(),dstate)); 
    825         group->addChild(createHUDWithText("Using osg::MatrixTransform's to create a forest\n\nPress left cursor key to select double quad based forest\nPress right cursor key to select osg::Billboard based forest")); 
     992        group->addChild(createHUDWithText("Using osg::MatrixTransform's to create a forest\n\nPress left cursor key to select double quad based forest\nPress right cursor key to select OpenGL shder based forest")); 
    826993        _techniqueSwitch->addChild(group); 
    827994        std::cout<<"done."<<std::endl; 
    828995    } 
    829996     
     997    { 
     998        osg::Group* group = new osg::Group; 
     999         
     1000 
     1001        osg::StateSet* stateset = new osg::StateSet; 
     1002 
     1003        stateset->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON ); 
     1004        stateset->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); 
     1005 
     1006        { 
     1007            /////////////////////////////////////////////////////////////////// 
     1008            // vertex shader using just Vec4 coefficients 
     1009            char vertexShaderSource[] =  
     1010                "void main(void) \n" 
     1011                "{ \n" 
     1012                "\n" 
     1013                "    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" 
     1014                "}\n"; 
     1015 
     1016            ////////////////////////////////////////////////////////////////// 
     1017            // fragment shader 
     1018            // 
     1019            char fragmentShaderSource[] =  
     1020                "uniform sampler2D baseTexture; \n" 
     1021                "\n" 
     1022                "void main(void) \n" 
     1023                "{ \n" 
     1024                "    gl_FragColor = texture2D( baseTexture, gl_TexCoord[0].xy); \n" 
     1025                "}\n"; 
     1026 
     1027 
     1028            osg::Program* program = new osg::Program; 
     1029            stateset->setAttribute(program); 
     1030 
     1031            osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource); 
     1032            program->addShader(vertex_shader); 
     1033 
     1034            osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource); 
     1035            program->addShader(fragment_shader); 
     1036 
     1037            osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0); 
     1038            stateset->addUniform(baseTextureSampler); 
     1039        } 
     1040 
     1041        std::cout<<"Creating billboard based forest..."; 
     1042        group->addChild(createShaderGraph(cell.get(),stateset)); 
     1043        group->addChild(createHUDWithText("Using OpenGL Shader to create a forest\n\nPress left cursor key to select osg::MatrixTransform based forest\nPress right cursor key to select osg::Billboard based forest")); 
     1044        _techniqueSwitch->addChild(group); 
     1045        std::cout<<"done."<<std::endl; 
     1046    } 
     1047 
    8301048    _currentTechnique = 0; 
    8311049    _techniqueSwitch->setSingleChildOn(_currentTechnique);