void OSGTerrainEngineNode::updateTextureCombining() { if ( _texCompositor.valid() ) { int numImageLayers = _update_mapf->imageLayers().size(); osg::StateSet* terrainStateSet = _terrain->getOrCreateStateSet(); if ( _texCompositor->usesShaderComposition() ) { // Creates or updates the shader components that are generated by the texture compositor. // These components reside in the CustomTerrain's stateset, and override the components // installed in the VP on the engine-node's stateset in installShaders(). VirtualProgram* vp = new VirtualProgram() ; vp->setName( "engine_osgterrain:TerrainNode" ); vp->installDefaultColoringShaders(numImageLayers); terrainStateSet->setAttributeAndModes( vp, osg::StateAttribute::ON ); // first, update the default shader components based on the new layer count: const ShaderFactory* sf = Registry::instance()->getShaderFactory(); // second, install the per-layer color filter functions. for( int i=0; i<numImageLayers; ++i ) { std::string layerFilterFunc = Stringify() << "osgearth_runColorFilters_" << i; const ColorFilterChain& chain = _update_mapf->getImageLayerAt(i)->getColorFilters(); // install the wrapper function that calls all the filters in turn: vp->setShader( layerFilterFunc, sf->createColorFilterChainFragmentShader(layerFilterFunc, chain) ); // install each of the filter entry points: for( ColorFilterChain::const_iterator j = chain.begin(); j != chain.end(); ++j ) { const ColorFilter* filter = j->get(); filter->install( terrainStateSet ); } } } // next, inform the compositor that it needs to update based on a new layer count: _texCompositor->updateMasterStateSet( terrainStateSet ); //, numImageLayers ); } }
osg::Node* ExtrudeGeometryFilter::push( FeatureList& input, FilterContext& context ) { reset( context ); // minimally, we require an extrusion symbol. if ( !_extrusionSymbol.valid() ) { OE_WARN << LC << "Missing required extrusion symbolology; geometry will be empty" << std::endl; return new osg::Group(); } // establish the active resource library, if applicable. _wallResLib = 0L; _roofResLib = 0L; const StyleSheet* sheet = context.getSession() ? context.getSession()->styles() : 0L; if ( sheet != 0L ) { if ( _wallSkinSymbol.valid() && _wallSkinSymbol->libraryName().isSet() ) { _wallResLib = sheet->getResourceLibrary( *_wallSkinSymbol->libraryName() ); if ( !_wallResLib.valid() ) { OE_WARN << LC << "Unable to load resource library '" << *_wallSkinSymbol->libraryName() << "'" << "; wall geometry will not be textured." << std::endl; _wallSkinSymbol = 0L; } } if ( _roofSkinSymbol.valid() && _roofSkinSymbol->libraryName().isSet() ) { _roofResLib = sheet->getResourceLibrary( *_roofSkinSymbol->libraryName() ); if ( !_roofResLib.valid() ) { OE_WARN << LC << "Unable to load resource library '" << *_roofSkinSymbol->libraryName() << "'" << "; roof geometry will not be textured." << std::endl; _roofSkinSymbol = 0L; } } } // calculate the localization matrices (_local2world and _world2local) computeLocalizers( context ); // push all the features through the extruder. bool ok = process( input, context ); // convert everything to triangles and combine drawables. if ( _mergeGeometry == true && _featureNameExpr.empty() ) { for( SortedGeodeMap::iterator i = _geodes.begin(); i != _geodes.end(); ++i ) { MeshConsolidator::run( *i->second.get() ); } } // parent geometry with a delocalizer (if necessary) osg::Group* group = createDelocalizeGroup(); // combines geometries where the statesets are the same. for( SortedGeodeMap::iterator i = _geodes.begin(); i != _geodes.end(); ++i ) { group->addChild( i->second.get() ); } _geodes.clear(); // if we drew outlines, apply a poly offset too. if ( _outlineSymbol.valid() ) { osg::StateSet* groupStateSet = group->getOrCreateStateSet(); groupStateSet->setAttributeAndModes( new osg::PolygonOffset(1,1), 1 ); if ( _outlineSymbol->stroke()->width().isSet() ) groupStateSet->setAttributeAndModes( new osg::LineWidth(*_outlineSymbol->stroke()->width()), 1 ); } // if we have textures, install a shader to draw them if ( _wallSkinSymbol.valid() || _roofSkinSymbol.valid() ) { osg::StateSet* stateSet = group->getOrCreateStateSet(); VirtualProgram* vp = new VirtualProgram(); vp->setName("ExtrudeGeomFilter"); vp->installDefaultColoringShaders( 1 ); stateSet->setAttributeAndModes( vp, osg::StateAttribute::ON ); // a default empty texture will support any non-textured geometry osg::Texture2D* tex = new osg::Texture2D( ImageUtils::createEmptyImage() ); tex->setUnRefImageDataAfterApply( false ); stateSet->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON); stateSet->getOrCreateUniform("tex0", osg::Uniform::SAMPLER_2D)->set(0); } return group; }