osgEarth 2.1.1
|
Public Member Functions | |
TextureCompositor (const TerrainOptions &options) | |
const TerrainOptions::CompositingTechnique & | getTechnique () const |
void | applyMapModelChange (const MapModelChange &change) |
bool | supportsLayerUpdate () const |
GeoImage | prepareImage (const GeoImage &image, const GeoExtent &tileExtent) const |
GeoImage | prepareSecondaryImage (const GeoImage &image, const GeoExtent &tileExtent) const |
void | applyLayerUpdate (osg::StateSet *stateSet, UID layerUID, const GeoImage &preparedImage, const TileKey &tileKey, osg::StateSet *parentStateSet) const |
void | applyLayerRemoval (osg::StateSet *stateSet, UID layerUID) const |
void | assignTexCoordArray (osg::Geometry *geom, UID layerUID, osg::Vec2Array *texCoords) const |
bool | requiresUnitTextureSpace () const |
bool | usesShaderComposition () const |
void | updateMasterStateSet (osg::StateSet *stateSet) const |
bool | reserveTextureImageUnit (int &out_unit) |
void | releaseTextureImageUnit (int unit) |
int | getRenderOrder (UID layerUID) const |
osg::Shader * | createSamplerFunction (UID layerUID, const std::string &functionName, osg::Shader::Type type) const |
TerrainOptions & | getOptions () |
Private Member Functions | |
void | init () |
Private Attributes | |
OpenThreads::Mutex | _initMutex |
TerrainOptions::CompositingTechnique | _tech |
TerrainOptions | _options |
bool | _forceTech |
osg::ref_ptr< osg::Program > | _program |
osg::ref_ptr < TextureCompositorTechnique > | _impl |
TextureLayout | _layout |
Threading::ReadWriteMutex | _layoutMutex |
std::set< int > | _reservedUnits |
Utility class that composites texture data for use by a terrain engine.
Definition at line 144 of file TextureCompositor.
TextureCompositor::TextureCompositor | ( | const TerrainOptions & | options | ) |
Constructs a new compositor.
Definition at line 260 of file TextureCompositor.cpp.
: osg::Referenced( true ), _tech( options.compositingTechnique().value() ), _options( options ), _forceTech( false ) { // for debugging: if ( _tech == TerrainOptions::COMPOSITING_AUTO && ::getenv( "OSGEARTH_COMPOSITOR_TECH" ) ) { TerrainOptions::CompositingTechnique oldTech = _tech; std::string t( ::getenv( "OSGEARTH_COMPOSITOR_TECH" ) ); if ( t == "TEXTURE_ARRAY" ) _tech = TerrainOptions::COMPOSITING_TEXTURE_ARRAY; else if ( t == "MULTITEXTURE_GPU" ) _tech = TerrainOptions::COMPOSITING_MULTITEXTURE_GPU; else if ( t == "MULTIPASS" ) _tech = TerrainOptions::COMPOSITING_MULTIPASS; if ( oldTech != _tech ) _forceTech = true; } init(); }
void TextureCompositor::applyLayerRemoval | ( | osg::StateSet * | stateSet, |
UID | layerUID | ||
) | const |
Updates a stateset's texture composition based on the information that a layer has been removed.
Definition at line 401 of file TextureCompositor.cpp.
void TextureCompositor::applyLayerUpdate | ( | osg::StateSet * | stateSet, |
UID | layerUID, | ||
const GeoImage & | preparedImage, | ||
const TileKey & | tileKey, | ||
osg::StateSet * | parentStateSet | ||
) | const |
Updates a stateset's texture composition with an image. Typically this will be the image returned from prepareImage(), but it doesn't have to be. Note: if the stateset is live in the scene graph, be sure to only call this method from UPDATE trav.
Definition at line 386 of file TextureCompositor.cpp.
{ if ( _impl.valid() ) { Threading::ScopedReadLock sharedLock( const_cast<TextureCompositor*>(this)->_layoutMutex ); _impl->applyLayerUpdate( stateSet, layerUID, preparedImage, tileKey, _layout, parentStateSet ); } }
void TextureCompositor::applyMapModelChange | ( | const MapModelChange & | change | ) |
Applies a map model change action to the texture layout contained within this compositor. You should call this any time the map model change happens.
Definition at line 358 of file TextureCompositor.cpp.
{ Threading::ScopedWriteLock exclusiveLock( _layoutMutex ); _layout.applyMapModelChange( change, _impl.valid() ? _impl->blendingRequiresSecondarySlot() : false ); }
void TextureCompositor::assignTexCoordArray | ( | osg::Geometry * | geom, |
UID | layerUID, | ||
osg::Vec2Array * | texCoords | ||
) | const |
Assigns a texture coordinate array to a geometry, putting it in the proper texture slot according to the compositor's layout.
Definition at line 431 of file TextureCompositor.cpp.
{ if ( geom && texCoords ) { if ( _tech == TerrainOptions::COMPOSITING_MULTIPASS ) { geom->setTexCoordArray( 0, texCoords ); } else { int slot; { Threading::ScopedReadLock sharedLock( const_cast<TextureCompositor*>(this)->_layoutMutex ); slot = _layout.getSlot( layerUID ); } if ( slot >= 0 ) geom->setTexCoordArray( slot, texCoords ); } } }
osg::Shader * TextureCompositor::createSamplerFunction | ( | UID | layerUID, |
const std::string & | functionName, | ||
osg::Shader::Type | type | ||
) | const |
Creates a shader component that implements texture sampling for the layer with the specified layer UID. You can use this is a custom shader to sample texels from one of osgEarth's Map image layers.
vec4 function_name()
Definition at line 462 of file TextureCompositor.cpp.
{ osg::Shader* result = 0L; if ( _impl.valid() ) { Threading::ScopedReadLock sharedLock( const_cast<TextureCompositor*>(this)->_layoutMutex ); result = _impl->createSamplerFunction( layerUID, functionName, type, _layout ); } if ( !result ) { std::string fname = !functionName.empty() ? functionName : "defaultSamplerFunction"; std::stringstream buf; buf << "vec4 " << functionName << "() { \n return vec4(0,0,0,0); \n } \n"; std::string str = buf.str(); result = new osg::Shader( type, str ); } return result; }
TerrainOptions& osgEarth::TextureCompositor::getOptions | ( | ) | [inline] |
Gets the terrain options for this TextureCompositor
Definition at line 261 of file TextureCompositor.
{ return _options;}
int TextureCompositor::getRenderOrder | ( | UID | layerUID | ) | const |
Gets the rendering order of the layer with the specified UID.
Definition at line 455 of file TextureCompositor.cpp.
{ Threading::ScopedReadLock sharedLock( const_cast<TextureCompositor*>(this)->_layoutMutex ); return _layout.getOrder( layerUID ); }
const TerrainOptions::CompositingTechnique& osgEarth::TextureCompositor::getTechnique | ( | ) | const [inline] |
Gets the actual technique selected by the compositor. This might not be the same as the requested technique, since it will validate against system capabilities and automatically "fall back" on lesser techniques if necessary.
Definition at line 157 of file TextureCompositor.
{ return _tech; }
void TextureCompositor::init | ( | ) | [private] |
Definition at line 486 of file TextureCompositor.cpp.
{ if ( _impl.valid() ) // double-check pattern { return; // already initialized } bool isAuto = _tech == TerrainOptions::COMPOSITING_AUTO; const Capabilities& caps = Registry::instance()->getCapabilities(); // MULTITEXTURE_GPU is the current default. if (_tech == TerrainOptions::COMPOSITING_MULTITEXTURE_GPU || (isAuto && caps.supportsGLSL(1.20f) && caps.supportsMultiTexture()) ) { _tech = TerrainOptions::COMPOSITING_MULTITEXTURE_GPU; _impl = new TextureCompositorMultiTexture( true, _options ); OE_INFO << LC << "Compositing technique = MULTITEXTURE/GPU" << std::endl; } #if OSG_VERSION_GREATER_OR_EQUAL( 2, 9, 8 ) else if (_tech == TerrainOptions::COMPOSITING_TEXTURE_ARRAY || (isAuto && caps.supportsGLSL(1.30f) && caps.supportsTextureArrays()) ) { _tech = TerrainOptions::COMPOSITING_TEXTURE_ARRAY; _impl = new TextureCompositorTexArray( _options ); OE_INFO << LC << "Compositing technique = TEXTURE ARRAY" << std::endl; } #endif // OSG_VERSION_GREATER_OR_EQUAL( 2, 9, 8 ) else if ( _tech == TerrainOptions::COMPOSITING_MULTITEXTURE_FFP || (isAuto && caps.supportsMultiTexture()) ) { _tech = TerrainOptions::COMPOSITING_MULTITEXTURE_FFP; _impl = new TextureCompositorMultiTexture( false, _options ); OE_INFO << LC << "Compositing technique = MULTITEXTURE/FFP" << std::endl; } // Fallback of last resort. The implementation is actually a NO-OP for multipass mode. else { _tech = TerrainOptions::COMPOSITING_MULTIPASS; _impl = 0L; OE_INFO << LC << "Compositing technique = MULTIPASS" << std::endl; } }
GeoImage TextureCompositor::prepareImage | ( | const GeoImage & | image, |
const GeoExtent & | tileExtent | ||
) | const |
Prepares a new image for incorporation into the texture composite. Usually you will call this method when you are updating a single layer AFTER having originally created the stateset (via createStateSet). It is safe to call this method from any thread. You can thereafter take the result and pass it to updateLayer. These two methods are separated so that you can call this one from any thread (it is guaranteed to be thread-safe) and then use updateLayer to updaet a live scene graph if necessary.
Definition at line 374 of file TextureCompositor.cpp.
{ return _impl.valid() ? _impl->prepareImage( image, tileExtent ) : GeoImage::INVALID; }
GeoImage TextureCompositor::prepareSecondaryImage | ( | const GeoImage & | image, |
const GeoExtent & | tileExtent | ||
) | const |
Like prepareImage, but prepares it for use as a secondary texture (for LOD blending).
Definition at line 380 of file TextureCompositor.cpp.
{ return _impl.valid() ? _impl->prepareSecondaryImage( image, tileExtent ) : GeoImage::INVALID; }
void TextureCompositor::releaseTextureImageUnit | ( | int | unit | ) |
Releases a reserved texture image unit previously returned by reserveTextureImageUnit.
Definition at line 346 of file TextureCompositor.cpp.
{ _reservedUnits.erase( unit ); if ( _tech == TerrainOptions::COMPOSITING_MULTITEXTURE_GPU ) { Threading::ScopedWriteLock exclusiveLock( _layoutMutex ); _layout.setReservedSlots( _reservedUnits ); } }
bool TextureCompositor::requiresUnitTextureSpace | ( | ) | const |
Whether the texture composition technique uses a single, unit (0..1) texture coordinate space (true), or a separate texture coordinate space per layer (false). This provides a hint to whomever is generating the texture coordinates as to what they need to do to support the current technique.
Definition at line 409 of file TextureCompositor.cpp.
bool TextureCompositor::reserveTextureImageUnit | ( | int & | out_unit | ) |
Requests a texture image unit that is not in use, and marks is as reserved. You can release the reserved texture image unit by calling releaseTextureImageUnit().
Definition at line 282 of file TextureCompositor.cpp.
{ //todo: move this into the impls!! out_unit = -1; //TODO: this only supports GPU texturing.... unsigned maxUnits = osgEarth::Registry::instance()->getCapabilities().getMaxGPUTextureUnits(); if ( _tech == TerrainOptions::COMPOSITING_MULTITEXTURE_GPU ) { Threading::ScopedWriteLock exclusiveLock( _layoutMutex ); for( unsigned i=0; i<maxUnits; ++i ) { if ( _layout.isSlotAvailable(i) ) { out_unit = i; _reservedUnits.insert( i ); _layout.setReservedSlots( _reservedUnits ); // in multitexture, slots == units return true; } } // all taken, return false. return false; } else if ( _tech == TerrainOptions::COMPOSITING_TEXTURE_ARRAY ) { // texture array reserved slots 0 and 1 (for primary and blending) for( unsigned i=2; i<maxUnits; ++i ) // 0 and 1 always reserved. { if ( _reservedUnits.find( i ) == _reservedUnits.end() ) { out_unit = i; _reservedUnits.insert( i ); return true; } } // all taken, return false. return false; } else // multipass... all image layers are locked at unit 0 { // search for an unused unit. for( unsigned i=1; i<maxUnits; ++i ) // start at 1 because unit 0 is always reserved { if ( _reservedUnits.find( i ) == _reservedUnits.end() ) { out_unit = i; _reservedUnits.insert( i ); return true; } } // all taken, return false. return false; } }
bool TextureCompositor::supportsLayerUpdate | ( | ) | const |
Returns true if the compositor implementation supports the ability to update an individual image layer (via prepareLayerUpdate and applyLayerUpdate).
Definition at line 368 of file TextureCompositor.cpp.
void TextureCompositor::updateMasterStateSet | ( | osg::StateSet * | stateSet | ) | const |
Updates a state set with attributes required to support the technique. Call this whenever the composition of the image layer stack changes in order to update applicable global uniforms, texture attributes, and so forth.
Definition at line 421 of file TextureCompositor.cpp.
{ if ( _impl.valid() ) { Threading::ScopedReadLock sharedLock( const_cast<TextureCompositor*>(this)->_layoutMutex ); _impl->updateMasterStateSet( stateSet, _layout ); } }
bool TextureCompositor::usesShaderComposition | ( | ) | const |
Whether the composition technique uses GLSL shader composition.
Definition at line 415 of file TextureCompositor.cpp.
bool osgEarth::TextureCompositor::_forceTech [private] |
Definition at line 269 of file TextureCompositor.
osg::ref_ptr<TextureCompositorTechnique> osgEarth::TextureCompositor::_impl [private] |
Definition at line 271 of file TextureCompositor.
OpenThreads::Mutex osgEarth::TextureCompositor::_initMutex [private] |
Definition at line 266 of file TextureCompositor.
Definition at line 273 of file TextureCompositor.
Definition at line 274 of file TextureCompositor.
Definition at line 268 of file TextureCompositor.
osg::ref_ptr<osg::Program> osgEarth::TextureCompositor::_program [private] |
Definition at line 270 of file TextureCompositor.
std::set<int> osgEarth::TextureCompositor::_reservedUnits [private] |
Definition at line 276 of file TextureCompositor.
Definition at line 267 of file TextureCompositor.