diff --git a/examples/osgterrain/osgterrain.cpp b/examples/osgterrain/osgterrain.cpp index 0be1c21b9..90097989c 100644 --- a/examples/osgterrain/osgterrain.cpp +++ b/examples/osgterrain/osgterrain.cpp @@ -140,11 +140,31 @@ public: toggleDefine("LIGHTING"); return true; } + else if (ea.getKey()=='h') + { + toggleDefine("HEIGHTFIELD_LAYER"); + return true; + } else if (ea.getKey()=='t') { toggleDefine("TEXTURE_2D"); return true; } + else if (ea.getKey()=='y') + { + toggleDefine("COLOR_LAYER0"); + return true; + } + else if (ea.getKey()=='u') + { + toggleDefine("COLOR_LAYER1"); + return true; + } + else if (ea.getKey()=='i') + { + toggleDefine("COLOR_LAYER2"); + return true; + } else if (ea.getKey()=='d') { toggleDefine("COMPUTE_DIAGONALS"); diff --git a/include/osg/StateSet b/include/osg/StateSet index d68700e13..1ae5d1fc8 100644 --- a/include/osg/StateSet +++ b/include/osg/StateSet @@ -327,7 +327,7 @@ class OSG_EXPORT StateSet : public Object /** Set the list of defines to pass on to shaders.*/ - void setDefineList(DefineList& dl) { _defineList = dl; } + void setDefineList(const DefineList& dl) { _defineList = dl; } /** Get the list of defines to pass on to shaders.*/ DefineList& getDefineList() { return _defineList; } diff --git a/include/osgTerrain/GeometryPool b/include/osgTerrain/GeometryPool index feb849102..b51ac7887 100644 --- a/include/osgTerrain/GeometryPool +++ b/include/osgTerrain/GeometryPool @@ -145,6 +145,8 @@ class OSGTERRAIN_EXPORT GeometryPool : public osg::Referenced typedef std::vector LayerTypes; typedef std::map > ProgramMap; + osg::StateSet* getRootStateSetForTerrain(Terrain* terrain); + virtual osg::ref_ptr getOrCreateProgram(LayerTypes& layerTypes); virtual osg::ref_ptr getOrCreateGeometry(osgTerrain::TerrainTile* tile); @@ -153,19 +155,17 @@ class OSGTERRAIN_EXPORT GeometryPool : public osg::Referenced virtual void applyLayers(osgTerrain::TerrainTile* tile, osg::StateSet* stateset); - void setUseGeometryShader(bool flag) { _useGeometryShader = flag; } - bool getUseGeometryShader() const { return _useGeometryShader; } - protected: virtual ~GeometryPool(); - bool _useGeometryShader; - OpenThreads::Mutex _geometryMapMutex; GeometryMap _geometryMap; OpenThreads::Mutex _programMapMutex; ProgramMap _programMap; + + osg::ref_ptr _rootStateSet; + bool _rootStateSetAssigned; }; diff --git a/src/osgFX/MultiTextureControl.cpp b/src/osgFX/MultiTextureControl.cpp index 3edc3c317..b0304f042 100644 --- a/src/osgFX/MultiTextureControl.cpp +++ b/src/osgFX/MultiTextureControl.cpp @@ -165,6 +165,7 @@ void MultiTextureControl::updateStateSet() } #endif stateset->addUniform(uniform.get()); + stateset->setDefine("TEXTURE_WEIGHTS"); } setStateSet(stateset.get()); diff --git a/src/osgTerrain/GeometryPool.cpp b/src/osgTerrain/GeometryPool.cpp index d5f70c917..a06e3c87f 100644 --- a/src/osgTerrain/GeometryPool.cpp +++ b/src/osgTerrain/GeometryPool.cpp @@ -42,21 +42,10 @@ const osgTerrain::Locator* osgTerrain::computeMasterLocator(const osgTerrain::Te // GeometryPool // GeometryPool::GeometryPool(): - _useGeometryShader(false) + _rootStateSetAssigned(false) + { - const char* ptr = 0; - if ((ptr = getenv("OSG_TERRAIN_USE_GEOMETRY_SHADER")) != 0) - { - if (strcmp(ptr,"OFF")==0 || strcmp(ptr,"Off")==0 || strcmp(ptr,"off")==0 || - strcmp(ptr,"FALSE")==0 || strcmp(ptr,"False")==0 || strcmp(ptr,"false")==0) - { - _useGeometryShader = false; - } - else - { - _useGeometryShader = true; - } - } + _rootStateSet = new osg::StateSet; } GeometryPool::~GeometryPool() @@ -322,8 +311,8 @@ osg::ref_ptr GeometryPool::getOrCreateGeometry(osgTerrain::Terra #else bool smallTile = numVertices <= 16384; - GLenum primitiveTypes = _useGeometryShader ? GL_LINES_ADJACENCY : GL_QUADS; - primitiveTypes = GL_QUADS; + GLenum primitiveTypes = GL_QUADS; + osg::ref_ptr elements = smallTile ? static_cast(new osg::DrawElementsUShort(primitiveTypes)) : static_cast(new osg::DrawElementsUInt(primitiveTypes)); @@ -577,11 +566,11 @@ osg::ref_ptr GeometryPool::getTileSubgraph(osgTerrain::Ter osg::ref_ptr GeometryPool::getOrCreateProgram(LayerTypes& layerTypes) { - OpenThreads::ScopedLock lock(_programMapMutex); + //OpenThreads::ScopedLock lock(_programMapMutex); ProgramMap::iterator itr = _programMap.find(layerTypes); if (itr!=_programMap.end()) { - // OSG_NOTICE<<") returning exisitng Program "<second.get()<second.get()<second.get(); } @@ -615,21 +604,14 @@ osg::ref_ptr GeometryPool::getOrCreateProgram(LayerTypes& layerTyp program->addShader(osgDB::readShaderFile("shaders/lighting.vert")); // OSG_NOTICE<<") creating new Program "<0) { #include "shaders/terrain_displacement_mapping_vert.cpp" osg::ref_ptr shader = osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping.vert", terrain_displacement_mapping_vert); program->addShader(shader.get()); } - else - { - #include "shaders/terrain_displacement_mapping_flat_vert.cpp" - program->addShader(osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping.vert", terrain_displacement_mapping_flat_vert)); - } - //if (_useGeometryShader) { #include "shaders/terrain_displacement_mapping_geom.cpp" osg::ref_ptr shader = osgDB::readShaderFileWithFallback(osg::Shader::GEOMETRY, "shaders/terrain_displacement_mapping.geom", terrain_displacement_mapping_geom); @@ -646,27 +628,8 @@ osg::ref_ptr GeometryPool::getOrCreateProgram(LayerTypes& layerTyp } { - osg::ref_ptr shader; - if (num_Color==0) - { - #include "shaders/terrain_displacement_mapping_frag.cpp" - shader = osgDB::readShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/terrain_displacement_mapping.frag", terrain_displacement_mapping_frag); - } - else if (num_Color==1) - { - #include "shaders/terrain_displacement_mapping_C_frag.cpp" - shader = osgDB::readShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/terrain_displacement_mapping_C.frag", terrain_displacement_mapping_C_frag); - } - else if (num_Color==2) - { - #include "shaders/terrain_displacement_mapping_CC_frag.cpp" - shader = osgDB::readShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/terrain_displacement_mapping_CC.frag", terrain_displacement_mapping_CC_frag); - } - else if (num_Color==3) - { - #include "shaders/terrain_displacement_mapping_CCC_frag.cpp" - shader = osgDB::readShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/terrain_displacement_mapping_CCC.frag", terrain_displacement_mapping_CCC_frag); - } + #include "shaders/terrain_displacement_mapping_frag.cpp" + osg::ref_ptr shader = osgDB::readShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/terrain_displacement_mapping.frag", terrain_displacement_mapping_frag); if (shader.valid()) { @@ -723,6 +686,7 @@ void GeometryPool::applyLayers(osgTerrain::TerrainTile* tile, osg::StateSet* sta layerTypes.push_back(HEIGHTFIELD_LAYER); } #if 1 + int colorLayerNum = 0; for(unsigned int layerNum=0; layerNumgetNumColorLayers(); ++layerNum) { osgTerrain::Layer* colorLayer = tile->getColorLayer(layerNum); @@ -787,47 +751,77 @@ void GeometryPool::applyLayers(osgTerrain::TerrainTile* tile, osg::StateSet* sta stateset->setTextureAttributeAndModes(textureUnit, texture2D, osg::StateAttribute::ON); std::stringstream str; - str<<"colorTexture"<addUniform(new osg::Uniform(str.str().c_str(),textureUnit)); layerTypes.push_back(COLOR_LAYER); + ++colorLayerNum; + } else if (contourLayer) { - osg::Texture1D* texture1D = dynamic_cast(layerToTextureMap[colorLayer]); - if (!texture1D) - { - texture1D = new osg::Texture1D; - texture1D->setImage(image); - texture1D->setResizeNonPowerOfTwoHint(false); - texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); - texture1D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getMagFilter()); - - layerToTextureMap[colorLayer] = texture1D; - } - - int textureUnit = layerTypes.size(); - stateset->setTextureAttributeAndModes(textureUnit, texture1D, osg::StateAttribute::ON); - - std::stringstream str; - str<<"contourTexture"<addUniform(new osg::Uniform(str.str().c_str(),textureUnit)); - - layerTypes.push_back(CONTOUR_LAYER); + OSG_NOTICE<<"Warning : GeometryPool does not presently support ContourLayers."< program = getOrCreateProgram(layerTypes); - if (program.valid()) - { - stateset->setAttribute(program.get()); - } + + // If we have a root StateSet assigned for Terrain? + // If tile_LayerTypes a subset of root_LayerTypes then toggle on/off locally + // If tile_LayerTypes a superset of root_LayerTypes then create local Program + // else no need to set anything + // else no root StateSet + // create new StateSet for Program required and assigned with layers required enabled + // + + //stateset->setDefine("GL_LIGHTING", osg::StateAttribute::ON); + { + OpenThreads::ScopedLock lock(_programMapMutex); + if (!_rootStateSetAssigned) + { + _rootStateSetAssigned = true; + + _rootStateSet->setDefine("LIGHTING"); + + int num_Color = 0; + for(LayerTypes::iterator itr = layerTypes.begin(); + itr != layerTypes.end(); + ++itr) + { + switch(*itr) + { + case(HEIGHTFIELD_LAYER): _rootStateSet->setDefine("HEIGHTFIELD_LAYER"); break; + case(COLOR_LAYER): ++num_Color; break; + case(CONTOUR_LAYER): break; // not supported right now + } + } + + if (num_Color>=1) + { + _rootStateSet->setDefine("TEXTURE_2D"); + _rootStateSet->setDefine("COLOR_LAYER0"); + } + + if (num_Color>=2) _rootStateSet->setDefine("COLOR_LAYER1"); + if (num_Color>=3) _rootStateSet->setDefine("COLOR_LAYER2"); + + osg::ref_ptr program = getOrCreateProgram(layerTypes); + if (program.valid()) + { + _rootStateSet->setAttribute(program.get()); + } + } + } } +osg::StateSet* GeometryPool::getRootStateSetForTerrain(Terrain* terrain) +{ + //OSG_NOTICE<<"getRootStateSetForTerrain("<(&nv); + osg::StateSet* ss = _geometryPool.valid() ? _geometryPool->getRootStateSetForTerrain(this) : 0; + if (cv && ss) + { + cv->pushStateSet(ss); + Group::traverse(nv); + cv->popStateSet(); + return; + } + } + Group::traverse(nv); }