osgEarth 2.1.1
Public Member Functions | Private Attributes

osgEarth::TextureCompositorMultiTexture Class Reference

Inheritance diagram for osgEarth::TextureCompositorMultiTexture:
Collaboration diagram for osgEarth::TextureCompositorMultiTexture:

List of all members.

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

Detailed Description

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.


Constructor & Destructor Documentation

TextureCompositorMultiTexture::TextureCompositorMultiTexture ( bool  useGPU,
const TerrainOptions options 
)

Definition at line 264 of file TextureCompositorMulti.cpp.

Here is the call graph for this function:


Member Function Documentation

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 );
        }
    }
}

Here is the call graph for this function:

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;
}

Here is the call graph for this function:

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);
            }
        }
    }
}

Here is the call graph for this function:

bool osgEarth::TextureCompositorMultiTexture::usesShaderComposition ( ) const [inline, virtual]

Implements osgEarth::TextureCompositorTechnique.

Definition at line 38 of file TextureCompositorMulti.

{ return _useGPU; }

Member Data Documentation

Definition at line 61 of file TextureCompositorMulti.

Definition at line 60 of file TextureCompositorMulti.

Definition at line 58 of file TextureCompositorMulti.

Definition at line 59 of file TextureCompositorMulti.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines