| | 851 | osg::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 | |
| | 925 | void 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 | |
| | 953 | osg::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 | |