Shader 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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. /* file: include/osg/Shader
  16. * author: Mike Weiblen 2008-01-02
  17. * Holger Helmich 2010-10-21
  18. */
  19. #ifndef OSG_SHADER
  20. #define OSG_SHADER 1
  21. #include <osg/GLExtensions>
  22. #include <osg/Object>
  23. #include <osg/buffered_value>
  24. #include <set>
  25. #include <map>
  26. namespace osg {
  27. class Program;
  28. // set of shader define strings that the shader is dependent upon.
  29. typedef std::set<std::string> ShaderDefines;
  30. /** Simple class for wrapping up the data used in OpenGL ES 2's glShaderBinary calls.
  31. * ShaderBinary is set up with the binary data then assigned to one or more osg::Shader. */
  32. class OSG_EXPORT ShaderBinary : public osg::Object
  33. {
  34. public:
  35. ShaderBinary();
  36. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  37. ShaderBinary(const ShaderBinary& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
  38. META_Object(osg, ShaderBinary);
  39. /** Allocated a data buffer of specified size.*/
  40. void allocate(unsigned int size);
  41. /** Assign shader binary data, copying the specified data into locally stored data buffer, the original data can then be deleted.*/
  42. void assign(unsigned int size, const unsigned char* data);
  43. /** Get the size of the shader binary data.*/
  44. unsigned int getSize() const { return static_cast<unsigned int>(_data.size()); }
  45. /** Get a ptr to the shader binary data.*/
  46. unsigned char* getData() { return _data.empty() ? 0 : &(_data.front()); }
  47. /** Get a const ptr to the shader binary data.*/
  48. const unsigned char* getData() const { return _data.empty() ? 0 : &(_data.front()); }
  49. /** Read shader binary from file.
  50. * Return the resulting Shader or 0 if no valid shader binary could be read.*/
  51. static ShaderBinary* readShaderBinaryFile(const std::string& fileName);
  52. protected:
  53. typedef std::vector<unsigned char> Data;
  54. Data _data;
  55. };
  56. ///////////////////////////////////////////////////////////////////////////
  57. /** osg::Shader is an application-level abstraction of an OpenGL glShader.
  58. * It is a container to load the shader source code text and manage its
  59. * compilation.
  60. * An osg::Shader may be attached to more than one osg::Program.
  61. * Shader will automatically manage per-context instancing of the
  62. * internal objects, if that is necessary for a particular display
  63. * configuration.
  64. */
  65. class OSG_EXPORT Shader : public osg::Object
  66. {
  67. public:
  68. enum Type {
  69. VERTEX = GL_VERTEX_SHADER,
  70. TESSCONTROL = GL_TESS_CONTROL_SHADER,
  71. TESSEVALUATION = GL_TESS_EVALUATION_SHADER,
  72. GEOMETRY = GL_GEOMETRY_SHADER,
  73. FRAGMENT = GL_FRAGMENT_SHADER,
  74. COMPUTE = GL_COMPUTE_SHADER,
  75. UNDEFINED = -1
  76. };
  77. Shader(Type type = UNDEFINED);
  78. Shader(Type type, const std::string& source );
  79. Shader(Type type, ShaderBinary* shaderBinary );
  80. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  81. Shader(const Shader& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
  82. META_Object(osg, Shader);
  83. int compare(const Shader& rhs) const;
  84. /** Set the Shader type as an enum. */
  85. bool setType(Type t);
  86. /** Get the Shader type as an enum. */
  87. inline Type getType() const { return _type; }
  88. /** Get the Shader type as a descriptive string. */
  89. const char* getTypename() const;
  90. /** Set file name for the shader source code. */
  91. inline void setFileName(const std::string& fileName) { _shaderFileName = fileName; }
  92. /** Get filename to which the shader source code belongs. */
  93. inline const std::string& getFileName() const { return _shaderFileName; }
  94. /** Set the Shader's source code text from a string. */
  95. void setShaderSource(const std::string& sourceText);
  96. /** Query the shader's source code text */
  97. inline const std::string& getShaderSource() const { return _shaderSource; }
  98. enum ShaderDefinesMode
  99. {
  100. USE_SHADER_PRAGMA,
  101. USE_MANUAL_SETTINGS
  102. };
  103. void setShaderDefinesMode(ShaderDefinesMode sdm) { _shaderDefinesMode = sdm; }
  104. ShaderDefinesMode getShaderDefinesMode() const { return _shaderDefinesMode; }
  105. void setShaderDefines(const ShaderDefines& shaderDefs) { _shaderDefines = shaderDefs; }
  106. ShaderDefines& getShaderDefines() { return _shaderDefines; }
  107. const ShaderDefines& getShaderDefines() const { return _shaderDefines; }
  108. void setShaderRequirements(const ShaderDefines& shaderDefs) { _shaderRequirements = shaderDefs; }
  109. ShaderDefines& getShaderRequirements() { return _shaderRequirements; }
  110. const ShaderDefines& getShaderRequirements() const { return _shaderRequirements; }
  111. /** Set the Shader using a ShaderBinary. */
  112. void setShaderBinary(ShaderBinary* shaderBinary) { _shaderBinary = shaderBinary; }
  113. /** Get the Shader's ShaderBinary, return NULL if none is assigned. */
  114. ShaderBinary* getShaderBinary() { return _shaderBinary.get(); }
  115. /** Get the const Shader's ShaderBinary, return NULL if none is assigned. */
  116. const ShaderBinary* getShaderBinary() const { return _shaderBinary.get(); }
  117. #ifdef OSG_USE_DEPRECATED_API
  118. /** Deorecated use osgDB::readRefShaderFile().*/
  119. static Shader* readShaderFile( Type type, const std::string& fileName );
  120. /** Deorecated use osgDB::readRefShaderFile(). */
  121. bool loadShaderSourceFromFile( const std::string& fileName );
  122. #endif
  123. /** The code injection map used when generating the main shader during main shader composition.*/
  124. typedef std::multimap<float, std::string> CodeInjectionMap;
  125. /** Add code injection that will be placed in the main shader to enable support for this shader.
  126. * The position is set up so that code to be inserted before the main() will have a negative value,
  127. * a position between 0 and 1.0 will be inserted in main() and a position greater than 1.0 will
  128. * be placed after the main().
  129. * During shader composition all the code injections are sorted in ascending order and then
  130. * placed in the appropriate section of the main shader. */
  131. void addCodeInjection(float position, const std::string& code) { _codeInjectionMap.insert(CodeInjectionMap::value_type(position, code)); }
  132. /** Get the code injection map.*/
  133. CodeInjectionMap& getCodeInjectionMap() { return _codeInjectionMap; }
  134. /** Get the const code injection map.*/
  135. const CodeInjectionMap& getCodeInjectionMap() const { return _codeInjectionMap; }
  136. /** Resize any per context GLObject buffers to specified size. */
  137. virtual void resizeGLObjectBuffers(unsigned int maxSize);
  138. /** release OpenGL objects in specified graphics context if State
  139. object is passed, otherwise release OpenGL objects for all graphics context if
  140. State object pointer NULL.*/
  141. void releaseGLObjects(osg::State* state=0) const;
  142. /** Mark our PCSs as needing recompilation.
  143. * Also mark Programs that depend on us as needing relink */
  144. void dirtyShader();
  145. /** If needed, compile the PCS's glShader */
  146. void compileShader(osg::State& state) const;
  147. static Shader::Type getTypeId( const std::string& tname );
  148. public:
  149. /** PerContextShader (PCS) is an OSG-internal encapsulation of glShader per-GL context. */
  150. class OSG_EXPORT PerContextShader : public osg::Referenced
  151. {
  152. public:
  153. PerContextShader(const Shader* shader, unsigned int contextID);
  154. void setDefineString(const std::string& defStr) { _defineStr = defStr; }
  155. const std::string& getDefineString() const { return _defineStr; }
  156. GLuint getHandle() const {return _glShaderHandle;}
  157. void requestCompile();
  158. void compileShader(osg::State& state);
  159. bool needsCompile() const {return _needsCompile;}
  160. bool isCompiled() const {return _isCompiled;}
  161. bool getInfoLog( std::string& infoLog ) const;
  162. /** Attach our glShader to a glProgram */
  163. void attachShader(GLuint program) const;
  164. /** Detach our glShader from a glProgram */
  165. void detachShader(GLuint program) const;
  166. protected: /*methods*/
  167. ~PerContextShader();
  168. protected: /*data*/
  169. /** Pointer to our parent osg::Shader */
  170. const Shader* _shader;
  171. /** Pointer to this context's extension functions. */
  172. osg::ref_ptr<osg::GLExtensions> _extensions;
  173. /** Handle to the actual glShader. */
  174. GLuint _glShaderHandle;
  175. /** Define string passed on to Shaders to help configure them.*/
  176. std::string _defineStr;
  177. /** Does our glShader need to be recompiled? */
  178. bool _needsCompile;
  179. /** Is our glShader successfully compiled? */
  180. bool _isCompiled;
  181. const unsigned int _contextID;
  182. private:
  183. PerContextShader(); // disallowed
  184. PerContextShader(const PerContextShader&); // disallowed
  185. PerContextShader& operator=(const PerContextShader&); // disallowed
  186. };
  187. struct OSG_EXPORT ShaderObjects : public osg::Referenced
  188. {
  189. typedef std::vector< osg::ref_ptr<PerContextShader> > PerContextShaders;
  190. ShaderObjects(const Shader* shader, unsigned int contextID);
  191. unsigned int _contextID;
  192. const Shader* _shader;
  193. mutable PerContextShaders _perContextShaders;
  194. PerContextShader* getPCS(const std::string& defineStr) const;
  195. PerContextShader* createPerContextShader(const std::string& defineStr);
  196. void requestCompile();
  197. };
  198. PerContextShader* getPCS(osg::State& state) const;
  199. protected: /*methods*/
  200. virtual ~Shader();
  201. friend class osg::Program;
  202. bool addProgramRef( osg::Program* program );
  203. bool removeProgramRef( osg::Program* program );
  204. void _computeShaderDefines();
  205. void _parseShaderDefines(const std::string& str, ShaderDefines& defines);
  206. protected: /*data*/
  207. Type _type;
  208. std::string _shaderFileName;
  209. std::string _shaderSource;
  210. osg::ref_ptr<ShaderBinary> _shaderBinary;
  211. CodeInjectionMap _codeInjectionMap;
  212. // ShaderDefines variables
  213. ShaderDefinesMode _shaderDefinesMode;
  214. ShaderDefines _shaderDefines;
  215. ShaderDefines _shaderRequirements;
  216. /** osg::Programs that this osg::Shader is attached to */
  217. typedef std::set< osg::Program* > ProgramSet;
  218. ProgramSet _programSet;
  219. OpenThreads::Mutex _programSetMutex;
  220. mutable osg::buffered_value< osg::ref_ptr<ShaderObjects> > _pcsList;
  221. private:
  222. Shader& operator=(const Shader&); // disallowed
  223. };
  224. class OSG_EXPORT ShaderComponent : public osg::Object
  225. {
  226. public:
  227. ShaderComponent();
  228. ShaderComponent(const ShaderComponent& sc,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  229. META_Object(osg, ShaderComponent);
  230. unsigned int addShader(osg::Shader* shader);
  231. void removeShader(unsigned int i);
  232. osg::Shader* getShader(unsigned int i) { return _shaders[i].get(); }
  233. const osg::Shader* getShader(unsigned int i) const { return _shaders[i].get(); }
  234. unsigned int getNumShaders() const { return static_cast<unsigned int>(_shaders.size()); }
  235. virtual void compileGLObjects(State& state) const;
  236. virtual void resizeGLObjectBuffers(unsigned int maxSize);
  237. virtual void releaseGLObjects(State* state=0) const;
  238. protected:
  239. typedef std::vector< osg::ref_ptr<osg::Shader> > Shaders;
  240. Shaders _shaders;
  241. };
  242. }
  243. #endif