Implement basic cache in ShadeComposer
This commit is contained in:
parent
a55c4b7d70
commit
9f8670f50d
@ -23,6 +23,8 @@ namespace osg {
|
||||
// forward declare osg::State
|
||||
class State;
|
||||
|
||||
typedef std::vector<osg::ShaderComponent*> ShaderComponents;
|
||||
|
||||
class OSG_EXPORT ShaderComposer : public osg::Object
|
||||
{
|
||||
public:
|
||||
@ -31,12 +33,22 @@ class OSG_EXPORT ShaderComposer : public osg::Object
|
||||
ShaderComposer(const ShaderComposer& sa,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
|
||||
META_Object(osg, ShaderComposer)
|
||||
|
||||
osg::Program* getOrCreateProgram() { return 0; }
|
||||
virtual osg::Program* getOrCreateProgram(const ShaderComponents& shaderComponents);
|
||||
|
||||
|
||||
typedef std::vector< const osg::Shader* > Shaders;
|
||||
virtual osg::Shader* composeMain(const Shaders& shaders);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~ShaderComposer();
|
||||
|
||||
typedef std::map< ShaderComponents, ref_ptr<Program> > ProgramMap;
|
||||
ProgramMap _programMap;
|
||||
|
||||
typedef std::map< Shaders, ref_ptr<Shader> > ShaderMainMap;
|
||||
ShaderMainMap _shaderMainMap;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -32,3 +32,109 @@ ShaderComposer::~ShaderComposer()
|
||||
OSG_INFO<<"ShaderComposer::~ShaderComposer() "<<this<<std::endl;
|
||||
}
|
||||
|
||||
osg::Program* ShaderComposer::getOrCreateProgram(const ShaderComponents& shaderComponents)
|
||||
{
|
||||
ProgramMap::iterator itr = _programMap.find(shaderComponents);
|
||||
if (itr != _programMap.end())
|
||||
{
|
||||
OSG_NOTICE<<"ShaderComposer::getOrCreateProgram(..) using cached Program"<<std::endl;
|
||||
return itr->second.get();
|
||||
}
|
||||
|
||||
// strip out vertex shaders
|
||||
Shaders vertexShaders;
|
||||
Shaders geometryShaders;
|
||||
Shaders fragmentShaders;
|
||||
|
||||
for(ShaderComponents::const_iterator itr = shaderComponents.begin();
|
||||
itr != shaderComponents.end();
|
||||
++itr)
|
||||
{
|
||||
const ShaderComponent* sc = *itr;
|
||||
|
||||
for(unsigned int i=0; i<sc->getNumShaders(); ++i)
|
||||
{
|
||||
const Shader* shader = sc->getShader(i);
|
||||
switch(shader->getType())
|
||||
{
|
||||
case(Shader::VERTEX):
|
||||
vertexShaders.push_back(shader);
|
||||
break;
|
||||
case(Shader::GEOMETRY):
|
||||
geometryShaders.push_back(shader);
|
||||
break;
|
||||
case(Shader::FRAGMENT):
|
||||
fragmentShaders.push_back(shader);
|
||||
break;
|
||||
case(Shader::UNDEFINED):
|
||||
OSG_WARN<<"Warning: ShaderCompose::getOrCreateProgam(ShaderComponts) encounterd invalid Shader::Type."<<std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Program> program = new osg::Program;
|
||||
|
||||
if (!vertexShaders.empty())
|
||||
{
|
||||
ShaderMainMap::iterator itr = _shaderMainMap.find(vertexShaders);
|
||||
if (itr == _shaderMainMap.end())
|
||||
{
|
||||
// no vertex shader in map yet, need to compose a new main shader
|
||||
osg::Shader* mainShader = composeMain(vertexShaders);
|
||||
_shaderMainMap[vertexShaders] = mainShader;
|
||||
program->addShader(mainShader);
|
||||
}
|
||||
else
|
||||
{
|
||||
program->addShader(itr->second.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (!geometryShaders.empty())
|
||||
{
|
||||
ShaderMainMap::iterator itr = _shaderMainMap.find(geometryShaders);
|
||||
if (itr == _shaderMainMap.end())
|
||||
{
|
||||
// no vertex shader in map yet, need to compose a new main shader
|
||||
osg::Shader* mainShader = composeMain(geometryShaders);
|
||||
_shaderMainMap[geometryShaders] = mainShader;
|
||||
program->addShader(mainShader);
|
||||
}
|
||||
else
|
||||
{
|
||||
program->addShader(itr->second.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!fragmentShaders.empty())
|
||||
{
|
||||
ShaderMainMap::iterator itr = _shaderMainMap.find(fragmentShaders);
|
||||
if (itr == _shaderMainMap.end())
|
||||
{
|
||||
// no vertex shader in map yet, need to compose a new main shader
|
||||
osg::Shader* mainShader = composeMain(fragmentShaders);
|
||||
_shaderMainMap[fragmentShaders] = mainShader;
|
||||
program->addShader(mainShader);
|
||||
}
|
||||
else
|
||||
{
|
||||
program->addShader(itr->second.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// assign newly created program to map.
|
||||
_programMap[shaderComponents] = program;
|
||||
|
||||
OSG_NOTICE<<"ShaderComposer::getOrCreateProgram(..) created new Program"<<std::endl;
|
||||
|
||||
return program.get();
|
||||
}
|
||||
|
||||
osg::Shader* ShaderComposer::composeMain(const Shaders& shaders)
|
||||
{
|
||||
OSG_NOTICE<<"ShaderComposer::composeMain(Shaders) shaders.size()=="<<shaders.size()<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ State::State():
|
||||
_graphicsContext = 0;
|
||||
_contextID = 0;
|
||||
|
||||
_shaderCompositionEnabled = true;
|
||||
_shaderCompositionEnabled = false; // true;
|
||||
_shaderCompositionDirty = true;
|
||||
_shaderComposer = new ShaderComposer;
|
||||
_currentShaderCompositionProgram = 0L;
|
||||
@ -519,8 +519,9 @@ void State::apply(const StateSet* dstate)
|
||||
{
|
||||
if (_shaderCompositionDirty)
|
||||
{
|
||||
// built lits of current ShaderComponents
|
||||
_currentShaderCompositionProgram = _shaderComposer->getOrCreateProgram();
|
||||
// build lits of current ShaderComponents
|
||||
ShaderComponents shaderComponents;
|
||||
_currentShaderCompositionProgram = _shaderComposer->getOrCreateProgram(shaderComponents);
|
||||
}
|
||||
|
||||
if (_currentShaderCompositionProgram)
|
||||
|
Loading…
Reference in New Issue
Block a user