First step of refactoring the osg::Program management in osgTerrain::GeometryPool for better performance by placing default osg::Program and shader defines on a single StateSet below the osgTerrain::Terrain
git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14704 16af8721-9629-0410-8352-f15c8da7e697
This commit is contained in:
parent
5c023d1f76
commit
afbf20eba9
@ -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");
|
||||
|
@ -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; }
|
||||
|
@ -145,6 +145,8 @@ class OSGTERRAIN_EXPORT GeometryPool : public osg::Referenced
|
||||
typedef std::vector<LayerType> LayerTypes;
|
||||
typedef std::map<LayerTypes, osg::ref_ptr<osg::Program> > ProgramMap;
|
||||
|
||||
osg::StateSet* getRootStateSetForTerrain(Terrain* terrain);
|
||||
|
||||
virtual osg::ref_ptr<osg::Program> getOrCreateProgram(LayerTypes& layerTypes);
|
||||
|
||||
virtual osg::ref_ptr<SharedGeometry> 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<osg::StateSet> _rootStateSet;
|
||||
bool _rootStateSetAssigned;
|
||||
};
|
||||
|
||||
|
||||
|
@ -165,6 +165,7 @@ void MultiTextureControl::updateStateSet()
|
||||
}
|
||||
#endif
|
||||
stateset->addUniform(uniform.get());
|
||||
stateset->setDefine("TEXTURE_WEIGHTS");
|
||||
}
|
||||
|
||||
setStateSet(stateset.get());
|
||||
|
@ -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<SharedGeometry> 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<osg::DrawElements> elements = smallTile ?
|
||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(primitiveTypes)) :
|
||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(primitiveTypes));
|
||||
@ -577,11 +566,11 @@ osg::ref_ptr<osg::MatrixTransform> GeometryPool::getTileSubgraph(osgTerrain::Ter
|
||||
|
||||
osg::ref_ptr<osg::Program> GeometryPool::getOrCreateProgram(LayerTypes& layerTypes)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_programMapMutex);
|
||||
//OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_programMapMutex);
|
||||
ProgramMap::iterator itr = _programMap.find(layerTypes);
|
||||
if (itr!=_programMap.end())
|
||||
{
|
||||
// OSG_NOTICE<<") returning exisitng Program "<<itr->second.get()<<std::endl;
|
||||
// OSG_NOTICE<<") returning existing Program "<<itr->second.get()<<std::endl;
|
||||
return itr->second.get();
|
||||
}
|
||||
|
||||
@ -615,21 +604,14 @@ osg::ref_ptr<osg::Program> GeometryPool::getOrCreateProgram(LayerTypes& layerTyp
|
||||
program->addShader(osgDB::readShaderFile("shaders/lighting.vert"));
|
||||
|
||||
// OSG_NOTICE<<") creating new Program "<<program.get()<<std::endl;
|
||||
if (num_HeightField>0)
|
||||
{
|
||||
#include "shaders/terrain_displacement_mapping_vert.cpp"
|
||||
osg::ref_ptr<osg::Shader> 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<osg::Shader> shader = osgDB::readShaderFileWithFallback(osg::Shader::GEOMETRY, "shaders/terrain_displacement_mapping.geom", terrain_displacement_mapping_geom);
|
||||
@ -646,27 +628,8 @@ osg::ref_ptr<osg::Program> GeometryPool::getOrCreateProgram(LayerTypes& layerTyp
|
||||
}
|
||||
|
||||
{
|
||||
osg::ref_ptr<osg::Shader> 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<osg::Shader> 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; layerNum<tile->getNumColorLayers(); ++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"<<textureUnit;
|
||||
str<<"colorTexture"<<colorLayerNum;
|
||||
stateset->addUniform(new osg::Uniform(str.str().c_str(),textureUnit));
|
||||
|
||||
layerTypes.push_back(COLOR_LAYER);
|
||||
|
||||
++colorLayerNum;
|
||||
|
||||
}
|
||||
else if (contourLayer)
|
||||
{
|
||||
osg::Texture1D* texture1D = dynamic_cast<osg::Texture1D*>(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"<<textureUnit;
|
||||
stateset->addUniform(new osg::Uniform(str.str().c_str(),textureUnit));
|
||||
|
||||
layerTypes.push_back(CONTOUR_LAYER);
|
||||
OSG_NOTICE<<"Warning : GeometryPool does not presently support ContourLayers."<<std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
osg::ref_ptr<osg::Program> 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<OpenThreads::Mutex> 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<osg::Program> program = getOrCreateProgram(layerTypes);
|
||||
if (program.valid())
|
||||
{
|
||||
_rootStateSet->setAttribute(program.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osg::StateSet* GeometryPool::getRootStateSetForTerrain(Terrain* terrain)
|
||||
{
|
||||
//OSG_NOTICE<<"getRootStateSetForTerrain("<<terrain<<")"<<std::endl;
|
||||
return _rootStateSet.get();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -123,6 +123,19 @@ void Terrain::traverse(osg::NodeVisitor& nv)
|
||||
}
|
||||
}
|
||||
|
||||
if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
|
||||
{
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user