void VirtualProgram::refreshAccumulatedFunctions( const osg::State& state ) { // This method searches the state's attribute stack and accumulates all // the user functions (including those in this program). Threading::ScopedMutexLock lock( _functionsMutex ); _accumulatedFunctions.clear(); const StateHack::AttributeVec* av = StateHack::GetAttributeVec( state, this ); for( StateHack::AttributeVec::const_iterator i = av->begin(); i != av->end(); ++i ) { const osg::StateAttribute* sa = i->first; const VirtualProgram* vp = dynamic_cast< const VirtualProgram* >( sa ); if( vp && vp != this && ( vp->_mask & _mask ) ) { FunctionLocationMap rhs; vp->getFunctions( rhs ); for( FunctionLocationMap::const_iterator j = rhs.begin(); j != rhs.end(); ++j ) { const OrderedFunctionMap& ofm = j->second; for( OrderedFunctionMap::const_iterator k = ofm.begin(); k != ofm.end(); ++k ) { _accumulatedFunctions[j->first].insert( *k ); } } } } // add the local ones too: for( FunctionLocationMap::const_iterator j = _functions.begin(); j != _functions.end(); ++j ) { const OrderedFunctionMap& ofm = j->second; for( OrderedFunctionMap::const_iterator k = ofm.begin(); k != ofm.end(); ++k ) { _accumulatedFunctions[j->first].insert( *k ); } } }
void VirtualProgram::refreshAccumulatedFunctions( const osg::State& state ) { // This method searches the state's attribute stack and accumulates all // the user functions (including those in this program). // mutex no longer required since this method is called safely //Threading::ScopedMutexLock lock( _functionsMutex ); _accumulatedFunctions.clear(); if ( _inherit ) { const StateHack::AttributeVec* av = StateHack::GetAttributeVec( state, this ); if ( av && av->size() > 0 ) { // find the closest VP that doesn't inherit: unsigned start; for( start = (int)av->size()-1; start > 0; --start ) { const VirtualProgram* vp = dynamic_cast<const VirtualProgram*>( (*av)[start].first ); if ( vp && (vp->_mask & _mask) && vp->_inherit == false ) break; } // collect functions from there on down. for( unsigned i=start; i<av->size(); ++i ) { const VirtualProgram* vp = dynamic_cast<const VirtualProgram*>( (*av)[i].first ); if ( vp && (vp->_mask && _mask) && (vp != this) ) { FunctionLocationMap rhs; vp->getFunctions( rhs ); for( FunctionLocationMap::const_iterator j = rhs.begin(); j != rhs.end(); ++j ) { const OrderedFunctionMap& source = j->second; OrderedFunctionMap& dest = _accumulatedFunctions[j->first]; for( OrderedFunctionMap::const_iterator k = source.begin(); k != source.end(); ++k ) { // remove/override an existing function with the same name for( OrderedFunctionMap::iterator exists = dest.begin(); exists != dest.end(); ++exists ) { if ( exists->second.compare( k->second ) == 0 ) { dest.erase(exists); break; } } dest.insert( *k ); //_accumulatedFunctions[j->first].insert( *k ); } } } } } } // add the local ones too: for( FunctionLocationMap::const_iterator j = _functions.begin(); j != _functions.end(); ++j ) { const OrderedFunctionMap& source = j->second; OrderedFunctionMap& dest = _accumulatedFunctions[j->first]; for( OrderedFunctionMap::const_iterator k = source.begin(); k != source.end(); ++k ) { // remove/override an existing function with the same name for( OrderedFunctionMap::iterator exists = dest.begin(); exists != dest.end(); ++exists ) { if ( exists->second.compare( k->second ) == 0 ) { dest.erase(exists); break; } } dest.insert( *k ); //_accumulatedFunctions[j->first].insert( *k ); } } }