From Art Trevs, add support for saving external shader files.

From Robert Osfield, adding missing member variable initializes and Output::getShaderFileNameForOutput() implementation
This commit is contained in:
Robert Osfield
2008-03-04 14:04:48 +00:00
parent 02b52cb73a
commit c4d07194a2
22 changed files with 515 additions and 19 deletions

View File

@@ -83,6 +83,12 @@ class OSG_EXPORT Shader : public osg::Object
/** Get the Shader type as a descriptive string. */
const char* getTypename() const;
/** Set file name for the shader source code. */
inline void setFileName(const std::string& fileName) { _shaderFileName = fileName; }
/** Get filename to which the shader source code belongs. */
inline const std::string& getFileName() const { return _shaderFileName; }
/** Resize any per context GLObject buffers to specified size. */
virtual void resizeGLObjectBuffers(unsigned int maxSize);
@@ -178,6 +184,7 @@ class OSG_EXPORT Shader : public osg::Object
protected: /*data*/
Type _type;
std::string _shaderSource;
std::string _shaderFileName;
/** osg::Programs that this osg::Shader is attached to */
typedef std::set< osg::Program* > ProgramSet;
ProgramSet _programSet;

View File

@@ -15,6 +15,7 @@
#define OSGDB_INPUT 1
#include <osg/Image>
#include <osg/Shader>
#include <osg/Node>
#include <osg/Drawable>
#include <osg/StateAttribute>
@@ -50,10 +51,12 @@ class OSGDB_EXPORT Input : public FieldReaderIterator
virtual osg::StateAttribute* readStateAttribute();
virtual osg::Uniform* readUniform();
virtual osg::Node* readNode();
virtual osg::Shader* readShader();
virtual osg::Object* readObject(const std::string& fileName);
virtual osg::Image* readImage(const std::string& fileName);
virtual osg::Node* readNode(const std::string& fileName);
virtual osg::Shader* readShader(const std::string& fileName);
virtual osg::Object* getObjectForUniqueID(const std::string& uniqueID);
virtual void registerUniqueIDForObject(const std::string& uniqueID,osg::Object* obj);

View File

@@ -92,6 +92,11 @@ class OSGDB_EXPORT Output : public std::ofstream
bool getOutputTextureFiles() const { return _outputTextureFiles; }
virtual std::string getTextureFileNameForOutput();
void setOutputShaderFiles(bool flag) { _outputShaderFiles = flag; }
bool getOutputShaderFiles() const { return _outputShaderFiles; }
virtual std::string getShaderFileNameForOutput();
protected:
@@ -111,9 +116,13 @@ class OSGDB_EXPORT Output : public std::ofstream
std::string _filename;
PathNameHint _pathNameHint;
bool _outputTextureFiles;
unsigned int _textureFileNameNumber;
bool _outputShaderFiles;
unsigned int _shaderFileNameNumber;
bool _writeOutDefaultValues;
};

View File

@@ -132,6 +132,26 @@ inline osg::Node* readNodeFiles(osg::ArgumentParser& parser)
return readNodeFiles(parser,Registry::instance()->getOptions());
}
/** Read an osg::Shader from file.
* Return valid osg::Shader on success,
* return NULL on failure.
* Use the Options object to control cache operations and file search paths in osgDB::Registry.
* The osgDB::Registry is used to load the appropriate ReaderWriter plugin
* for the filename extension, and this plugin then handles the request
* to read the specified file.*/
extern OSGDB_EXPORT osg::Shader* readShaderFile(const std::string& filename,const ReaderWriter::Options* options);
/** Read an osg::Shader from file.
* Return valid osg::Shader on success,
* return NULL on failure.
* The osgDB::Registry is used to load the appropriate ReaderWriter plugin
* for the filename extension, and this plugin then handles the request
* to read the specified file.*/
inline osg::Shader* readShaderFile(const std::string& filename)
{
return readShaderFile(filename,Registry::instance()->getOptions());
}
/** Read an osg::Object from file.
* Return an assigned osg::ref_ptr on success,
@@ -213,6 +233,26 @@ inline osg::ref_ptr<osg::Node> readRefNodeFile(const std::string& filename)
return readRefNodeFile(filename,Registry::instance()->getOptions());
}
/** Read an osg::Shader from file.
* Return an assigned osg::ref_ptr on success,
* return an osg::ref_ptr with a NULL pointer assigned to it on failure.
* Use the Options object to control cache operations and file search paths in osgDB::Registry.
* The osgDB::Registry is used to load the appropriate ReaderWriter plugin
* for the filename extension, and this plugin then handles the request
* to read the specified file.*/
extern OSGDB_EXPORT osg::ref_ptr<osg::Shader> readRefShaderFile(const std::string& filename,const ReaderWriter::Options* options);
/** Read an osg::Shader from file.
* Return an assigned osg::ref_ptr on success,
* return an osg::ref_ptr with a NULL pointer assigned to it on failure.
* The osgDB::Registry is used to load the appropriate ReaderWriter plugin
* for the filename extension, and this plugin then handles the request
* to read the specified file.*/
inline osg::ref_ptr<osg::Shader> readRefShaderFile(const std::string& filename)
{
return readRefShaderFile(filename,Registry::instance()->getOptions());
}
}

View File

@@ -75,12 +75,16 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object
/// cache objects loaded via readObject(filename)
CACHE_OBJECTS = 16,
/// cache shaders loaded via readShader(filename)
CACHE_SHADERS = 32,
/// cache on all read*(filename) calls
CACHE_ALL = CACHE_NODES |
CACHE_IMAGES |
CACHE_HEIGHTFIELDS |
CACHE_ARCHIVES |
CACHE_OBJECTS
CACHE_OBJECTS |
CACHE_SHADERS
};
@@ -175,18 +179,21 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object
osg::HeightField* getHeightField();
osg::Node* getNode();
osgDB::Archive* getArchive();
osg::Shader* getShader();
bool validObject() { return _object.valid(); }
bool validImage() { return getImage()!=0; }
bool validHeightField() { return getHeightField()!=0; }
bool validNode() { return getNode()!=0; }
bool validArchive() { return getArchive()!=0; }
bool validShader() { return getShader()!=0; }
osg::Object* takeObject();
osg::Image* takeImage();
osg::HeightField* takeHeightField();
osg::Node* takeNode();
osgDB::Archive* takeArchive();
osg::Shader* takeShader();
std::string& message() { return _message; }
const std::string& message() const { return _message; }
@@ -253,21 +260,25 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object
virtual ReadResult readImage(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readHeightField(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readNode(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readShader(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual WriteResult writeObject(const osg::Object& /*obj*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeImage(const osg::Image& /*image*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeNode(const osg::Node& /*node*/,const std::string& /*fileName*/,const Options* =NULL) const { return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeShader(const osg::Shader& /*shader*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual ReadResult readObject(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readImage(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readHeightField(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readNode(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readShader(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual WriteResult writeObject(const osg::Object& /*obj*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeImage(const osg::Image& /*image*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeNode(const osg::Node& /*node*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeShader(const osg::Shader& /*shader*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::FILE_NOT_HANDLED); }
};

View File

@@ -126,6 +126,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced
osg::Uniform* readUniform(Input& fr);
osg::StateAttribute* readStateAttribute(Input& fr);
osg::Node* readNode(Input& fr);
osg::Shader* readShader(Input& fr);
bool writeObject(const osg::Object& obj,Output& fw);
@@ -158,6 +159,11 @@ class OSGDB_EXPORT Registry : public osg::Referenced
{
return osgDB::Registry::instance()->readNodeImplementation(filename,options);
}
virtual ReaderWriter::ReadResult readShader(const std::string& filename, const ReaderWriter::Options* options)
{
return osgDB::Registry::instance()->readShaderImplementation(filename,options);
}
protected:
virtual ~ReadFileCallback() {}
@@ -208,6 +214,12 @@ class OSGDB_EXPORT Registry : public osg::Referenced
}
ReaderWriter::ReadResult readNodeImplementation(const std::string& fileName,const ReaderWriter::Options* options);
ReaderWriter::ReadResult readShader(const std::string& fileName,const ReaderWriter::Options* options)
{
if (_readFileCallback.valid()) return _readFileCallback->readShader(fileName,options);
else return readShaderImplementation(fileName,options);
}
ReaderWriter::ReadResult readShaderImplementation(const std::string& fileName,const ReaderWriter::Options* options);
@@ -234,6 +246,11 @@ class OSGDB_EXPORT Registry : public osg::Referenced
{
return osgDB::Registry::instance()->writeNodeImplementation(obj,fileName,options);
}
virtual ReaderWriter::WriteResult writeShader(const osg::Shader& obj, const std::string& fileName,const ReaderWriter::Options* options)
{
return osgDB::Registry::instance()->writeShaderImplementation(obj,fileName,options);
}
protected:
virtual ~WriteFileCallback() {}
@@ -277,6 +294,12 @@ class OSGDB_EXPORT Registry : public osg::Referenced
}
ReaderWriter::WriteResult writeNodeImplementation(const osg::Node& node, const std::string& fileName,const ReaderWriter::Options* options);
ReaderWriter::WriteResult writeShader(const osg::Shader& obj, const std::string& fileName,const ReaderWriter::Options* options)
{
if (_writeFileCallback.valid()) return _writeFileCallback->writeShader(obj,fileName,options);
else return writeShaderImplementation(obj,fileName,options);
}
ReaderWriter::WriteResult writeShaderImplementation(const osg::Shader& obj, const std::string& fileName,const ReaderWriter::Options* options);
void setCreateNodeFromImage(bool flag) { _createNodeFromImage = flag; }
@@ -447,6 +470,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced
struct ReadHeightFieldFunctor;
struct ReadNodeFunctor;
struct ReadArchiveFunctor;
struct ReadShaderFunctor;
// make helper classes friends to get round VS6.0 "issues"
friend struct ReadFunctor;
@@ -455,6 +479,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced
friend struct ReadHeightFieldFunctor;
friend struct ReadNodeFunctor;
friend struct ReadArchiveFunctor;
friend struct ReadShaderFunctor;
ReaderWriter::ReadResult read(const ReadFunctor& readFunctor);
ReaderWriter::ReadResult readImplementation(const ReadFunctor& readFunctor,bool useObjectCache);
@@ -474,6 +499,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced
DotOsgWrapperMap _stateAttrWrapperMap;
DotOsgWrapperMap _uniformWrapperMap;
DotOsgWrapperMap _nodeWrapperMap;
DotOsgWrapperMap _shaderWrapperMap;
DotOsgWrapperMap _classNameWrapperMap;

View File

@@ -105,6 +105,26 @@ inline bool writeNodeFile(const osg::Node& node, const std::string& filename)
return writeNodeFile( node, filename, Registry::instance()->getOptions() );
}
/** Write an osg::Shader to file.
* Return true on success,
* return false on failure.
* Use the Options object to control cache operations and file search paths in osgDB::Registry.
* The osgDB::Registry is used to load the appropriate ReaderWriter plugin
* for the filename extension, and this plugin then handles the request
* to write the specified file.*/
extern OSGDB_EXPORT bool writeShaderFile(const osg::Shader& shader, const std::string& filename, const ReaderWriter::Options* options );
/** Write an osg::Shader to file.
* Return true on success,
* return false on failure.
* The osgDB::Registry is used to load the appropriate ReaderWriter plugin
* for the filename extension, and this plugin then handles the request
* to write the specified file.*/
inline bool writeShaderFile(const osg::Shader& shader, const std::string& filename)
{
return writeShaderFile( shader, filename, Registry::instance()->getOptions() );
}
}
#endif

View File

@@ -110,7 +110,8 @@ Shader::Shader(Type type, const std::string& source) :
Shader::Shader(const Shader& rhs, const osg::CopyOp& copyop):
osg::Object( rhs, copyop ),
_type(rhs._type),
_shaderSource(rhs._shaderSource)
_shaderSource(rhs._shaderSource),
_shaderFileName(rhs._shaderFileName)
{
}
@@ -142,6 +143,9 @@ int Shader::compare(const Shader& rhs) const
if( getShaderSource() < rhs.getShaderSource() ) return -1;
if( rhs.getShaderSource() < getShaderSource() ) return 1;
if( getFileName() < rhs.getFileName() ) return -1;
if( rhs.getFileName() < getFileName() ) return 1;
return 0;
}
@@ -171,6 +175,7 @@ bool Shader::loadShaderSourceFromFile( const std::string& fileName )
}
osg::notify(osg::INFO)<<"Loading shader source file \""<<fileName<<"\""<<std::endl;
_shaderFileName = fileName;
sourceFile.seekg(0, std::ios::end);
int length = sourceFile.tellg();

View File

@@ -87,9 +87,13 @@ osg::Object* Input::readObject(const std::string& fileName)
return readObjectFile(fileName,_options.get());
}
osg::Shader* Input::readShader()
{
return Registry::instance()->readShader(*this);
}
osg::Image* Input::readImage(const std::string& fileName)
{
return readImageFile(fileName,_options.get());
}
@@ -98,6 +102,11 @@ osg::Node* Input::readNode(const std::string& fileName)
return readNodeFile(fileName,_options.get());
}
osg::Shader* Input::readShader(const std::string& fileName)
{
return readShaderFile(fileName,_options.get());
}
bool Input::read(Parameter value1)
{
if (value1.valid((*this)[0].getStr()))

View File

@@ -46,8 +46,13 @@ void Output::init()
_indentStep = 2;
_numIndicesPerLine = 10;
_pathNameHint = AS_IS;
_outputTextureFiles = false;
_textureFileNameNumber = 0;
_outputShaderFiles = false;
_shaderFileNameNumber = 0;
_writeOutDefaultValues = false;
const char* env = getenv("OSG_WRITE_OUT_DEFAULT_VALUES");
@@ -212,3 +217,19 @@ std::string Output::getTextureFileNameForOutput()
return fileName;
}
std::string Output::getShaderFileNameForOutput()
{
std::string fileName = osgDB::getNameLessExtension(_filename);
if (_shaderFileNameNumber>0)
{
std::ostringstream o;
o << '_' << _shaderFileNameNumber;
fileName += o.str();
}
fileName += ".glsl";
++_shaderFileNameNumber;
return fileName;
}

View File

@@ -13,6 +13,7 @@
#include <osg/Notify>
#include <osg/Object>
#include <osg/Image>
#include <osg/Shader>
#include <osg/ImageStream>
#include <osg/Node>
#include <osg/Group>
@@ -45,6 +46,14 @@ Image* osgDB::readImageFile(const std::string& filename,const ReaderWriter::Opti
return NULL;
}
Shader* osgDB::readShaderFile(const std::string& filename,const ReaderWriter::Options* options)
{
ReaderWriter::ReadResult rr = Registry::instance()->readShader(filename,options);
if (rr.validShader()) return rr.takeShader();
if (rr.error()) notify(WARN) << rr.message() << std::endl;
return NULL;
}
HeightField* osgDB::readHeightFieldFile(const std::string& filename,const ReaderWriter::Options* options)
{
@@ -255,6 +264,14 @@ osg::ref_ptr<osg::Image> osgDB::readRefImageFile(const std::string& filename,con
return NULL;
}
osg::ref_ptr<osg::Shader> osgDB::readRefShaderFile(const std::string& filename,const ReaderWriter::Options* options)
{
ReaderWriter::ReadResult rr = Registry::instance()->readShader(filename,options);
if (rr.validShader()) return osg::ref_ptr<osg::Shader>(rr.getShader());
if (rr.error()) notify(WARN) << rr.message() << std::endl;
return NULL;
}
osg::ref_ptr<osg::HeightField> osgDB::readRefHeightFieldFile(const std::string& filename,const ReaderWriter::Options* options)
{
ReaderWriter::ReadResult rr = Registry::instance()->readHeightField(filename,options);

View File

@@ -21,12 +21,14 @@ osg::Image* ReaderWriter::ReadResult::getImage() { return dynamic_cast<osg::Imag
osg::HeightField* ReaderWriter::ReadResult::getHeightField() { return dynamic_cast<osg::HeightField*>(_object.get()); }
osg::Node* ReaderWriter::ReadResult::getNode() { return dynamic_cast<osg::Node*>(_object.get()); }
osgDB::Archive* ReaderWriter::ReadResult::getArchive() { return dynamic_cast<osgDB::Archive*>(_object.get()); }
osg::Shader* ReaderWriter::ReadResult::getShader() { return dynamic_cast<osg::Shader*>(_object.get()); }
osg::Object* ReaderWriter::ReadResult::takeObject() { osg::Object* obj = _object.get(); if (obj) { obj->ref(); _object=NULL; obj->unref_nodelete(); } return obj; }
osg::Image* ReaderWriter::ReadResult::takeImage() { osg::Image* image=dynamic_cast<osg::Image*>(_object.get()); if (image) { image->ref(); _object=NULL; image->unref_nodelete(); } return image; }
osg::HeightField* ReaderWriter::ReadResult::takeHeightField() { osg::HeightField* hf=dynamic_cast<osg::HeightField*>(_object.get()); if (hf) { hf->ref(); _object=NULL; hf->unref_nodelete(); } return hf; }
osg::Node* ReaderWriter::ReadResult::takeNode() { osg::Node* node=dynamic_cast<osg::Node*>(_object.get()); if (node) { node->ref(); _object=NULL; node->unref_nodelete(); } return node; }
osgDB::Archive* ReaderWriter::ReadResult::takeArchive() { osgDB::Archive* archive=dynamic_cast<osgDB::Archive*>(_object.get()); if (archive) { archive->ref(); _object=NULL; archive->unref_nodelete(); } return archive; }
osg::Shader* ReaderWriter::ReadResult::takeShader() { osg::Shader* shader=dynamic_cast<osg::Shader*>(_object.get()); if (shader) { shader->ref(); _object=NULL; shader->unref_nodelete(); } return shader; }
ReaderWriter::~ReaderWriter()
{

View File

@@ -14,6 +14,7 @@
#include <osg/Notify>
#include <osg/Object>
#include <osg/Image>
#include <osg/Shader>
#include <osg/Node>
#include <osg/Group>
#include <osg/Geode>
@@ -431,6 +432,11 @@ void Registry::addDotOsgWrapper(DotOsgWrapper* wrapper)
_nodeWrapperMap[name] = wrapper;
_nodeWrapperMap[compositeName] = wrapper;
}
if (dynamic_cast<const Shader*>(proto))
{
_shaderWrapperMap[name] = wrapper;
_shaderWrapperMap[compositeName] = wrapper;
}
}
@@ -468,6 +474,7 @@ void Registry::removeDotOsgWrapper(DotOsgWrapper* wrapper)
eraseWrapper(_uniformWrapperMap,wrapper);
eraseWrapper(_stateAttrWrapperMap,wrapper);
eraseWrapper(_nodeWrapperMap,wrapper);
eraseWrapper(_shaderWrapperMap,wrapper);
}
void Registry::addReaderWriter(ReaderWriter* rw)
@@ -1126,6 +1133,31 @@ Node* Registry::readNode(Input& fr)
return NULL;
}
//
// read image from input iterator.
//
Shader* Registry::readShader(Input& fr)
{
if (fr[0].matchWord("Use"))
{
if (fr[1].isString())
{
Shader* shader = dynamic_cast<Shader*>(fr.getObjectForUniqueID(fr[1].getStr()));
if (shader) fr+=2;
return shader;
}
else return NULL;
}
osg::Object* obj = readObject(_shaderWrapperMap,fr);
osg::Shader* shader = dynamic_cast<Shader*>(obj);
if (shader) return shader;
else if (obj) obj->unref();
return NULL;
}
//
// Write object to output
//
@@ -1313,6 +1345,15 @@ struct Registry::ReadArchiveFunctor : public Registry::ReadFunctor
};
struct Registry::ReadShaderFunctor : public Registry::ReadFunctor
{
ReadShaderFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {}
virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw)const { return rw.readShader(_filename, _options); }
virtual bool isValid(ReaderWriter::ReadResult& readResult) const { return readResult.validShader(); }
virtual bool isValid(osg::Object* object) const { return dynamic_cast<osg::Shader*>(object)!=0; }
};
void Registry::addArchiveExtension(const std::string ext)
{
for(ArchiveExtensionList::iterator aitr=_archiveExtList.begin();
@@ -1792,6 +1833,58 @@ ReaderWriter::WriteResult Registry::writeNodeImplementation(const Node& node,con
return results.front();
}
ReaderWriter::ReadResult Registry::readShaderImplementation(const std::string& fileName,const ReaderWriter::Options* options)
{
return readImplementation(ReadShaderFunctor(fileName, options),
options ? (options->getObjectCacheHint()&ReaderWriter::Options::CACHE_SHADERS)!=0: false);
}
ReaderWriter::WriteResult Registry::writeShaderImplementation(const Shader& shader,const std::string& fileName,const ReaderWriter::Options* options)
{
// record the errors reported by readerwriters.
typedef std::vector<ReaderWriter::WriteResult> Results;
Results results;
// first attempt to load the file from existing ReaderWriter's
AvailableReaderWriterIterator itr(_rwList);
for(;itr.valid();++itr)
{
ReaderWriter::WriteResult rr = itr->writeShader(shader,fileName,options);
if (rr.success()) return rr;
else results.push_back(rr);
}
results.clear();
// now look for a plug-in to save the file.
std::string libraryName = createLibraryNameForFile(fileName);
if (loadLibrary(libraryName))
{
for(;itr.valid();++itr)
{
ReaderWriter::WriteResult rr = itr->writeShader(shader,fileName,options);
if (rr.success()) return rr;
else results.push_back(rr);
}
}
if (results.empty())
{
return ReaderWriter::WriteResult("Warning: Could not find plugin to write shader to file \""+fileName+"\".");
}
if (results.front().message().empty())
{
switch(results.front().status())
{
case(ReaderWriter::WriteResult::FILE_NOT_HANDLED): results.front().message() = "Warning: Write to \""+fileName+"\" not supported."; break;
case(ReaderWriter::WriteResult::ERROR_IN_WRITING_FILE): results.front().message() = "Warning: Error in writing to \""+fileName+"\"."; break;
default: break;
}
}
return results.front();
}
void Registry::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp)
{

View File

@@ -53,3 +53,11 @@ bool osgDB::writeNodeFile(const Node& node,const std::string& filename, const Re
if (wr.error()) notify(WARN) << "Error writing file " << filename << ": " << wr.message() << std::endl;
return wr.success();
}
bool osgDB::writeShaderFile(const Shader& shader,const std::string& filename, const ReaderWriter::Options* options )
{
ReaderWriter::WriteResult wr = Registry::instance()->writeShader( shader, filename, options );
if (wr.error()) notify(WARN) << "Error writing file " << filename << ": " << wr.message() << std::endl;
return wr.success();
}

View File

@@ -59,6 +59,11 @@ ADD_SUBDIRECTORY(ive)
#
ADD_SUBDIRECTORY(cfg)
############################################################
#
# Shader plugins
#
ADD_SUBDIRECTORY(glsl)
############################################################
#

View File

@@ -0,0 +1,6 @@
#this file is automatically generated
SET(TARGET_SRC ReaderWriterGLSL.cpp )
#### end var setup ###
SETUP_PLUGIN(glsl)

View File

@@ -0,0 +1,89 @@
#include <osg/Shader>
#include <osg/Notify>
#include <osg/GL>
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
class ReaderWriterGLSL : public osgDB::ReaderWriter
{
public:
virtual const char* className() const { return "GLSL Shader Reader"; }
virtual bool acceptsExtension(const std::string& extension) const
{
return osgDB::equalCaseInsensitive(extension,"glsl") || osgDB::equalCaseInsensitive(extension,"gl");
}
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 );
// check options which can define the type of the shader program
if (options)
{
if (options->getOptionString().find("fragment")!=std::string::npos) shader->setType(osg::Shader::FRAGMENT);
if (options->getOptionString().find("vertex")!=std::string::npos) shader->setType(osg::Shader::VERTEX);
if (options->getOptionString().find("geometry")!=std::string::npos) shader->setType(osg::Shader::GEOMETRY);
}
// cleanup
delete [] text;
// return valid shader
return shader;
}
virtual ReadResult readShader(const std::string& file, const osgDB::ReaderWriter::Options* options) const
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
std::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
if(!istream) return ReadResult::FILE_NOT_HANDLED;
ReadResult rr = readShader(istream, options);
if(rr.validShader()) rr.getShader()->setFileName(file);
return rr;
}
virtual WriteResult writeShader(const osg::Shader& shader,std::ostream& fout,const Options* = NULL) const
{
// get shader source
std::string source = shader.getShaderSource();
// write source to file
fout << source;
// return all things went fine
return WriteResult::FILE_SAVED;
}
virtual WriteResult writeShader(const osg::Shader &shader,const std::string& fileName, const osgDB::ReaderWriter::Options*) const
{
std::string ext = osgDB::getFileExtension(fileName);
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
std::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);
if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;
return writeShader(shader, fout);
}
};
// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(glsl, ReaderWriterGLSL)

View File

@@ -8,6 +8,7 @@
#include "osgDB/Input"
#include "osgDB/Output"
#include "osgDB/FileUtils"
#include "osgDB/WriteFile"
using namespace osg;
using namespace osgDB;
@@ -84,24 +85,48 @@ bool Shader_writeLocalData(const Object& obj,Output& fw)
fw.indent() << "type " << shader.getTypename() << std::endl;
// split source text into individual lines
std::vector<std::string> lines;
std::istringstream iss(shader.getShaderSource());
std::string line;
while (std::getline(iss, line)) {
lines.push_back(line);
// osg::notify(osg::NOTICE)<<"fw.getOutputShaderFiles()="<<fw.getOutputShaderFiles()<<std::endl;
// check whenever output to shader files is requested
if (fw.getOutputShaderFiles())
{
std::string fileName = shader.getFileName();
if (fileName.empty())
{
fileName = fw.getShaderFileNameForOutput();
}
osgDB::writeShaderFile(shader, fileName);
if (!fileName.empty())
{
fw.indent() << "file "<<fw.wrapString(fw.getFileNameForOutput(fileName))<< std::endl;
}
}
else // no need to write shaders to external files, hence embed it
{
// split source text into individual lines
std::vector<std::string> lines;
std::istringstream iss(shader.getShaderSource());
std::string line;
while (std::getline(iss, line)) {
lines.push_back(line);
}
fw.indent() << "code {\n";
fw.moveIn();
std::vector<std::string>::const_iterator j;
for (j=lines.begin(); j!=lines.end(); ++j) {
fw.indent() << fw.wrapString(*j) << "\n";
fw.indent() << "code {\n";
fw.moveIn();
std::vector<std::string>::const_iterator j;
for (j=lines.begin(); j!=lines.end(); ++j) {
fw.indent() << fw.wrapString(*j) << "\n";
}
fw.moveOut();
fw.indent() << "}\n";
}
fw.moveOut();
fw.indent() << "}\n";
return true;
}

View File

@@ -107,6 +107,16 @@ BEGIN_OBJECT_REFLECTOR(osg::Shader)
__C5_char_P1__getTypename,
"Get the Shader type as a descriptive string. ",
"");
I_Method1(void, setFileName, IN, const std::string &, fileName,
Properties::NON_VIRTUAL,
__void__setFileName__C5_std_string_R1,
"Set file name for the shader source code. ",
"");
I_Method0(const std::string &, getFileName,
Properties::NON_VIRTUAL,
__C5_std_string_R1__getFileName,
"Get filename to which the shader source code belongs. ",
"");
I_Method1(void, resizeGLObjectBuffers, IN, unsigned int, maxSize,
Properties::VIRTUAL,
__void__resizeGLObjectBuffers__unsigned_int,
@@ -175,6 +185,9 @@ BEGIN_OBJECT_REFLECTOR(osg::Shader)
__bool__removeProgramRef__osg_Program_P1,
"",
"");
I_SimpleProperty(const std::string &, FileName,
__C5_std_string_R1__getFileName,
__void__setFileName__C5_std_string_R1);
I_SimpleProperty(const std::string &, ShaderSource,
__C5_std_string_R1__getShaderSource,
__void__setShaderSource__C5_std_string_R1);

View File

@@ -14,6 +14,7 @@
#include <osg/Image>
#include <osg/Node>
#include <osg/Object>
#include <osg/Shader>
#include <osg/StateAttribute>
#include <osg/Uniform>
#include <osgDB/Input>
@@ -86,6 +87,11 @@ BEGIN_OBJECT_REFLECTOR(osgDB::Input)
__osg_Node_P1__readNode,
"",
"");
I_Method0(osg::Shader *, readShader,
Properties::VIRTUAL,
__osg_Shader_P1__readShader,
"",
"");
I_Method1(osg::Object *, readObject, IN, const std::string &, fileName,
Properties::VIRTUAL,
__osg_Object_P1__readObject__C5_std_string_R1,
@@ -101,6 +107,11 @@ BEGIN_OBJECT_REFLECTOR(osgDB::Input)
__osg_Node_P1__readNode__C5_std_string_R1,
"",
"");
I_Method1(osg::Shader *, readShader, IN, const std::string &, fileName,
Properties::VIRTUAL,
__osg_Shader_P1__readShader__C5_std_string_R1,
"",
"");
I_Method1(osg::Object *, getObjectForUniqueID, IN, const std::string &, uniqueID,
Properties::VIRTUAL,
__osg_Object_P1__getObjectForUniqueID__C5_std_string_R1,

View File

@@ -14,6 +14,7 @@
#include <osg/Image>
#include <osg/Node>
#include <osg/Object>
#include <osg/Shader>
#include <osg/Shape>
#include <osgDB/Archive>
#include <osgDB/ReaderWriter>
@@ -103,6 +104,11 @@ BEGIN_OBJECT_REFLECTOR(osgDB::ReaderWriter)
__ReadResult__readNode__C5_std_string_R1__C5_Options_P1,
"",
"");
I_MethodWithDefaults2(osgDB::ReaderWriter::ReadResult, readShader, IN, const std::string &, x, , IN, const osgDB::ReaderWriter::Options *, x, NULL,
Properties::VIRTUAL,
__ReadResult__readShader__C5_std_string_R1__C5_Options_P1,
"",
"");
I_MethodWithDefaults3(osgDB::ReaderWriter::WriteResult, writeObject, IN, const osg::Object &, x, , IN, const std::string &, x, , IN, const osgDB::ReaderWriter::Options *, x, NULL,
Properties::VIRTUAL,
__WriteResult__writeObject__C5_osg_Object_R1__C5_std_string_R1__C5_Options_P1,
@@ -123,6 +129,11 @@ BEGIN_OBJECT_REFLECTOR(osgDB::ReaderWriter)
__WriteResult__writeNode__C5_osg_Node_R1__C5_std_string_R1__C5_Options_P1,
"",
"");
I_MethodWithDefaults3(osgDB::ReaderWriter::WriteResult, writeShader, IN, const osg::Shader &, x, , IN, const std::string &, x, , IN, const osgDB::ReaderWriter::Options *, x, NULL,
Properties::VIRTUAL,
__WriteResult__writeShader__C5_osg_Shader_R1__C5_std_string_R1__C5_Options_P1,
"",
"");
I_MethodWithDefaults2(osgDB::ReaderWriter::ReadResult, readObject, IN, std::istream &, x, , IN, const osgDB::ReaderWriter::Options *, x, NULL,
Properties::VIRTUAL,
__ReadResult__readObject__std_istream_R1__C5_Options_P1,
@@ -143,6 +154,11 @@ BEGIN_OBJECT_REFLECTOR(osgDB::ReaderWriter)
__ReadResult__readNode__std_istream_R1__C5_Options_P1,
"",
"");
I_MethodWithDefaults2(osgDB::ReaderWriter::ReadResult, readShader, IN, std::istream &, x, , IN, const osgDB::ReaderWriter::Options *, x, NULL,
Properties::VIRTUAL,
__ReadResult__readShader__std_istream_R1__C5_Options_P1,
"",
"");
I_MethodWithDefaults3(osgDB::ReaderWriter::WriteResult, writeObject, IN, const osg::Object &, x, , IN, std::ostream &, x, , IN, const osgDB::ReaderWriter::Options *, x, NULL,
Properties::VIRTUAL,
__WriteResult__writeObject__C5_osg_Object_R1__std_ostream_R1__C5_Options_P1,
@@ -163,6 +179,11 @@ BEGIN_OBJECT_REFLECTOR(osgDB::ReaderWriter)
__WriteResult__writeNode__C5_osg_Node_R1__std_ostream_R1__C5_Options_P1,
"",
"");
I_MethodWithDefaults3(osgDB::ReaderWriter::WriteResult, writeShader, IN, const osg::Shader &, x, , IN, std::ostream &, x, , IN, const osgDB::ReaderWriter::Options *, x, NULL,
Properties::VIRTUAL,
__WriteResult__writeShader__C5_osg_Shader_R1__std_ostream_R1__C5_Options_P1,
"",
"");
END_REFLECTOR
BEGIN_ENUM_REFLECTOR(osgDB::ReaderWriter::Options::CacheHintOptions)
@@ -173,6 +194,7 @@ BEGIN_ENUM_REFLECTOR(osgDB::ReaderWriter::Options::CacheHintOptions)
I_EnumLabel(osgDB::ReaderWriter::Options::CACHE_HEIGHTFIELDS);
I_EnumLabel(osgDB::ReaderWriter::Options::CACHE_ARCHIVES);
I_EnumLabel(osgDB::ReaderWriter::Options::CACHE_OBJECTS);
I_EnumLabel(osgDB::ReaderWriter::Options::CACHE_SHADERS);
I_EnumLabel(osgDB::ReaderWriter::Options::CACHE_ALL);
END_REFLECTOR
@@ -344,6 +366,11 @@ BEGIN_VALUE_REFLECTOR(osgDB::ReaderWriter::ReadResult)
__osgDB_Archive_P1__getArchive,
"",
"");
I_Method0(osg::Shader *, getShader,
Properties::NON_VIRTUAL,
__osg_Shader_P1__getShader,
"",
"");
I_Method0(bool, validObject,
Properties::NON_VIRTUAL,
__bool__validObject,
@@ -369,6 +396,11 @@ BEGIN_VALUE_REFLECTOR(osgDB::ReaderWriter::ReadResult)
__bool__validArchive,
"",
"");
I_Method0(bool, validShader,
Properties::NON_VIRTUAL,
__bool__validShader,
"",
"");
I_Method0(osg::Object *, takeObject,
Properties::NON_VIRTUAL,
__osg_Object_P1__takeObject,
@@ -394,6 +426,11 @@ BEGIN_VALUE_REFLECTOR(osgDB::ReaderWriter::ReadResult)
__osgDB_Archive_P1__takeArchive,
"",
"");
I_Method0(osg::Shader *, takeShader,
Properties::NON_VIRTUAL,
__osg_Shader_P1__takeShader,
"",
"");
I_Method0(std::string &, message,
Properties::NON_VIRTUAL,
__std_string_R1__message,
@@ -449,6 +486,9 @@ BEGIN_VALUE_REFLECTOR(osgDB::ReaderWriter::ReadResult)
I_SimpleProperty(osg::Object *, Object,
__osg_Object_P1__getObject,
0);
I_SimpleProperty(osg::Shader *, Shader,
__osg_Shader_P1__getShader,
0);
END_REFLECTOR
BEGIN_ENUM_REFLECTOR(osgDB::ReaderWriter::WriteResult::WriteStatus)

View File

@@ -15,6 +15,7 @@
#include <osg/Image>
#include <osg/Node>
#include <osg/Object>
#include <osg/Shader>
#include <osg/Shape>
#include <osg/State>
#include <osg/StateAttribute>
@@ -179,6 +180,11 @@ BEGIN_OBJECT_REFLECTOR(osgDB::Registry)
__osg_Node_P1__readNode__Input_R1,
"",
"");
I_Method1(osg::Shader *, readShader, IN, osgDB::Input &, fr,
Properties::NON_VIRTUAL,
__osg_Shader_P1__readShader__Input_R1,
"",
"");
I_Method2(bool, writeObject, IN, const osg::Object &, obj, IN, osgDB::Output &, fw,
Properties::NON_VIRTUAL,
__bool__writeObject__C5_osg_Object_R1__Output_R1,
@@ -249,6 +255,16 @@ BEGIN_OBJECT_REFLECTOR(osgDB::Registry)
__ReaderWriter_ReadResult__readNodeImplementation__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
I_Method2(osgDB::ReaderWriter::ReadResult, readShader, IN, const std::string &, fileName, IN, const osgDB::ReaderWriter::Options *, options,
Properties::NON_VIRTUAL,
__ReaderWriter_ReadResult__readShader__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
I_Method2(osgDB::ReaderWriter::ReadResult, readShaderImplementation, IN, const std::string &, fileName, IN, const osgDB::ReaderWriter::Options *, options,
Properties::NON_VIRTUAL,
__ReaderWriter_ReadResult__readShaderImplementation__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
I_Method1(void, setWriteFileCallback, IN, osgDB::Registry::WriteFileCallback *, cb,
Properties::NON_VIRTUAL,
__void__setWriteFileCallback__WriteFileCallback_P1,
@@ -304,6 +320,16 @@ BEGIN_OBJECT_REFLECTOR(osgDB::Registry)
__ReaderWriter_WriteResult__writeNodeImplementation__C5_osg_Node_R1__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
I_Method3(osgDB::ReaderWriter::WriteResult, writeShader, IN, const osg::Shader &, obj, IN, const std::string &, fileName, IN, const osgDB::ReaderWriter::Options *, options,
Properties::NON_VIRTUAL,
__ReaderWriter_WriteResult__writeShader__C5_osg_Shader_R1__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
I_Method3(osgDB::ReaderWriter::WriteResult, writeShaderImplementation, IN, const osg::Shader &, obj, IN, const std::string &, fileName, IN, const osgDB::ReaderWriter::Options *, options,
Properties::NON_VIRTUAL,
__ReaderWriter_WriteResult__writeShaderImplementation__C5_osg_Shader_R1__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
I_Method1(void, setCreateNodeFromImage, IN, bool, flag,
Properties::NON_VIRTUAL,
__void__setCreateNodeFromImage__bool,
@@ -559,6 +585,11 @@ BEGIN_OBJECT_REFLECTOR(osgDB::Registry::ReadFileCallback)
__ReaderWriter_ReadResult__readNode__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
I_Method2(osgDB::ReaderWriter::ReadResult, readShader, IN, const std::string &, filename, IN, const osgDB::ReaderWriter::Options *, options,
Properties::VIRTUAL,
__ReaderWriter_ReadResult__readShader__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
END_REFLECTOR
BEGIN_ABSTRACT_OBJECT_REFLECTOR(osgDB::Registry::ReadFunctor)
@@ -611,5 +642,10 @@ BEGIN_OBJECT_REFLECTOR(osgDB::Registry::WriteFileCallback)
__ReaderWriter_WriteResult__writeNode__C5_osg_Node_R1__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
I_Method3(osgDB::ReaderWriter::WriteResult, writeShader, IN, const osg::Shader &, obj, IN, const std::string &, fileName, IN, const osgDB::ReaderWriter::Options *, options,
Properties::VIRTUAL,
__ReaderWriter_WriteResult__writeShader__C5_osg_Shader_R1__C5_std_string_R1__C5_ReaderWriter_Options_P1,
"",
"");
END_REFLECTOR