Added osgTerrain::TerrainTile::set/getBlendingPolicy(BlendingPolicy) to enable control over whether the tile should have blending enabled on it.

This commit is contained in:
Robert Osfield 2010-03-16 12:05:41 +00:00
parent d10ce23e62
commit 1537af6235
3 changed files with 69 additions and 39 deletions

View File

@ -156,6 +156,21 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group
/** Get whether the TeatBoundariesToValidDataAsDefaultValue hint.*/ /** Get whether the TeatBoundariesToValidDataAsDefaultValue hint.*/
bool getTreatBoundariesToValidDataAsDefaultValue() const { return _treatBoundariesToValidDataAsDefaultValue; } bool getTreatBoundariesToValidDataAsDefaultValue() const { return _treatBoundariesToValidDataAsDefaultValue; }
enum BlendingPolicy
{
DO_NOT_SET_BLENDING,
ENABLE_BLENDING,
ENABLE_BLENDING_WHEN_ALPHA_PRESENT /** Default - check colour layers for alpha value and if present enable blending. */
};
/** Set the policy to use when deciding whether to enable/disable blending and use of transparent bin.*/
void setBlendingPolicy(BlendingPolicy policy) { _blendingPolicy = policy; }
/** Get the policy to use when deciding whether to enable/disable blending and use of transparent bin.*/
BlendingPolicy getBlendingPolicy() const { return _blendingPolicy; }
/** Set the dirty flag on/off.*/ /** Set the dirty flag on/off.*/
void setDirty(bool dirty); void setDirty(bool dirty);
@ -171,7 +186,7 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group
virtual bool deferExternalLayerLoading() const = 0; virtual bool deferExternalLayerLoading() const = 0;
virtual void loaded(osgTerrain::TerrainTile* tile, const osgDB::ReaderWriter::Options* options) const = 0; virtual void loaded(osgTerrain::TerrainTile* tile, const osgDB::ReaderWriter::Options* options) const = 0;
}; };
static void setTileLoadedCallback(TileLoadedCallback* lc); static void setTileLoadedCallback(TileLoadedCallback* lc);
static osg::ref_ptr<TileLoadedCallback>& getTileLoadedCallback(); static osg::ref_ptr<TileLoadedCallback>& getTileLoadedCallback();
@ -185,27 +200,27 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group
virtual ~TerrainTile(); virtual ~TerrainTile();
typedef std::vector< osg::ref_ptr<Layer> > Layers; typedef std::vector< osg::ref_ptr<Layer> > Layers;
friend class Terrain; friend class Terrain;
Terrain* _terrain; Terrain* _terrain;
bool _dirty; bool _dirty;
bool _hasBeenTraversal; bool _hasBeenTraversal;
TileID _tileID; TileID _tileID;
osg::ref_ptr<TerrainTechnique> _terrainTechnique; osg::ref_ptr<TerrainTechnique> _terrainTechnique;
osg::ref_ptr<Locator> _locator; osg::ref_ptr<Locator> _locator;
osg::ref_ptr<Layer> _elevationLayer; osg::ref_ptr<Layer> _elevationLayer;
Layers _colorLayers; Layers _colorLayers;
bool _requiresNormals; bool _requiresNormals;
bool _treatBoundariesToValidDataAsDefaultValue; bool _treatBoundariesToValidDataAsDefaultValue;
BlendingPolicy _blendingPolicy;
}; };
/** Helper callback for managing optional sets of layers, that loading of is deffered to this callback, /** Helper callback for managing optional sets of layers, that loading of is deffered to this callback,

View File

@ -107,21 +107,22 @@ void GeometryTechnique::setFilterMatrixAs(FilterType filterType)
void GeometryTechnique::init() void GeometryTechnique::init()
{ {
OSG_NOTIFY(osg::INFO)<<"Doing GeometryTechnique::init()"<<std::endl; OSG_INFO<<"Doing GeometryTechnique::init()"<<std::endl;
if (!_terrainTile) return; if (!_terrainTile) return;
BufferData& buffer = getWriteBuffer(); BufferData& buffer = getWriteBuffer();
Locator* masterLocator = computeMasterLocator(); Locator* masterLocator = computeMasterLocator();
osg::Vec3d centerModel = computeCenterModel(masterLocator); osg::Vec3d centerModel = computeCenterModel(masterLocator);
generateGeometry(masterLocator, centerModel); generateGeometry(masterLocator, centerModel);
applyColorLayers(); applyColorLayers();
applyTransparency(); applyTransparency();
// smoothGeometry(); // smoothGeometry();
if (buffer._transform.valid()) buffer._transform->setThreadSafeRefUnref(true); if (buffer._transform.valid()) buffer._transform->setThreadSafeRefUnref(true);
@ -140,7 +141,7 @@ Locator* GeometryTechnique::computeMasterLocator()
Locator* masterLocator = elevationLocator ? elevationLocator : colorLocator; Locator* masterLocator = elevationLocator ? elevationLocator : colorLocator;
if (!masterLocator) if (!masterLocator)
{ {
OSG_NOTIFY(osg::NOTICE)<<"Problem, no locator found in any of the terrain layers"<<std::endl; OSG_NOTICE<<"Problem, no locator found in any of the terrain layers"<<std::endl;
return 0; return 0;
} }
@ -195,8 +196,8 @@ osg::Vec3d GeometryTechnique::computeCenterModel(Locator* masterLocator)
} }
} }
OSG_NOTIFY(osg::INFO)<<"bottomLeftNDC = "<<bottomLeftNDC<<std::endl; OSG_INFO<<"bottomLeftNDC = "<<bottomLeftNDC<<std::endl;
OSG_NOTIFY(osg::INFO)<<"topRightNDC = "<<topRightNDC<<std::endl; OSG_INFO<<"topRightNDC = "<<topRightNDC<<std::endl;
buffer._transform = new osg::MatrixTransform; buffer._transform = new osg::MatrixTransform;
@ -238,7 +239,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
double i_sampleFactor = 1.0; double i_sampleFactor = 1.0;
double j_sampleFactor = 1.0; double j_sampleFactor = 1.0;
// OSG_NOTIFY(osg::NOTICE)<<"Sample ratio="<<sampleRatio<<std::endl; // OSG_NOTICE<<"Sample ratio="<<sampleRatio<<std::endl;
if (sampleRatio!=1.0f) if (sampleRatio!=1.0f)
{ {
@ -256,7 +257,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
bool treatBoundariesToValidDataAsDefaultValue = _terrainTile->getTreatBoundariesToValidDataAsDefaultValue(); bool treatBoundariesToValidDataAsDefaultValue = _terrainTile->getTreatBoundariesToValidDataAsDefaultValue();
OSG_NOTIFY(osg::INFO)<<"TreatBoundariesToValidDataAsDefaultValue="<<treatBoundariesToValidDataAsDefaultValue<<std::endl; OSG_INFO<<"TreatBoundariesToValidDataAsDefaultValue="<<treatBoundariesToValidDataAsDefaultValue<<std::endl;
float skirtHeight = 0.0f; float skirtHeight = 0.0f;
HeightFieldLayer* hfl = dynamic_cast<HeightFieldLayer*>(elevationLayer); HeightFieldLayer* hfl = dynamic_cast<HeightFieldLayer*>(elevationLayer);
@ -362,7 +363,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
{ {
float value = 0.0f; float value = 0.0f;
validValue = elevationLayer->getValidValue(i_equiv,j_equiv, value); validValue = elevationLayer->getValidValue(i_equiv,j_equiv, value);
// OSG_NOTIFY(osg::INFO)<<"i="<<i<<" j="<<j<<" z="<<value<<std::endl; // OSG_INFO<<"i="<<i<<" j="<<j<<" z="<<value<<std::endl;
ndc.z() = value*scaleHeight; ndc.z() = value*scaleHeight;
} }
@ -419,7 +420,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
bool smallTile = numVertices <= 16384; bool smallTile = numVertices <= 16384;
// OSG_NOTIFY(osg::NOTICE)<<"smallTile = "<<smallTile<<std::endl; // OSG_NOTICE<<"smallTile = "<<smallTile<<std::endl;
osg::ref_ptr<osg::DrawElements> elements = smallTile ? osg::ref_ptr<osg::DrawElements> elements = smallTile ?
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_TRIANGLES)) : static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_TRIANGLES)) :
@ -697,11 +698,11 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
//osg::Timer_t before = osg::Timer::instance()->tick(); //osg::Timer_t before = osg::Timer::instance()->tick();
//OSG_NOTIFY(osg::NOTICE)<<"osgTerrain::GeometryTechnique::build kd tree"<<std::endl; //OSG_NOTICE<<"osgTerrain::GeometryTechnique::build kd tree"<<std::endl;
osg::ref_ptr<osg::KdTreeBuilder> builder = osgDB::Registry::instance()->getKdTreeBuilder()->clone(); osg::ref_ptr<osg::KdTreeBuilder> builder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
buffer._geode->accept(*builder); buffer._geode->accept(*builder);
//osg::Timer_t after = osg::Timer::instance()->tick(); //osg::Timer_t after = osg::Timer::instance()->tick();
//OSG_NOTIFY(osg::NOTICE)<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl; //OSG_NOTICE<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
} }
} }
@ -759,19 +760,19 @@ void GeometryTechnique::applyColorLayers()
if (mipMapping && (s_NotPowerOfTwo || t_NotPowerOfTwo)) if (mipMapping && (s_NotPowerOfTwo || t_NotPowerOfTwo))
{ {
OSG_NOTIFY(osg::INFO)<<"Disabling mipmapping for non power of two tile size("<<image->s()<<", "<<image->t()<<")"<<std::endl; OSG_INFO<<"Disabling mipmapping for non power of two tile size("<<image->s()<<", "<<image->t()<<")"<<std::endl;
texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
} }
layerToTextureMap[colorLayer] = texture2D; layerToTextureMap[colorLayer] = texture2D;
// OSG_NOTIFY(osg::NOTICE)<<"Creating new ImageLayer texture "<<layerNum<<" image->s()="<<image->s()<<" image->t()="<<image->t()<<std::endl; // OSG_NOTICE<<"Creating new ImageLayer texture "<<layerNum<<" image->s()="<<image->s()<<" image->t()="<<image->t()<<std::endl;
} }
else else
{ {
// OSG_NOTIFY(osg::NOTICE)<<"Reusing ImageLayer texture "<<layerNum<<std::endl; // OSG_NOTICE<<"Reusing ImageLayer texture "<<layerNum<<std::endl;
} }
stateset->setTextureAttributeAndModes(layerNum, texture2D, osg::StateAttribute::ON); stateset->setTextureAttributeAndModes(layerNum, texture2D, osg::StateAttribute::ON);
@ -801,21 +802,33 @@ void GeometryTechnique::applyColorLayers()
void GeometryTechnique::applyTransparency() void GeometryTechnique::applyTransparency()
{ {
BufferData& buffer = getWriteBuffer(); if (_terrainTile->getBlendingPolicy()==TerrainTile::DO_NOT_SET_BLENDING)
bool containsTransparency = false;
for(unsigned int i=0; i<_terrainTile->getNumColorLayers(); ++i)
{ {
osg::Image* image = (_terrainTile->getColorLayer(i)!=0) ? _terrainTile->getColorLayer(i)->getImage() : 0; return;
if (image)
{
containsTransparency = image->isImageTranslucent();
break;
}
} }
if (containsTransparency) bool enableBlending = false;
if (_terrainTile->getBlendingPolicy()==TerrainTile::ENABLE_BLENDING)
{ {
enableBlending = true;
}
else if (_terrainTile->getBlendingPolicy()==TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT)
{
for(unsigned int i=0; i<_terrainTile->getNumColorLayers(); ++i)
{
osg::Image* image = (_terrainTile->getColorLayer(i)!=0) ? _terrainTile->getColorLayer(i)->getImage() : 0;
if (image)
{
enableBlending = image->isImageTranslucent();
break;
}
}
}
if (enableBlending)
{
BufferData& buffer = getWriteBuffer();
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet(); osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
stateset->setMode(GL_BLEND, osg::StateAttribute::ON); stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
@ -885,7 +898,7 @@ void GeometryTechnique::traverse(osg::NodeVisitor& nv)
if (_terrainTile->getDirty()) if (_terrainTile->getDirty())
{ {
OSG_NOTIFY(osg::INFO)<<"******* Doing init ***********"<<std::endl; OSG_INFO<<"******* Doing init ***********"<<std::endl;
_terrainTile->init(); _terrainTile->init();
} }

View File

@ -61,7 +61,8 @@ TerrainTile::TerrainTile():
_dirty(false), _dirty(false),
_hasBeenTraversal(false), _hasBeenTraversal(false),
_requiresNormals(true), _requiresNormals(true),
_treatBoundariesToValidDataAsDefaultValue(false) _treatBoundariesToValidDataAsDefaultValue(false),
_blendingPolicy(ENABLE_BLENDING_WHEN_ALPHA_PRESENT)
{ {
setThreadSafeRefUnref(true); setThreadSafeRefUnref(true);
} }
@ -74,7 +75,8 @@ TerrainTile::TerrainTile(const TerrainTile& terrain,const osg::CopyOp& copyop):
_elevationLayer(terrain._elevationLayer), _elevationLayer(terrain._elevationLayer),
_colorLayers(terrain._colorLayers), _colorLayers(terrain._colorLayers),
_requiresNormals(terrain._requiresNormals), _requiresNormals(terrain._requiresNormals),
_treatBoundariesToValidDataAsDefaultValue(terrain._treatBoundariesToValidDataAsDefaultValue) _treatBoundariesToValidDataAsDefaultValue(terrain._treatBoundariesToValidDataAsDefaultValue),
_blendingPolicy(terrain._blendingPolicy)
{ {
if (terrain.getTerrainTechnique()) if (terrain.getTerrainTechnique())
{ {