From Per Fahlberg, "Attached is a fix allowing removal of shaders from a program after it is
first compiled. It will also allow new shaders to be attached after the program is first compiled."
This commit is contained in:
@@ -203,6 +203,16 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
||||
inline GLint getUniformLocation( const std::string& name ) const { ActiveVarInfoMap::const_iterator itr = _uniformInfoMap.find(name); return (itr!=_uniformInfoMap.end()) ? itr->second._location : -1; }
|
||||
inline GLint getAttribLocation( const std::string& name ) const { ActiveVarInfoMap::const_iterator itr = _attribInfoMap.find(name); return (itr!=_attribInfoMap.end()) ? itr->second._location : -1; }
|
||||
|
||||
inline void addShaderToAttach(Shader *shader)
|
||||
{
|
||||
_shadersToAttach.push_back(shader);
|
||||
}
|
||||
|
||||
inline void addShaderToDetach(Shader *shader)
|
||||
{
|
||||
_shadersToDetach.push_back(shader);
|
||||
}
|
||||
|
||||
protected: /*methods*/
|
||||
~PerContextProgram();
|
||||
|
||||
@@ -225,6 +235,10 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
||||
typedef std::pair<const osg::Uniform*, unsigned int> UniformModifiedCountPair;
|
||||
typedef std::vector<UniformModifiedCountPair> LastAppliedUniformList;
|
||||
mutable LastAppliedUniformList _lastAppliedUniformList;
|
||||
|
||||
typedef std::vector< ref_ptr<Shader> > ShaderList;
|
||||
ShaderList _shadersToDetach;
|
||||
ShaderList _shadersToAttach;
|
||||
|
||||
private:
|
||||
PerContextProgram(); // disallowed
|
||||
@@ -247,7 +261,6 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
||||
typedef std::vector< ref_ptr<Shader> > ShaderList;
|
||||
ShaderList _shaderList;
|
||||
|
||||
|
||||
private:
|
||||
Program& operator=(const Program&); // disallowed
|
||||
};
|
||||
|
||||
@@ -99,6 +99,9 @@ class OSG_EXPORT Shader : public osg::Object
|
||||
/** For a given GL context, attach a glShader to a glProgram */
|
||||
void attachShader(unsigned int contextID, GLuint program) const;
|
||||
|
||||
/** For a given GL context, detach a glShader to a glProgram */
|
||||
void detachShader(unsigned int contextID, GLuint program) const;
|
||||
|
||||
/** Query InfoLog from a glShader */
|
||||
bool getGlShaderInfoLog(unsigned int contextID, std::string& log) const;
|
||||
|
||||
|
||||
@@ -2100,6 +2100,12 @@ bool Program::addShader( Shader* shader )
|
||||
if( shader == _shaderList[i].get() ) return false;
|
||||
}
|
||||
|
||||
// Add shader to PCPs
|
||||
for( unsigned int cxt=0; cxt < _pcpList.size(); ++cxt )
|
||||
{
|
||||
if( _pcpList[cxt].valid() ) _pcpList[cxt]->addShaderToAttach( shader );
|
||||
}
|
||||
|
||||
shader->addProgramRef( this );
|
||||
_shaderList.push_back( shader );
|
||||
dirtyProgram();
|
||||
@@ -2118,12 +2124,20 @@ bool Program::removeShader( Shader* shader )
|
||||
{
|
||||
if( shader == itr->get() )
|
||||
{
|
||||
// Remove shader from PCPs
|
||||
for( unsigned int cxt=0; cxt < _pcpList.size(); ++cxt )
|
||||
{
|
||||
if( _pcpList[cxt].valid() ) _pcpList[cxt]->addShaderToDetach( shader );
|
||||
}
|
||||
|
||||
shader->removeProgramRef( this );
|
||||
_shaderList.erase(itr);
|
||||
|
||||
dirtyProgram();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2196,9 +2210,10 @@ Program::PerContextProgram* Program::getPCP(unsigned int contextID) const
|
||||
// attach all PCSs to this new PCP
|
||||
for( unsigned int i=0; i < _shaderList.size(); ++i )
|
||||
{
|
||||
_shaderList[i]->attachShader( contextID, _pcpList[contextID]->getHandle() );
|
||||
_pcpList[contextID]->addShaderToAttach( _shaderList[i].get() );
|
||||
}
|
||||
}
|
||||
|
||||
return _pcpList[contextID].get();
|
||||
}
|
||||
|
||||
@@ -2266,6 +2281,20 @@ void Program::PerContextProgram::linkProgram()
|
||||
<< " contextID=" << _contextID
|
||||
<< std::endl;
|
||||
|
||||
// Detach removed shaders
|
||||
for( unsigned int i=0; i < _shadersToDetach.size(); ++i )
|
||||
{
|
||||
_shadersToDetach[i]->detachShader( _contextID, _glProgramHandle );
|
||||
}
|
||||
_shadersToDetach.clear();
|
||||
|
||||
// Attach new shaders
|
||||
for( unsigned int i=0; i < _shadersToAttach.size(); ++i )
|
||||
{
|
||||
_shadersToAttach[i]->attachShader( _contextID, _glProgramHandle );
|
||||
}
|
||||
_shadersToAttach.clear();
|
||||
|
||||
_uniformInfoMap.clear();
|
||||
_attribInfoMap.clear();
|
||||
_lastAppliedUniformList.clear();
|
||||
|
||||
@@ -240,6 +240,12 @@ void Shader::attachShader(unsigned int contextID, GLuint program) const
|
||||
if( pcs ) pcs->attachShader( program );
|
||||
}
|
||||
|
||||
void Shader::detachShader(unsigned int contextID, GLuint program) const
|
||||
{
|
||||
PerContextShader* pcs = getPCS( contextID );
|
||||
if( pcs ) pcs->detachShader( program );
|
||||
}
|
||||
|
||||
|
||||
bool Shader::getGlShaderInfoLog(unsigned int contextID, std::string& log) const
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user