From c665fdc973233370e274017d6cd3ca40b7380ce0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Dec 2010 12:16:57 +0000 Subject: [PATCH] Form Richard Schmidt, "The following features were added: * the glsl plugin now supports processing #includes. The file extension sets the shader type. * the registry releases gl objects of the shared state manager " --- include/osgDB/SharedStateManager | 2 + src/osgDB/Registry.cpp | 5 ++ src/osgDB/SharedStateManager.cpp | 27 ++++++++++ src/osgPlugins/glsl/ReaderWriterGLSL.cpp | 69 +++++++++++++++++++----- 4 files changed, 89 insertions(+), 14 deletions(-) diff --git a/include/osgDB/SharedStateManager b/include/osgDB/SharedStateManager index 7c544ee7c..bfd113b11 100644 --- a/include/osgDB/SharedStateManager +++ b/include/osgDB/SharedStateManager @@ -70,6 +70,8 @@ namespace osgDB { bool isShared(osg::Texture* texture); + void releaseGLObjects(osg::State* state ) const; + protected: inline bool shareTexture(osg::Object::DataVariance variance) diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 8e9a609c0..84ab3ea44 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -1563,6 +1563,11 @@ void Registry::releaseGLObjects(osg::State* state) osg::Object* object = itr->second.first.get(); object->releaseGLObjects(state); } + + if (_sharedStateManager.valid()) + { + _sharedStateManager->releaseGLObjects( state ); + } } SharedStateManager* Registry::getOrCreateSharedStateManager() diff --git a/src/osgDB/SharedStateManager.cpp b/src/osgDB/SharedStateManager.cpp index 593c7816d..ba8e6294d 100644 --- a/src/osgDB/SharedStateManager.cpp +++ b/src/osgDB/SharedStateManager.cpp @@ -283,3 +283,30 @@ void SharedStateManager::process(osg::StateSet* ss, osg::Object* parent) shareTextures(ss); } } + +void SharedStateManager::releaseGLObjects(osg::State* state) const +{ + OpenThreads::ScopedLock lock(_listMutex); + + { + TextureSet::const_iterator it; + for ( it = _sharedTextureList.begin(); it != _sharedTextureList.end(); ++it ) + { + if ( it->valid() ) + { + it->get()->releaseGLObjects(state); + } + } + } + + { + StateSetSet::const_iterator it; + for( it = _sharedStateSetList.begin(); it != _sharedStateSetList.end(); ++it ) + { + if ( it->valid() ) + { + it->get()->releaseGLObjects(state); + } + } + } +} diff --git a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp index 284d7878f..f1534688e 100644 --- a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp +++ b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,6 +6,7 @@ #include #include #include +#include #include @@ -23,19 +25,61 @@ class ReaderWriterGLSL : public osgDB::ReaderWriter virtual const char* className() const { return "GLSL Shader Reader"; } + osg::Shader* processIncludes( const osg::Shader* shader, const Options* options ) const + { + std::string code = shader->getShaderSource(); + + std::string::size_type pos = 0; + + static std::string::size_type includeLen = 8; + + while( ( pos = code.find( "#include", pos ) ) != std::string::npos ) + { + // we found an include + std::string::size_type pos2 = code.find_first_not_of( " ", pos + includeLen ); + + if ( ( pos2 == std::string::npos ) || ( code[ pos2 ] != '\"' ) ) + { + // error, bail out + return NULL; + } + + // we found an " + std::string::size_type pos3 = code.find( "\"", pos2 + 1 ); + + if ( pos3 == std::string::npos ) + { + return NULL; + } + + const std::string filename = code.substr( pos2 + 1, pos3 - pos2 - 1 ); + + osg::ref_ptr innerShader = osgDB::readShaderFile( shader->getType(), filename, options ); + + if ( !innerShader.valid() ) + { + return NULL; + } + + code.replace( pos, pos3 - pos + 1, innerShader->getShaderSource() ); + + pos += innerShader->getShaderSource().size(); + } + + return new osg::Shader( shader->getType(), code ); + } + + virtual ReadResult readShader(std::istream& fin,const Options* options) const { - // read source - fin.seekg(0, std::ios::end); - int length = fin.tellg(); - char *text = new char[length + 1]; - fin.seekg(0, std::ios::beg); - fin.read(text, length); - text[length] = '\0'; - // create shader - osg::Shader* shader = new osg::Shader(); - shader->setShaderSource( text ); + osg::ref_ptr shader = new osg::Shader(); + + { + std::stringstream ss; + ss << fin.rdbuf(); + shader->setShaderSource( ss.str() ); + } // check options which can define the type of the shader program if (options) @@ -45,11 +89,8 @@ class ReaderWriterGLSL : public osgDB::ReaderWriter if (options->getOptionString().find("geometry")!=std::string::npos) shader->setType(osg::Shader::GEOMETRY); } - // cleanup - delete [] text; - // return valid shader - return shader; + return processIncludes( shader.get(), options ); } virtual ReadResult readShader(const std::string& file, const osgDB::ReaderWriter::Options* options) const