osgEarth 2.1.1
|
Public Member Functions | |
void | setFunction (const std::string &name, const std::string &source, ShaderComp::FunctionLocation loc, float priority=1.0f) |
VirtualProgram (unsigned int mask=0xFFFFFFFFUL) | |
VirtualProgram (const VirtualProgram &VirtualProgram, const osg::CopyOp ©op=osg::CopyOp::SHALLOW_COPY) | |
META_StateAttribute (osgEarth, VirtualProgram, Type(PROGRAM)) virtual int compare(const StateAttribute &sa) const | |
virtual void | apply (osg::State &state) const |
osg::Shader * | getShader (const std::string &shaderSemantic, osg::Shader::Type type) |
osg::Shader * | setShader (const std::string &shaderSemantic, osg::Shader *shader) |
void | removeShader (const std::string &shaderSemantic, osg::Shader::Type type) |
void | getFunctions (ShaderComp::FunctionLocationMap &out) const |
Protected Types | |
typedef std::vector < osg::ref_ptr< osg::Shader > > | ShaderList |
typedef std::pair< std::string, osg::Shader::Type > | ShaderSemantic |
typedef std::map < ShaderSemantic, osg::ref_ptr < osg::Shader > > | ShaderMap |
typedef std::map< ShaderList, osg::ref_ptr< osg::Program > > | ProgramMap |
Protected Member Functions | |
bool | hasLocalFunctions () const |
void | refreshAccumulatedFunctions (const osg::State &state) |
Protected Attributes | |
ProgramMap | _programMap |
ShaderMap | _shaderMap |
unsigned int | _mask |
ShaderComp::FunctionLocationMap | _functions |
ShaderComp::FunctionLocationMap | _accumulatedFunctions |
Threading::Mutex | _functionsMutex |
VirtualProgram enables basic GLSL shader composition within osgEarth.
VirtualProgram has been adapted from the VirtualProgram shader composition work originally done by Wojciech Lewandowski and found in OSG's osgvirtualprogram example, and is used by permission.
Definition at line 105 of file ShaderComposition.
typedef std::map< ShaderList, osg::ref_ptr<osg::Program> > osgEarth::VirtualProgram::ProgramMap [protected] |
Definition at line 160 of file ShaderComposition.
typedef std::vector< osg::ref_ptr< osg::Shader > > osgEarth::VirtualProgram::ShaderList [protected] |
Definition at line 157 of file ShaderComposition.
typedef std::map< ShaderSemantic, osg::ref_ptr<osg::Shader> > osgEarth::VirtualProgram::ShaderMap [protected] |
Definition at line 159 of file ShaderComposition.
typedef std::pair< std::string, osg::Shader::Type > osgEarth::VirtualProgram::ShaderSemantic [protected] |
Definition at line 158 of file ShaderComposition.
VirtualProgram::VirtualProgram | ( | unsigned int | mask = 0xFFFFFFFFUL | ) |
Definition at line 65 of file ShaderComposition.cpp.
: _mask( mask ) { // because we sometimes update/change the attribute's members from within the apply() method this->setDataVariance( osg::Object::DYNAMIC ); }
VirtualProgram::VirtualProgram | ( | const VirtualProgram & | VirtualProgram, |
const osg::CopyOp & | copyop = osg::CopyOp::SHALLOW_COPY |
||
) |
Definition at line 72 of file ShaderComposition.cpp.
: osg::Program( rhs, copyop ), _shaderMap( rhs._shaderMap ), _mask( rhs._mask ), _functions( rhs._functions ) { //nop }
void VirtualProgram::apply | ( | osg::State & | state | ) | const [virtual] |
If enabled, activate our program in the GL pipeline, performing any rebuild operations that might be pending.
Definition at line 136 of file ShaderComposition.cpp.
{ if( _shaderMap.empty() ) // Virtual Program works as normal Program return Program::apply( state ); // first, find and collect all the VirtualProgram attributes: ShaderMap shaderMap; const StateHack::AttributeVec* av = StateHack::GetAttributeVec( state, this ); if ( av ) { 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->_mask & _mask ) ) { for( ShaderMap::const_iterator i = vp->_shaderMap.begin(); i != vp->_shaderMap.end(); ++i ) { shaderMap[ i->first ] = i->second; } } } } // next add the local shader components to the map: for( ShaderMap::const_iterator i = _shaderMap.begin(); i != _shaderMap.end(); ++i ) shaderMap[ i->first ] = i->second; if( shaderMap.size() ) { // next, assemble a list of the shaders in the map so we can compare it: ShaderList sl; for( ShaderMap::iterator i = shaderMap.begin(); i != shaderMap.end(); ++i ) sl.push_back( i->second ); // see if there's already a program associated with this list: osg::Program* program = 0L; ProgramMap::iterator p = _programMap.find( sl ); if ( p != _programMap.end() ) { program = p->second.get(); } else { ShaderFactory* sf = osgEarth::Registry::instance()->getShaderFactory(); // build a new set of accumulated functions, to support the creation of main() const_cast<VirtualProgram*>(this)->refreshAccumulatedFunctions( state ); osg::Shader* vert_main = sf->createVertexShaderMain( _accumulatedFunctions ); const_cast<VirtualProgram*>(this)->setShader( "osgearth_vert_main", vert_main ); shaderMap[ ShaderSemantic("osgearth_vert_main", osg::Shader::VERTEX) ] = vert_main; osg::Shader* frag_main = sf->createFragmentShaderMain( _accumulatedFunctions ); const_cast<VirtualProgram*>(this)->setShader( "osgearth_frag_main", frag_main ); shaderMap[ ShaderSemantic("osgearth_frag_main", osg::Shader::FRAGMENT) ] = frag_main; // rebuild the shader list now that we've changed the shader map. sl.clear(); for( ShaderMap::iterator i = shaderMap.begin(); i != shaderMap.end(); ++i ) sl.push_back( i->second ); // Create a new program and add all our shaders. program = new osg::Program(); #if !MERGE_SHADERS for( ShaderList::iterator i = sl.begin(); i != sl.end(); ++i ) { program->addShader( i->get() ); } #else std::string strFragment; std::string strVertex; std::string strGeometry; for( ShaderList::iterator i = sl.begin(); i != sl.end(); ++i ) { if( i->get()->getType() == osg::Shader::FRAGMENT ) strFragment += i->get()->getShaderSource(); else if ( i->get()->getType() == osg::Shader::VERTEX ) strVertex += i->get()->getShaderSource(); else if ( i->get()->getType() == osg::Shader::GEOMETRY ) strGeometry += i->get()->getShaderSource(); } if( strFragment.length() > 0 ) { program->addShader( new osg::Shader( osg::Shader::FRAGMENT, strFragment ) ); } if( strVertex.length() > 0 ) { program->addShader( new osg::Shader( osg::Shader::VERTEX, strVertex ) ); } if( strGeometry.length() > 0 ) { program->addShader( new osg::Shader( osg::Shader::GEOMETRY, strGeometry ) ); } #endif // finally, cache the program so we only regenerate it when it changes. _programMap[ sl ] = program; } // finally, apply the program attribute. program->apply( state ); } else { Program::apply( state ); } }
void VirtualProgram::getFunctions | ( | ShaderComp::FunctionLocationMap & | out | ) | const |
Definition at line 250 of file ShaderComposition.cpp.
{ Threading::ScopedMutexLock lock( const_cast<VirtualProgram*>(this)->_functionsMutex ); out = _functions; }
osg::Shader * VirtualProgram::getShader | ( | const std::string & | shaderSemantic, |
osg::Shader::Type | type | ||
) |
Definition at line 82 of file ShaderComposition.cpp.
{ ShaderMap::key_type key( shaderSemantic, type ); return _shaderMap[ key ].get(); }
bool osgEarth::VirtualProgram::hasLocalFunctions | ( | ) | const [protected] |
osgEarth::VirtualProgram::META_StateAttribute | ( | osgEarth | , |
VirtualProgram | , | ||
Type(PROGRAM) | |||
) | const [inline] |
return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.
Definition at line 130 of file ShaderComposition.
{ // check the types are equal and then create the rhs variable // used by the COMPARE_StateAttribute_Parameter macros below. COMPARE_StateAttribute_Types(VirtualProgram,sa) // compare each parameter in turn against the rhs. COMPARE_StateAttribute_Parameter(_mask) COMPARE_StateAttribute_Parameter(_shaderMap) return 0; // passed all the above comparison macros, must be equal. }
void VirtualProgram::refreshAccumulatedFunctions | ( | const osg::State & | state | ) | [protected] |
Definition at line 257 of file ShaderComposition.cpp.
{ // 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::removeShader | ( | const std::string & | shaderSemantic, |
osg::Shader::Type | type | ||
) |
Definition at line 127 of file ShaderComposition.cpp.
{ _shaderMap.erase( ShaderMap::key_type( shaderSemantic, type ) ); }
void VirtualProgram::setFunction | ( | const std::string & | name, |
const std::string & | source, | ||
ShaderComp::FunctionLocation | loc, | ||
float | priority = 1.0f |
||
) |
Adds a shader function to the program. Call this method (rather than setShader directly) to inject "user" functions into the shader program.
name: name of the function. This should be the actual function name in the shader source. source: the shader source code. location: Function location relative to the built-ins. priority: Lets you control the order of functions that you inject at the same location.
Definition at line 112 of file ShaderComposition.cpp.
{ Threading::ScopedMutexLock lock( _functionsMutex ); OrderedFunctionMap& ofm = _functions[location]; ofm.insert( std::pair<float,std::string>( priority, functionName ) ); osg::Shader::Type type = (int)location <= (int)LOCATION_VERTEX_POST_LIGHTING ? osg::Shader::VERTEX : osg::Shader::FRAGMENT; setShader( functionName, new osg::Shader( type, shaderSource ) ); }
osg::Shader * VirtualProgram::setShader | ( | const std::string & | shaderSemantic, |
osg::Shader * | shader | ||
) |
Definition at line 89 of file ShaderComposition.cpp.
{ if( shader->getType() == osg::Shader::UNDEFINED ) return NULL; ShaderMap::key_type key( shaderSemantic, shader->getType() ); osg::ref_ptr< osg::Shader > shaderNew = shader; osg::ref_ptr< osg::Shader >& shaderCurrent = _shaderMap[ key ]; shaderNew->setName( shaderSemantic ); if( shaderCurrent != shaderNew ) { shaderCurrent = shaderNew; } //OE_NOTICE << shader->getShaderSource() << std::endl; return shaderCurrent.get(); }
Definition at line 167 of file ShaderComposition.
Definition at line 166 of file ShaderComposition.
Definition at line 169 of file ShaderComposition.
unsigned int osgEarth::VirtualProgram::_mask [protected] |
Definition at line 164 of file ShaderComposition.
ProgramMap osgEarth::VirtualProgram::_programMap [mutable, protected] |
Definition at line 162 of file ShaderComposition.
ShaderMap osgEarth::VirtualProgram::_shaderMap [protected] |
Definition at line 163 of file ShaderComposition.