osgEarth 2.1.1
|
Public Member Functions | |
TextureCompositorMultiTexture (bool useGPU, const TerrainOptions &options) | |
bool | requiresUnitTextureSpace () const |
bool | usesShaderComposition () const |
bool | blendingRequiresSecondarySlot () const |
void | updateMasterStateSet (osg::StateSet *stateSet, const TextureLayout &layout) const |
bool | supportsLayerUpdate () const |
void | applyLayerUpdate (osg::StateSet *stateSet, UID layerUID, const GeoImage &preparedImage, const TileKey &tileExtent, const TextureLayout &layout, osg::StateSet *parentStateSet) const |
osg::Shader * | createSamplerFunction (UID layerUID, const std::string &functionName, osg::Shader::Type type, const TextureLayout &layout) const |
Private Attributes | |
float | _lodTransitionTime |
bool | _useGPU |
bool | _enableMipmappingOnUpdatedTextures |
bool | _enableMipmapping |
Texture compositor that implements multitexturing. It supports either GPU multitexturing (using shaders and taking advantage of all the hardware's resources) or FFP (fixed-function pipeline) multitexturing, which limits you to the old ARB texture unit limit (usually 4).
Definition at line 31 of file TextureCompositorMulti.
TextureCompositorMultiTexture::TextureCompositorMultiTexture | ( | bool | useGPU, |
const TerrainOptions & | options | ||
) |
Definition at line 264 of file TextureCompositorMulti.cpp.
: _lodTransitionTime( *options.lodTransitionTime() ), _enableMipmapping( *options.enableMipmapping() ), _useGPU( useGPU ) { _enableMipmappingOnUpdatedTextures = Registry::instance()->getCapabilities().supportsMipmappedTextureUpdates(); }
void TextureCompositorMultiTexture::applyLayerUpdate | ( | osg::StateSet * | stateSet, |
UID | layerUID, | ||
const GeoImage & | preparedImage, | ||
const TileKey & | tileExtent, | ||
const TextureLayout & | layout, | ||
osg::StateSet * | parentStateSet | ||
) | const [virtual] |
Reimplemented from osgEarth::TextureCompositorTechnique.
Definition at line 273 of file TextureCompositorMulti.cpp.
{ osg::Texture2D* tex = s_getTexture( stateSet, layerUID, layout, parentStateSet); if ( tex ) { osg::Image* image = preparedImage.getImage(); image->dirty(); // required for ensure the texture recognizes the image as new data tex->setImage( image ); // set up proper mipmapping filters: if (_enableMipmapping && _enableMipmappingOnUpdatedTextures && ImageUtils::isPowerOfTwo( image ) && !(!image->isMipmap() && ImageUtils::isCompressed(image)) ) { if ( tex->getFilter(osg::Texture::MIN_FILTER) != osg::Texture::LINEAR_MIPMAP_LINEAR ) tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR ); } else if ( tex->getFilter(osg::Texture::MIN_FILTER) != osg::Texture::LINEAR ) { tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR ); } bool lodBlending = layout.getSlot(layerUID, 1) >= 0; if (_enableMipmapping && _enableMipmappingOnUpdatedTextures && lodBlending ) { int slot = layout.getSlot(layerUID, 0); // update the timestamp on the image layer to support blending. float now = (float)osg::Timer::instance()->delta_s( osg::Timer::instance()->getStartTick(), osg::Timer::instance()->tick() ); ArrayUniform stampUniform( "osgearth_SlotStamp", osg::Uniform::FLOAT, stateSet, layout.getMaxUsedSlot() + 1 ); stampUniform.setElement( slot, now ); // set the texture matrix to properly position the blend (parent) texture osg::Matrix mat; if ( parentStateSet != 0L ) { unsigned tileX, tileY; tileKey.getTileXY(tileX, tileY); mat(0,0) = 0.5f; mat(1,1) = 0.5f; mat(3,0) = (float)(tileX % 2) * 0.5f; mat(3,1) = (float)(1 - tileY % 2) * 0.5f; } ArrayUniform texMatUniform( "osgearth_TexBlendMatrix", osg::Uniform::FLOAT_MAT4, stateSet, layout.getMaxUsedSlot() + 1 ); texMatUniform.setElement( slot, mat ); } } }
bool osgEarth::TextureCompositorMultiTexture::blendingRequiresSecondarySlot | ( | ) | const [inline, virtual] |
Reimplemented from osgEarth::TextureCompositorTechnique.
Definition at line 40 of file TextureCompositorMulti.
{ return true; }
osg::Shader * TextureCompositorMultiTexture::createSamplerFunction | ( | UID | layerUID, |
const std::string & | functionName, | ||
osg::Shader::Type | type, | ||
const TextureLayout & | layout | ||
) | const [virtual] |
Reimplemented from osgEarth::TextureCompositorTechnique.
Definition at line 462 of file TextureCompositorMulti.cpp.
{ osg::Shader* result = 0L; int slot = layout.getSlot( layerUID ); if ( slot >= 0 ) { std::stringstream buf; buf << "uniform sampler2D tex"<< slot << "; \n" << "vec4 " << functionName << "() \n" << "{ \n"; if ( type == osg::Shader::VERTEX ) buf << " return texture2D(tex"<< slot << ", gl_MultiTexCoord"<< slot <<".st); \n"; else buf << " return texture2D(tex"<< slot << ", gl_TexCoord["<< slot << "].st); \n"; buf << "} \n"; std::string str = buf.str(); result = new osg::Shader( type, str ); } return result; }
bool osgEarth::TextureCompositorMultiTexture::requiresUnitTextureSpace | ( | ) | const [inline, virtual] |
Implements osgEarth::TextureCompositorTechnique.
Definition at line 36 of file TextureCompositorMulti.
{ return false; }
bool osgEarth::TextureCompositorMultiTexture::supportsLayerUpdate | ( | ) | const [inline, virtual] |
Reimplemented from osgEarth::TextureCompositorTechnique.
Definition at line 44 of file TextureCompositorMulti.
{ return true; }
void TextureCompositorMultiTexture::updateMasterStateSet | ( | osg::StateSet * | stateSet, |
const TextureLayout & | layout | ||
) | const [virtual] |
Reimplemented from osgEarth::TextureCompositorTechnique.
Definition at line 334 of file TextureCompositorMulti.cpp.
{ int numSlots = layout.getMaxUsedSlot() + 1; int maxUnits = numSlots; if ( _useGPU ) { // Validate against the max number of GPU texture units: if ( maxUnits > Registry::instance()->getCapabilities().getMaxGPUTextureUnits() ) { maxUnits = Registry::instance()->getCapabilities().getMaxGPUTextureUnits(); OE_WARN << LC << "Warning! You have exceeded the number of texture units available on your GPU (" << maxUnits << "). Consider using another compositing mode." << std::endl; } VirtualProgram* vp = static_cast<VirtualProgram*>( stateSet->getAttribute(osg::StateAttribute::PROGRAM) ); if ( maxUnits > 0 ) { // see if we have any blended layers: bool hasBlending = layout.containsSecondarySlots( maxUnits ); vp->setShader( "osgearth_vert_setupTexturing", s_createTextureVertexShader(layout, hasBlending) ); vp->setShader( "osgearth_frag_applyTexturing", s_createTextureFragShaderFunction(layout, maxUnits, hasBlending, _lodTransitionTime ) ); } else { vp->removeShader( "osgearth_frag_applyTexturing", osg::Shader::FRAGMENT ); vp->removeShader( "osgearth_vert_setupTexturing", osg::Shader::VERTEX ); } } else { // Validate against the maximum number of textures available in FFP mode. if ( maxUnits > Registry::instance()->getCapabilities().getMaxFFPTextureUnits() ) { maxUnits = Registry::instance()->getCapabilities().getMaxFFPTextureUnits(); OE_WARN << LC << "Warning! You have exceeded the number of texture units available in fixed-function pipeline " "mode on your graphics hardware (" << maxUnits << "). Consider using another " "compositing mode." << std::endl; } // FFP multitexturing requires that we set up a series of TexCombine attributes: if (maxUnits == 1) { osg::TexEnv* texenv = new osg::TexEnv(osg::TexEnv::MODULATE); stateSet->setTextureAttributeAndModes(0, texenv, osg::StateAttribute::ON); } else if (maxUnits >= 2) { //Blend together the colors and accumulate the alpha values of textures 0 and 1 on unit 0 { osg::TexEnvCombine* texenv = new osg::TexEnvCombine; texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); texenv->setCombine_Alpha(osg::TexEnvCombine::ADD); texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+1); texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); texenv->setSource0_Alpha(osg::TexEnvCombine::TEXTURE0+1); texenv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA); texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+0); texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); texenv->setSource1_Alpha(osg::TexEnvCombine::TEXTURE0+0); texenv->setOperand1_Alpha(osg::TexEnvCombine::SRC_ALPHA); texenv->setSource2_RGB(osg::TexEnvCombine::TEXTURE0+1); texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_ALPHA); stateSet->setTextureAttributeAndModes(0, texenv, osg::StateAttribute::ON); } //For textures 2 and beyond, blend them together with the previous //Add the alpha values of this unit and the previous unit for (int unit = 1; unit < maxUnits-1; ++unit) { osg::TexEnvCombine* texenv = new osg::TexEnvCombine; texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); texenv->setCombine_Alpha(osg::TexEnvCombine::ADD); texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+unit+1); texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); texenv->setSource0_Alpha(osg::TexEnvCombine::TEXTURE0+unit+1); texenv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA); texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); texenv->setSource1_Alpha(osg::TexEnvCombine::PREVIOUS); texenv->setOperand1_Alpha(osg::TexEnvCombine::SRC_ALPHA); texenv->setSource2_RGB(osg::TexEnvCombine::TEXTURE0+unit+1); texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_ALPHA); stateSet->setTextureAttributeAndModes(unit, texenv, osg::StateAttribute::ON); } //Modulate the colors to get proper lighting on the last unit //Keep the alpha results from the previous stage { osg::TexEnvCombine* texenv = new osg::TexEnvCombine; texenv->setCombine_RGB(osg::TexEnvCombine::MODULATE); texenv->setCombine_Alpha(osg::TexEnvCombine::REPLACE); texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); texenv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS); texenv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA); texenv->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR); texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); stateSet->setTextureAttributeAndModes(maxUnits-1, texenv, osg::StateAttribute::ON); } } } }
bool osgEarth::TextureCompositorMultiTexture::usesShaderComposition | ( | ) | const [inline, virtual] |
Implements osgEarth::TextureCompositorTechnique.
Definition at line 38 of file TextureCompositorMulti.
{ return _useGPU; }
bool osgEarth::TextureCompositorMultiTexture::_enableMipmapping [private] |
Definition at line 61 of file TextureCompositorMulti.
Definition at line 60 of file TextureCompositorMulti.
float osgEarth::TextureCompositorMultiTexture::_lodTransitionTime [private] |
Definition at line 58 of file TextureCompositorMulti.
bool osgEarth::TextureCompositorMultiTexture::_useGPU [private] |
Definition at line 59 of file TextureCompositorMulti.