Changeset 12885 for OpenSceneGraph/trunk/examples/osgforest/osgforest.cpp
- Timestamp:
- 11/18/11 09:15:36 (19 months ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/examples/osgforest/osgforest.cpp
r10711 r12885 86 86 unsigned int _type; 87 87 }; 88 88 89 89 typedef std::vector< osg::ref_ptr<Tree> > TreeList; 90 90 91 91 class Cell : public osg::Referenced 92 92 { … … 96 96 Cell():_parent(0) {} 97 97 Cell(osg::BoundingBox& bb):_parent(0), _bb(bb) {} 98 98 99 99 void addCell(Cell* cell) { cell->_parent=this; _cells.push_back(cell); } 100 100 101 101 void addTree(Tree* tree) { _trees.push_back(tree); } 102 102 103 103 void addTrees(const TreeList& trees) { _trees.insert(_trees.end(),trees.begin(),trees.end()); } 104 104 105 105 void computeBound(); 106 106 107 107 bool contains(const osg::Vec3& position) const { return _bb.contains(position); } 108 108 109 109 bool divide(unsigned int maxNumTreesPerCell=10); 110 110 111 111 bool divide(bool xAxis, bool yAxis, bool zAxis); 112 112 113 113 void bin(); 114 114 … … 118 118 CellList _cells; 119 119 TreeList _trees; 120 120 121 121 }; 122 122 … … 140 140 141 141 osg::Node* createShaderGraph(Cell* cell,osg::StateSet* stateset); 142 142 143 143 osg::Node* createHUDWithText(const std::string& text); 144 144 145 145 osg::Node* createScene(unsigned int numTreesToCreates); 146 146 147 147 void advanceToNextTechnique(int delta=1) 148 148 { … … 157 157 } 158 158 } 159 159 160 160 osg::ref_ptr<osg::Switch> _techniqueSwitch; 161 161 int _currentTechnique; 162 162 163 163 164 164 }; … … 170 170 171 171 TechniqueEventHandler(ForestTechniqueManager* ttm=0) { _ForestTechniqueManager = ttm; } 172 172 173 173 META_Object(osgforestApp,TechniqueEventHandler); 174 174 175 175 virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&, osg::Object*, osg::NodeVisitor*); 176 176 177 177 virtual void getUsage(osg::ApplicationUsage& usage) const; 178 178 … … 180 180 181 181 ~TechniqueEventHandler() {} 182 182 183 183 TechniqueEventHandler(const TechniqueEventHandler&,const osg::CopyOp&) {} 184 184 185 185 osg::ref_ptr<ForestTechniqueManager> _ForestTechniqueManager; 186 186 187 187 188 188 }; 189 189 … … 195 195 { 196 196 if (ea.getKey()=='n' || 197 ea.getKey()==osgGA::GUIEventAdapter::KEY_Right || 197 ea.getKey()==osgGA::GUIEventAdapter::KEY_Right || 198 198 ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Right) 199 199 { … … 202 202 } 203 203 else if (ea.getKey()=='p' || 204 ea.getKey()==osgGA::GUIEventAdapter::KEY_Left ||205 ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left)204 ea.getKey()==osgGA::GUIEventAdapter::KEY_Left || 205 ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left) 206 206 { 207 207 _ForestTechniqueManager->advanceToNextTechnique(-1); … … 261 261 } 262 262 return true; 263 }264 else265 {266 return false;267 }263 } 264 else 265 { 266 return false; 267 } 268 268 } 269 269 … … 330 330 331 331 void ForestTechniqueManager::Cell::bin() 332 { 332 { 333 333 // put trees in appropriate cells. 334 334 TreeList treesNotAssigned; … … 388 388 stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON); 389 389 } 390 390 391 391 geode->setStateSet( stateset ); 392 392 393 393 unsigned int numColumns = 38; 394 394 unsigned int numRows = 39; … … 407 407 } 408 408 } 409 409 410 410 float scale_z = size.z()/(max_z-min_z); 411 411 … … 428 428 } 429 429 } 430 430 431 431 geode->addDrawable(new osg::ShapeDrawable(grid)); 432 432 } … … 434 434 { 435 435 osg::Geometry* geometry = new osg::Geometry; 436 436 437 437 osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows)); 438 438 osg::Vec2Array& t = *(new osg::Vec2Array(numColumns*numRows)); 439 439 osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1)); 440 440 441 441 color[0].set(255,255,255,255); 442 442 443 443 float rowCoordDelta = size.y()/(float)(numRows-1); 444 444 float columnCoordDelta = size.x()/(float)(numColumns-1); 445 445 446 446 float rowTexDelta = 1.0f/(float)(numRows-1); 447 447 float columnTexDelta = 1.0f/(float)(numColumns-1); … … 465 465 tex.y() += rowTexDelta; 466 466 } 467 467 468 468 geometry->setVertexArray(&v); 469 469 geometry->setColorArray(&color); 470 470 geometry->setColorBinding(osg::Geometry::BIND_OVERALL); 471 471 geometry->setTexCoordArray(0,&t); 472 472 473 473 for(r=0;r<numRows-1;++r) 474 474 { … … 482 482 } 483 483 } 484 484 485 485 geode->addDrawable(geometry); 486 486 487 487 osgUtil::SmoothingVisitor sv; 488 488 sv.smooth(*geometry); 489 489 } 490 490 491 491 return geode; 492 492 } … … 497 497 float max_TreeHeight = sqrtf(size.length2()/(float)numTreesToCreate); 498 498 float max_TreeWidth = max_TreeHeight*0.5f; 499 499 500 500 float min_TreeHeight = max_TreeHeight*0.3f; 501 501 float min_TreeWidth = min_TreeHeight*0.5f; … … 512 512 tree->_height = random(min_TreeHeight,max_TreeHeight); 513 513 tree->_type = 0; 514 514 515 515 if (terrain) 516 516 { 517 osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = 517 osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = 518 518 new osgUtil::LineSegmentIntersector(tree->_position,tree->_position+osg::Vec3(0.0f,0.0f,size.z())); 519 519 520 520 osgUtil::IntersectionVisitor iv(intersector.get()); 521 521 522 522 terrain->accept(iv); 523 523 … … 534 534 } 535 535 } 536 536 537 537 trees.push_back(tree); 538 538 } … … 578 578 osg::Vec2Array& t = *(new osg::Vec2Array(8)); 579 579 osg::Vec4ubArray& c = *(new osg::Vec4ubArray(1)); 580 580 581 581 float rotation = random(0.0f,osg::PI/2.0f); 582 582 float sw = sinf(rotation)*w*0.5f; … … 623 623 bool needGroup = !(cell->_cells.empty()); 624 624 bool needBillboard = !(cell->_trees.empty()); 625 625 626 626 osg::Billboard* billboard = 0; 627 627 osg::Group* group = 0; 628 628 629 629 if (needBillboard) 630 630 { … … 636 636 { 637 637 Tree& tree = **itr; 638 billboard->addDrawable(createSprite(tree._width,tree._height,tree._color),tree._position); 639 } 640 } 641 638 billboard->addDrawable(createSprite(tree._width,tree._height,tree._color),tree._position); 639 } 640 } 641 642 642 if (needGroup) 643 643 { … … 649 649 group->addChild(createBillboardGraph(itr->get(),stateset)); 650 650 } 651 651 652 652 if (billboard) group->addChild(billboard); 653 653 654 654 } 655 655 if (group) return group; … … 661 661 bool needGroup = !(cell->_cells.empty()); 662 662 bool needTrees = !(cell->_trees.empty()); 663 663 664 664 osg::Geode* geode = 0; 665 665 osg::Group* group = 0; 666 666 667 667 if (needTrees) 668 668 { 669 669 geode = new osg::Geode; 670 670 geode->setStateSet(stateset); 671 671 672 672 for(TreeList::iterator itr=cell->_trees.begin(); 673 673 itr!=cell->_trees.end(); … … 678 678 } 679 679 } 680 680 681 681 if (needGroup) 682 682 { … … 688 688 group->addChild(createXGraph(itr->get(),stateset)); 689 689 } 690 690 691 691 if (geode) group->addChild(geode); 692 692 693 693 } 694 694 if (group) return group; … … 700 700 bool needGroup = !(cell->_cells.empty()); 701 701 bool needTrees = !(cell->_trees.empty()); 702 702 703 703 osg::Group* transform_group = 0; 704 704 osg::Group* group = 0; 705 705 706 706 if (needTrees) 707 707 { 708 708 transform_group = new osg::Group; 709 709 710 710 osg::Geometry* geometry = createOrthogonalQuads(osg::Vec3(0.0f,0.0f,0.0f),1.0f,1.0f,osg::Vec4ub(255,255,255,255)); 711 711 712 712 for(TreeList::iterator itr=cell->_trees.begin(); 713 713 itr!=cell->_trees.end(); … … 717 717 osg::MatrixTransform* transform = new osg::MatrixTransform; 718 718 transform->setMatrix(osg::Matrix::scale(tree._width,tree._width,tree._height)*osg::Matrix::translate(tree._position)); 719 719 720 720 osg::Geode* geode = new osg::Geode; 721 721 geode->setStateSet(stateset); … … 725 725 } 726 726 } 727 727 728 728 if (needGroup) 729 729 { … … 735 735 group->addChild(createTransformGraph(itr->get(),stateset)); 736 736 } 737 737 738 738 if (transform_group) group->addChild(transform_group); 739 739 740 740 } 741 741 if (group) return group; … … 748 748 osg::Vec3Array& v = *(new osg::Vec3Array(8)); 749 749 osg::Vec2Array& t = *(new osg::Vec2Array(8)); 750 750 751 751 float rotation = random(0.0f,osg::PI/2.0f); 752 752 float sw = sinf(rotation)*w*0.5f; … … 796 796 797 797 typedef std::vector<osg::Vec4> PositionSizeList; 798 798 799 799 virtual void drawImplementation(osg::RenderInfo& renderInfo) const 800 800 { … … 823 823 return bb; 824 824 } 825 825 826 826 void setGeometry(osg::Geometry* geometry) 827 827 { 828 828 _geometry = geometry; 829 829 } 830 830 831 831 void addTree(ForestTechniqueManager::Tree& tree) 832 832 { 833 833 _trees.push_back(osg::Vec4(tree._position.x(), tree._position.y(), tree._position.z(), tree._height)); 834 834 } 835 835 836 836 osg::ref_ptr<osg::Geometry> _geometry; 837 837 … … 839 839 840 840 protected: 841 841 842 842 virtual ~ShaderGeometry() {} 843 843 844 844 }; 845 845 … … 857 857 bool needGroup = !(cell->_cells.empty()); 858 858 bool needTrees = !(cell->_trees.empty()); 859 859 860 860 osg::Geode* geode = 0; 861 861 osg::Group* group = 0; 862 862 863 863 if (needTrees) 864 864 { 865 865 geode = new osg::Geode; 866 866 867 867 ShaderGeometry* shader_geometry = new ShaderGeometry; 868 868 shader_geometry->setGeometry(shared_geometry); 869 870 869 870 871 871 for(TreeList::iterator itr=cell->_trees.begin(); 872 872 itr!=cell->_trees.end(); … … 881 881 geode->addDrawable(shader_geometry); 882 882 } 883 883 884 884 if (needGroup) 885 885 { … … 891 891 group->addChild(createShaderGraph(itr->get(),stateset)); 892 892 } 893 893 894 894 if (geode) group->addChild(geode); 895 895 896 896 } 897 897 if (group) return group; … … 902 902 { 903 903 osg::Geode* geode = new osg::Geode(); 904 904 905 905 std::string timesFont("fonts/arial.ttf"); 906 906 … … 909 909 stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); 910 910 911 // or disable depth test, and make sure that the hud is drawn after everything 911 // or disable depth test, and make sure that the hud is drawn after everything 912 912 // else so that it always appears ontop. 913 913 stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); … … 924 924 text->setPosition(position); 925 925 text->setText(str); 926 926 927 927 position += delta; 928 } 929 930 928 } 929 930 931 931 // create the hud. 932 932 osg::MatrixTransform* modelview_abs = new osg::MatrixTransform; … … 950 950 osg::ref_ptr<osg::Node> terrain = createTerrain(origin,size); 951 951 std::cout<<"done."<<std::endl; 952 952 953 953 std::cout<<"Creating tree locations...";std::cout.flush(); 954 954 TreeList trees; 955 955 createTreeList(terrain.get(),origin,size,numTreesToCreates,trees); 956 956 std::cout<<"done."<<std::endl; 957 957 958 958 std::cout<<"Creating cell subdivision..."; 959 959 osg::ref_ptr<Cell> cell = new Cell; 960 960 cell->addTrees(trees); 961 961 cell->divide(); 962 std::cout<<"done."<<std::endl;963 964 962 std::cout<<"done."<<std::endl; 963 964 965 965 osg::Texture2D *tex = new osg::Texture2D; 966 966 tex->setWrap( osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP ); … … 969 969 970 970 osg::StateSet *dstate = new osg::StateSet; 971 { 971 { 972 972 dstate->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON ); 973 973 … … 984 984 dstate->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); 985 985 } 986 986 987 987 988 988 _techniqueSwitch = new osg::Switch; … … 996 996 std::cout<<"done."<<std::endl; 997 997 } 998 998 999 999 { 1000 1000 std::cout<<"Creating double quad based forest..."; … … 1026 1026 vp_oss << 1027 1027 "!!ARBvp1.0\n" 1028 1028 1029 1029 "ATTRIB vpos = vertex.position;\n" 1030 1030 "ATTRIB vcol = vertex.color;\n" … … 1035 1035 1036 1036 "TEMP position;\n" 1037 1038 // vec3 position = gl_Vertex.xyz * gl_Color.w + gl_Color.xyz;1037 1038 // vec3 position = gl_Vertex.xyz * gl_Color.w + gl_Color.xyz; 1039 1039 "MAD position, vpos, vcol.w, vcol;\n" 1040 1040 … … 1049 1049 "MOV result.color.front.primary, one;\n" 1050 1050 1051 // texcoord = gl_MultiTexCoord0.st;1051 // texcoord = gl_MultiTexCoord0.st; 1052 1052 "MOV result.texcoord, tc;\n" 1053 1053 "END\n"; … … 1088 1088 #if 1 1089 1089 // use inline shaders 1090 1090 1091 1091 /////////////////////////////////////////////////////////////////// 1092 1092 // vertex shader using just Vec4 coefficients 1093 char vertexShaderSource[] = 1093 char vertexShaderSource[] = 1094 1094 "varying vec2 texcoord;\n" 1095 1095 "\n" … … 1105 1105 // fragment shader 1106 1106 // 1107 char fragmentShaderSource[] = 1107 char fragmentShaderSource[] = 1108 1108 "uniform sampler2D baseTexture; \n" 1109 1109 "varying vec2 texcoord; \n" … … 1119 1119 osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource); 1120 1120 program->addShader(fragment_shader); 1121 1121 1122 1122 #else 1123 1123 … … 1140 1140 _currentTechnique = 0; 1141 1141 _techniqueSwitch->setSingleChildOn(_currentTechnique); 1142 1142 1143 1143 1144 1144 osg::Group* scene = new osg::Group; 1145 1145 1146 1146 scene->addChild(terrain.get()); 1147 1147 scene->addChild(_techniqueSwitch.get()); … … 1155 1155 // use an ArgumentParser object to manage the program arguments. 1156 1156 osg::ArgumentParser arguments(&argc,argv); 1157 1157 1158 1158 // construct the viewer. 1159 1159 osgViewer::Viewer viewer(arguments); … … 1161 1161 float numTreesToCreates = 10000; 1162 1162 arguments.read("--trees",numTreesToCreates); 1163 1163 1164 1164 osg::ref_ptr<ForestTechniqueManager> ttm = new ForestTechniqueManager; 1165 1165 1166 1166 // add the stats handler 1167 1167 viewer.addEventHandler(new osgViewer::StatsHandler);
