root/OpenSceneGraph/trunk/src/osgPlugins/glsl/ReaderWriterGLSL.cpp @ 13041

Revision 13041, 5.6 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1#include <sstream>
2#include <osg/Shader>
3#include <osg/Notify>
4#include <osg/GL>
5
6#include <osgDB/Registry>
7#include <osgDB/FileNameUtils>
8#include <osgDB/FileUtils>
9#include <osgDB/ReadFile>
10#include <osgDB/fstream>
11
12
13class ReaderWriterGLSL : public osgDB::ReaderWriter
14{
15    public:
16
17        ReaderWriterGLSL()
18        {
19            supportsExtension("gl","OpenGL Shader Language format");
20            supportsExtension("frag","OpenGL Shader Language format");
21            supportsExtension("vert","OpenGL Shader Language format");
22            supportsExtension("geom","OpenGL Shader Language format");
23            supportsExtension("glsl","OpenGL Shader Language format");
24        }
25
26        virtual const char* className() const { return "GLSL Shader Reader"; }
27
28        osg::Shader* processIncludes( const osg::Shader* shader, const Options* options ) const
29        {
30            std::string code = shader->getShaderSource();
31
32            std::string::size_type pos = 0;
33
34            static std::string::size_type includeLen = 8;
35
36            while( ( pos = code.find( "#include", pos ) ) != std::string::npos )
37            {
38                // we found an include
39                std::string::size_type pos2 = code.find_first_not_of( " ", pos + includeLen );
40
41                if ( ( pos2 == std::string::npos ) || ( code[ pos2 ] != '\"' ) )
42                {
43                    // error, bail out
44                    return NULL;
45                }
46
47                // we found an "
48                std::string::size_type pos3 = code.find( "\"", pos2 + 1 );
49
50                if ( pos3 == std::string::npos )
51                {
52                    return NULL;
53                }
54
55                const std::string filename = code.substr( pos2 + 1, pos3 - pos2 - 1 );
56
57                osg::ref_ptr<osg::Shader> innerShader = osgDB::readShaderFile( shader->getType(), filename, options );
58
59                if ( !innerShader.valid() )
60                {
61                    return NULL;
62                }
63
64                code.replace( pos, pos3 - pos + 1, innerShader->getShaderSource() );
65
66                pos += innerShader->getShaderSource().size();
67            }
68
69            return new osg::Shader( shader->getType(), code );
70        }
71
72        virtual ReadResult readObject(std::istream& fin,const Options* options) const
73        {
74            return readShader(fin, options);
75        }
76
77        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
78        {
79            return readShader(file, options);
80        }
81
82        virtual ReadResult readShader(std::istream& fin,const Options* options) const
83        {
84            // create shader
85            osg::ref_ptr<osg::Shader> shader = new osg::Shader();
86
87            {
88                std::stringstream ss;
89                ss << fin.rdbuf();
90                shader->setShaderSource( ss.str() );
91            }
92
93            // check options which can define the type of the shader program
94            if (options)
95            {
96                if (options->getOptionString().find("fragment")!=std::string::npos) shader->setType(osg::Shader::FRAGMENT);
97                if (options->getOptionString().find("vertex")!=std::string::npos) shader->setType(osg::Shader::VERTEX);
98                if (options->getOptionString().find("geometry")!=std::string::npos) shader->setType(osg::Shader::GEOMETRY);
99            }
100
101            // return valid shader
102            return processIncludes( shader.get(), options );
103        }
104
105        virtual ReadResult readShader(const std::string& file, const osgDB::ReaderWriter::Options* options) const
106        {
107            std::string ext = osgDB::getLowerCaseFileExtension(file);
108            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
109
110            std::string fileName = osgDB::findDataFile( file, options );
111            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
112
113            osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
114            if(!istream) return ReadResult::FILE_NOT_HANDLED;
115            ReadResult rr = readShader(istream, options);
116            if(rr.validShader())
117            {
118                osg::Shader* shader = rr.getShader();
119                shader->setFileName(file);
120                if (shader->getType() == osg::Shader::UNDEFINED)
121                {
122                    // set type based on filename extension, where possible
123                    if (ext == "frag") shader->setType(osg::Shader::FRAGMENT);
124                    if (ext == "vert") shader->setType(osg::Shader::VERTEX);
125                    if (ext == "geom") shader->setType(osg::Shader::GEOMETRY);
126                }
127            }
128            return rr;
129        }
130
131        virtual WriteResult writeShader(const osg::Shader& shader,std::ostream& fout,const Options* = NULL) const
132        {
133            // get shader source
134            std::string source = shader.getShaderSource();
135
136            // write source to file
137            fout << source;
138
139            // return all things went fine
140            return WriteResult::FILE_SAVED;
141        }
142
143        virtual WriteResult writeShader(const osg::Shader &shader,const std::string& fileName, const osgDB::ReaderWriter::Options*) const
144        {
145            std::string ext = osgDB::getFileExtension(fileName);
146            if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
147
148            osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);
149            if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;
150
151            return writeShader(shader, fout);
152        }
153};
154
155// now register with Registry to instantiate the above
156// reader/writer.
157REGISTER_OSGPLUGIN(glsl, ReaderWriterGLSL)
Note: See TracBrowser for help on using the browser.