root/OpenSceneGraph/trunk/include/osg/Shader @ 13041

Revision 13041, 11.8 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 * Copyright (C) 2003-2005 3Dlabs Inc. Ltd.
3 * Copyright (C) 2004-2005 Nathan Cournia
4 * Copyright (C) 2008 Zebra Imaging
5 * Copyright (C) 2010 VIRES Simulationstechnologie GmbH
6 *
7 * This application is open source and may be redistributed and/or modified
8 * freely and without restriction, both in commercial and non commercial
9 * applications, as long as this copyright notice is maintained.
10 *
11 * This application is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14*/
15
16/* file:   include/osg/Shader
17 * author: Mike Weiblen 2008-01-02
18 *         Holger Helmich 2010-10-21
19*/
20
21#ifndef OSG_SHADER
22#define OSG_SHADER 1
23
24
25#include <osg/GL2Extensions>
26#include <osg/Object>
27#include <osg/buffered_value>
28
29#include <set>
30#include <map>
31
32namespace osg {
33
34class Program;
35
36/** Simple class for wrapping up the data used in OpenGL ES 2's glShaderBinary calls.
37  * ShaderBinary is set up with the binary data then assigned to one or more osg::Shader. */
38class OSG_EXPORT ShaderBinary : public osg::Object
39{
40    public:
41
42        ShaderBinary();
43
44        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
45        ShaderBinary(const ShaderBinary& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
46
47        META_Object(osg, ShaderBinary);
48
49        /** Allocated a data buffer of specified size/*/
50        void allocate(unsigned int size);
51
52        /** Assign shader binary data, copying the specified data into locally stored data buffer, the original data can then be deleted.*/
53        void assign(unsigned int size, const unsigned char* data);
54
55        /** Get the size of the shader binary data.*/
56        unsigned int getSize() const { return _data.size(); }
57
58        /** Get a ptr to the shader binary data.*/
59        unsigned char* getData() { return _data.empty() ? 0 : &(_data.front()); }
60
61        /** Get a const ptr to the shader binary data.*/
62        const unsigned char* getData() const { return _data.empty() ? 0 : &(_data.front()); }
63
64        /** Read shader binary from file.
65          * Return the resulting Shader or 0 if no valid shader binary could be read.*/
66        static ShaderBinary* readShaderBinaryFile(const std::string& fileName);
67
68    protected:
69
70        typedef std::vector<unsigned char> Data;
71        Data _data;
72};
73
74
75///////////////////////////////////////////////////////////////////////////
76/** osg::Shader is an application-level abstraction of an OpenGL glShader.
77  * It is a container to load the shader source code text and manage its
78  * compilation.
79  * An osg::Shader may be attached to more than one osg::Program.
80  * Shader will automatically manage per-context instancing of the
81  * internal objects, if that is necessary for a particular display
82  * configuration.
83  */
84
85class OSG_EXPORT Shader : public osg::Object
86{
87    public:
88
89        enum Type {
90            VERTEX = GL_VERTEX_SHADER,
91            TESSCONTROL = GL_TESS_CONTROL_SHADER,
92            TESSEVALUATION = GL_TESS_EVALUATION_SHADER,
93            GEOMETRY = GL_GEOMETRY_SHADER_EXT,
94            FRAGMENT = GL_FRAGMENT_SHADER,
95            UNDEFINED = -1
96        };
97
98        Shader(Type type = UNDEFINED);
99        Shader(Type type, const std::string& source );
100        Shader(Type type, ShaderBinary* shaderBinary );
101
102        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
103        Shader(const Shader& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
104
105        META_Object(osg, Shader);
106
107        int compare(const Shader& rhs) const;
108
109        /** Set the Shader type as an enum. */
110        bool setType(Type t);
111
112        /** Get the Shader type as an enum. */
113        inline Type getType() const { return _type; }
114
115        /** Get the Shader type as a descriptive string. */
116        const char* getTypename() const;
117
118
119        /** Set file name for the shader source code. */
120        inline void setFileName(const std::string& fileName) { _shaderFileName = fileName; }
121
122        /** Get filename to which the shader source code belongs. */
123        inline const std::string& getFileName() const { return _shaderFileName; }
124
125
126        /** Set the Shader's source code text from a string. */
127        void setShaderSource(const std::string& sourceText);
128
129        /** Query the shader's source code text */
130        inline const std::string& getShaderSource() const { return _shaderSource; }
131
132
133        /** Set the Shader using a ShaderBinary. */
134        void setShaderBinary(ShaderBinary* shaderBinary) { _shaderBinary = shaderBinary; }
135
136        /** Get the Shader's ShaderBinary, return NULL if none is assigned. */
137        ShaderBinary* getShaderBinary() { return _shaderBinary.get(); }
138
139        /** Get the const Shader's ShaderBinary, return NULL if none is assigned. */
140        const ShaderBinary* getShaderBinary() const { return _shaderBinary.get(); }
141
142
143        /** Read shader source from file and then constructor shader of specified type.
144          * Return the resulting Shader or 0 if no valid shader source could be read.*/
145        static Shader* readShaderFile( Type type, const std::string& fileName );
146
147        /** Load the Shader's source code text from a file. */
148        bool loadShaderSourceFromFile( const std::string& fileName );
149
150
151        /** The code injection map used when generating the main shader during main shader composition.*/
152        typedef std::multimap<float, std::string> CodeInjectionMap;
153
154        /** Add code injection that will be placed in the main shader to enable support for this shader.
155          * The position is set up so that code to be inserted before the main() will have a negative value,
156          * a position between 0 and 1.0 will be inserted in main() and a position greater than 1.0 will
157          * be placed after the main().
158          * During shader composition all the code injections are sorted in ascending order and then
159          * placed in the appropriate section of the main shader. */
160        void addCodeInjection(float position, const std::string& code) { _codeInjectionMap.insert(CodeInjectionMap::value_type(position, code)); }
161
162        /** Get the code injection map.*/
163        CodeInjectionMap& getCodeInjectionMap() { return _codeInjectionMap; }
164
165        /** Get the const code injection map.*/
166        const CodeInjectionMap& getCodeInjectionMap() const { return _codeInjectionMap; }
167
168
169
170        /** Resize any per context GLObject buffers to specified size. */
171        virtual void resizeGLObjectBuffers(unsigned int maxSize);
172
173        /** release OpenGL objects in specified graphics context if State
174            object is passed, otherwise release OpenGL objects for all graphics context if
175            State object pointer NULL.*/
176        void releaseGLObjects(osg::State* state=0) const;
177
178        /** Mark our PCSs as needing recompilation.
179          * Also mark Programs that depend on us as needing relink */
180        void dirtyShader();
181
182        /** If needed, compile the PCS's glShader */
183        void compileShader(osg::State& state) const;
184
185        /** For a given GL context, attach a glShader to a glProgram */
186        void attachShader(unsigned int contextID, GLuint program) const;
187
188        /** For a given GL context, detach a glShader to a glProgram */
189        void detachShader(unsigned int contextID, GLuint program) const;
190
191        /** Query InfoLog from a glShader */
192        bool getGlShaderInfoLog(unsigned int contextID, std::string& log) const;
193
194        /** Mark internal glShader for deletion.
195          * Deletion requests are queued until they can be executed
196          * in the proper GL context. */
197        static void deleteGlShader(unsigned int contextID, GLuint shader);
198
199        /** flush all the cached glShaders which need to be deleted
200          * in the OpenGL context related to contextID.*/
201        static void flushDeletedGlShaders(unsigned int contextID,double currentTime, double& availableTime);
202
203        /** discard all the cached glShaders which need to be deleted in the OpenGL context related to contextID.
204          * Note, unlike flush no OpenGL calls are made, instead the handles are all removed.
205          * this call is useful for when an OpenGL context has been destroyed. */
206        static void discardDeletedGlShaders(unsigned int contextID);
207
208        static Shader::Type getTypeId( const std::string& tname );
209
210    public:
211        /** PerContextShader (PCS) is an OSG-internal encapsulation of glShader per-GL context. */
212        class OSG_EXPORT PerContextShader : public osg::Referenced
213        {
214            public:
215                PerContextShader(const Shader* shader, unsigned int contextID);
216
217                GLuint getHandle() const {return _glShaderHandle;}
218
219                void requestCompile();
220                void compileShader(osg::State& state);
221                bool needsCompile() const {return _needsCompile;}
222                bool isCompiled() const {return _isCompiled;}
223                bool getInfoLog( std::string& infoLog ) const;
224
225                /** Attach our glShader to a glProgram */
226                void attachShader(GLuint program) const;
227
228                /** Detach our glShader from a glProgram */
229                void detachShader(GLuint program) const;
230
231            protected:        /*methods*/
232                ~PerContextShader();
233
234            protected:        /*data*/
235                /** Pointer to our parent osg::Shader */
236                const Shader* _shader;
237                /** Pointer to this context's extension functions. */
238                osg::ref_ptr<osg::GL2Extensions> _extensions;
239                /** Handle to the actual glShader. */
240                GLuint _glShaderHandle;
241                /** Does our glShader need to be recompiled? */
242                bool _needsCompile;
243                /** Is our glShader successfully compiled? */
244                bool _isCompiled;
245                const unsigned int _contextID;
246
247            private:
248                PerContextShader();        // disallowed
249                PerContextShader(const PerContextShader&);        // disallowed
250                PerContextShader& operator=(const PerContextShader&);        // disallowed
251        };
252
253        PerContextShader* getPCS(unsigned int contextID) const;
254
255    protected:        /*methods*/
256        virtual ~Shader();
257
258
259        friend class osg::Program;
260        bool addProgramRef( osg::Program* program );
261        bool removeProgramRef( osg::Program* program );
262
263    protected:        /*data*/
264        Type                            _type;
265        std::string                     _shaderFileName;
266        std::string                     _shaderSource;
267        osg::ref_ptr<ShaderBinary>      _shaderBinary;
268
269        CodeInjectionMap                _codeInjectionMap;
270
271        /** osg::Programs that this osg::Shader is attached to */
272        typedef std::set< osg::Program* > ProgramSet;
273        ProgramSet                      _programSet;
274        mutable osg::buffered_value< osg::ref_ptr<PerContextShader> > _pcsList;
275
276    private:
277        Shader& operator=(const Shader&);        // disallowed
278};
279
280
281class OSG_EXPORT ShaderComponent : public osg::Object
282{
283    public:
284
285        ShaderComponent();
286        ShaderComponent(const ShaderComponent& sc,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
287
288        META_Object(osg, ShaderComponent)
289
290        unsigned int addShader(osg::Shader* shader);
291        void removeShader(unsigned int i);
292
293        osg::Shader* getShader(unsigned int i) { return _shaders[i].get(); }
294        const osg::Shader* getShader(unsigned int i) const { return _shaders[i].get(); }
295
296        unsigned int getNumShaders() const { return _shaders.size(); }
297
298        virtual void compileGLObjects(State& state) const;
299        virtual void resizeGLObjectBuffers(unsigned int maxSize);
300        virtual void releaseGLObjects(State* state=0) const;
301
302    protected:
303
304       typedef std::vector< osg::ref_ptr<osg::Shader> >  Shaders;
305       Shaders _shaders;
306};
307
308
309}
310
311#endif
Note: See TracBrowser for help on using the browser.