|
osgEarth 2.1.1
|
Inheritance diagram for osgEarth::TextureCompositorMultiTexture:
Collaboration diagram for osgEarth::TextureCompositorMultiTexture: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(); }
Here is the call graph for this function:| 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; }
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.
1.7.3