osgEarth 2.1.1
Functions

anonymous_namespace{TextureCompositorMulti.cpp} Namespace Reference

Functions

static osg::Shader * s_createTextureVertexShader (const TextureLayout &layout, bool blending)
static osg::Shader * s_createTextureFragShaderFunction (const TextureLayout &layout, int maxSlots, bool blending, float fadeInDuration)
static std::string makeSamplerName (int slot)
static osg::Texture2D * s_getTexture (osg::StateSet *stateSet, UID layerUID, const TextureLayout &layout, osg::StateSet *parentStateSet)

Function Documentation

static std::string anonymous_namespace{TextureCompositorMulti.cpp}::makeSamplerName ( int  slot) [static]

Definition at line 188 of file TextureCompositorMulti.cpp.

    {
        std::stringstream buf;
        buf << "tex" << slot;
        return buf.str();
    }

Here is the caller graph for this function:

static osg::Shader* anonymous_namespace{TextureCompositorMulti.cpp}::s_createTextureFragShaderFunction ( const TextureLayout layout,
int  maxSlots,
bool  blending,
float  fadeInDuration 
) [static]

Definition at line 82 of file TextureCompositorMulti.cpp.

    {
        const TextureLayout::RenderOrderVector& order = layout.getRenderOrder();

        std::stringstream buf;

        buf << "#version 120 \n";

        if ( blending )
        {
            buf << "#extension GL_ARB_shader_texture_lod : enable \n"
                << "uniform float osgearth_SlotStamp[" << maxSlots << "]; \n"
                << "uniform float osg_FrameTime; \n"
                << "uniform float osgearth_LODRangeFactor; \n";
        }

        buf << "uniform float osgearth_ImageLayerOpacity[" << maxSlots << "]; \n"
            //The enabled array is a fixed size.  Make sure this corresponds to the size definition in TerrainEngineNode.cpp
            << "uniform bool  osgearth_ImageLayerEnabled[" << 16 << "]; \n"  
            << "uniform float osgearth_ImageLayerRange[" << 2 * maxSlots << "]; \n"
            << "uniform float osgearth_ImageLayerAttenuation; \n"
            << "uniform float osgearth_CameraElevation; \n"
            << "varying float osgearth_CameraRange; \n";

        const TextureLayout::TextureSlotVector& slots = layout.getTextureSlots();

        for( int i = 0; i < maxSlots && i < (int)slots.size(); ++i )
        {
            if ( slots[i] >= 0 )
            {
                buf << "uniform sampler2D tex" << i << ";\n";
            }
        }

        buf << "void osgearth_frag_applyTexturing( inout vec4 color ) \n"
            << "{ \n"
            << "    vec3 color3 = color.rgb; \n"
            << "    vec4 texel; \n"
            << "    float maxOpacity = 0.0; \n"
            << "    float dmin, dmax, atten_min, atten_max, age; \n";           

        for( unsigned int i=0; i < order.size(); ++i )
        {
            int slot = order[i];
            int q = 2 * i;

            // if this UID has a secondyar slot, LOD blending ON.
            int secondarySlot = layout.getSlot( slots[slot], 1, maxSlots );

            buf << "    if (osgearth_ImageLayerEnabled["<< i << "]) { \n"
                << "        dmin = osgearth_CameraElevation - osgearth_ImageLayerRange["<< q << "]; \n"
                << "        dmax = osgearth_CameraElevation - osgearth_ImageLayerRange["<< q+1 <<"]; \n"

                << "        if (dmin >= 0 && dmax <= 0.0) { \n"
                << "            atten_max = -clamp( dmax, -osgearth_ImageLayerAttenuation, 0 ) / osgearth_ImageLayerAttenuation; \n"
                << "            atten_min =  clamp( dmin, 0, osgearth_ImageLayerAttenuation ) / osgearth_ImageLayerAttenuation; \n";

            if ( secondarySlot >= 0 ) // LOD blending enabled for this layer
            {
                float invFadeInDuration = 1.0f/fadeInDuration;

                buf << "            age = "<< invFadeInDuration << " * min( "<< fadeInDuration << ", osg_FrameTime - osgearth_SlotStamp[" << slot << "] ); \n"
                    << "            age = clamp(age, 0.0, 1.0); \n"
                    << "            vec4 texel0 = texture2D(tex" << slot << ", gl_TexCoord["<< slot << "].st);\n"
                    << "            vec4 texel1 = texture2D(tex" << secondarySlot << ", gl_TexCoord["<< secondarySlot << "].st);\n"
                    << "            float mixval = age * osgearth_LODRangeFactor;\n"

                    // pre-multiply alpha before mixing:
                    << "            texel0.rgb *= texel0.a; \n"
                    << "            texel1.rgb *= texel1.a; \n"
                    << "            texel = mix(texel1, texel0, mixval); \n"

                    // revert to non-pre-multiplies alpha (assumes openGL state uses non-pre-mult alpha)
                    << "            if (texel.a > 0.0) { \n"
                    << "                texel.rgb /= texel.a; \n"
                    << "            } \n";
            }
            else
            {
                buf << "            texel = texture2D(tex" << slot << ", gl_TexCoord["<< slot <<"].st); \n";
            }
            
            buf << "            float opacity =  texel.a * osgearth_ImageLayerOpacity[" << i << "];\n"
                << "            color3 = mix(color3, texel.rgb, opacity * atten_max * atten_min); \n"
                << "            if (opacity > maxOpacity) {\n"
                << "              maxOpacity = opacity;\n"
                << "            }\n"                
                << "        } \n"
                << "    } \n";
        }
        
            buf << "    color = vec4(color3, maxOpacity);\n"
                << "} \n";



        std::string str = buf.str();
        //OE_INFO << std::endl << str;
        return new osg::Shader( osg::Shader::FRAGMENT, str );
    }

Here is the call graph for this function:

Here is the caller graph for this function:

static osg::Shader* anonymous_namespace{TextureCompositorMulti.cpp}::s_createTextureVertexShader ( const TextureLayout layout,
bool  blending 
) [static]

Definition at line 38 of file TextureCompositorMulti.cpp.

    {
        std::stringstream buf;
       
        const TextureLayout::TextureSlotVector& slots = layout.getTextureSlots();

        if ( blending )
        {
            buf << "uniform mat4 osgearth_TexBlendMatrix[" << slots.size() << "];\n";
        }

        buf << "void osgearth_vert_setupTexturing() \n"
            << "{ \n";

        // Set up the texture coordinates for each active slot (primary and secondary).
        // Primary slots are the actual image layer's texture image unit. A Secondary
        // slot is what an image layer uses for LOD blending, and is set on a per-layer basis.
        for( int slot = 0; slot < (int)slots.size(); ++slot )
        {
            if ( slots[slot] >= 0 )
            {
                UID uid = slots[slot];
                int primarySlot = layout.getSlot(uid, 0);

                if ( slot == primarySlot )
                {
                    // normal unit:
                    buf << "    gl_TexCoord["<< slot <<"] = gl_MultiTexCoord" << slot << ";\n";
                }
                else
                {
                    // secondary (blending) unit:
                    buf << "    gl_TexCoord["<< slot <<"] = osgearth_TexBlendMatrix["<< primarySlot << "] * gl_MultiTexCoord" << primarySlot << ";\n";
                }
            }
        }
            
        buf << "} \n";

        std::string str = buf.str();
        return new osg::Shader( osg::Shader::VERTEX, str );
    }

Here is the call graph for this function:

Here is the caller graph for this function:

static osg::Texture2D* anonymous_namespace{TextureCompositorMulti.cpp}::s_getTexture ( osg::StateSet *  stateSet,
UID  layerUID,
const TextureLayout layout,
osg::StateSet *  parentStateSet 
) [static]

Definition at line 196 of file TextureCompositorMulti.cpp.

    {
        int slot = layout.getSlot( layerUID, 0 );
        if ( slot < 0 )
            return 0L;

        osg::Texture2D* tex = static_cast<osg::Texture2D*>(
            stateSet->getTextureAttribute( slot, osg::StateAttribute::TEXTURE ) );

        if ( !tex )
        {
            tex = new osg::Texture2D();

            // configure the mipmapping

            tex->setMaxAnisotropy( 16.0f );

            tex->setResizeNonPowerOfTwoHint(false);
            tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
            tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );

            // configure the wrapping
            tex->setWrap( osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE );
            tex->setWrap( osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE );

            stateSet->setTextureAttributeAndModes( slot, tex, osg::StateAttribute::ON );
            
            // install the slot attribute
            std::string name = makeSamplerName(slot);
            stateSet->getOrCreateUniform( name.c_str(), osg::Uniform::SAMPLER_2D )->set( slot );
        }

        // see if we need an LOD blending secondary texture:
        int secondarySlot = layout.getSlot( layerUID, 1 );
        if ( secondarySlot >= 0 )
        {
            osg::Texture2D* parentTex = 0;

            //int parentSlot = slot + layout.getRenderOrder().size();
            std::string parentSampler = makeSamplerName( secondarySlot );
            if (parentStateSet)
            {
                parentTex = static_cast<osg::Texture2D*>(
                    parentStateSet->getTextureAttribute( slot, osg::StateAttribute::TEXTURE ) );

                if (parentTex)
                {
                    stateSet->setTextureAttributeAndModes(secondarySlot, parentTex, osg::StateAttribute::ON );
                    stateSet->getOrCreateUniform(parentSampler.c_str(),
                                                 osg::Uniform::SAMPLER_2D )->set( secondarySlot );
                }
            }

            if ( !parentTex )
            {
                // Bind the main texture as the secondary texture and
                // set the scaling factors appropriately.
                stateSet->getOrCreateUniform(
                    parentSampler.c_str(), osg::Uniform::SAMPLER_2D)->set(slot);
            }

        }
        return tex;
    }

Here is the call graph for this function:

Here is the caller graph for this function:

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines