Tulip  4.8.0
Better Visualization Through Research
 All Classes Files Functions Variables Enumerations Enumerator Properties Groups Pages
GlShaderProgram.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 ///@cond DOXYGEN_HIDDEN
20 
21 
22 #ifndef GL_SHADER_PROGRAM
23 #define GL_SHADER_PROGRAM
24 
25 #if defined(_MSC_VER)
26 #include <Windows.h>
27 #endif
28 
29 #if defined(__APPLE__)
30 #include <OpenGL/gl.h>
31 #else
32 #include <GL/gl.h>
33 #endif
34 
35 #include <string>
36 #include <vector>
37 
38 #include <tulip/tulipconf.h>
39 #include <tulip/Matrix.h>
40 #include <tulip/Color.h>
41 
42 namespace tlp {
43 
44 enum ShaderType {Vertex, Fragment, Geometry};
45 
46 /**
47  * \brief A class to manage shader objects, components of a shader program
48  *
49  * This class allow to create and compile OpenGL shader object. Shaders are used to program the graphics processing unit (GPU) rendering pipeline.
50  * The three existing types of shaders are managed :
51  *
52  * -> Vertex shader : run once for each vertex given to the graphics processor. The purpose is to transform each vertex's 3D position in virtual space
53  * to the 2D coordinate at which it appears on the screen (as well as a depth value for the Z-buffer).
54  * Vertex shaders can manipulate properties such as position, color, and texture coordinate, but cannot create new vertices.
55  * The output of the vertex shader goes to the next stage in the pipeline, which is either a geometry shader if present or the rasterizer otherwise.
56  *
57  * -> Geometry shader : can add and remove vertices from a mesh. Geometry shaders can be used to generate geometry procedurally
58  * or to add volumetric detail to existing meshes that would be too costly to process on the CPU. If geometry shaders are being used,
59  * the output is then sent to the rasterizer.
60  *
61  * -> Fragment shader (Pixel shader) : calculate the color of individual pixels. The input to this stage comes from the rasterizer,
62  * which fills in the polygons being sent through the graphics pipeline.
63  *
64  * Shaders source codes have to be written with the "OpenGL Shading Language (GLSL)"
65  */
66 class TLP_GL_SCOPE GlShader {
67 
68  friend class GlShaderProgram;
69 
70 public :
71 
72  /**
73  * Vertex and Fragment shader constructor
74  *
75  * Use this constructor to create either a vertex shader or a fragment shader
76  *
77  * \param shaderType Type of the shader to create, Vertex or Fragment
78  */
79  GlShader(ShaderType shaderType);
80 
81  /**
82  * Geometry shader constructor
83  *
84  * Use this constructor to create a geometry shader
85  *
86  * \param inputPrimitiveType the type of graphic primitive the geometry shader takes as input.
87  * (must be one from the following list : GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_EXT, GL_TRIANGLES, GL_TRIANGLES_ADJACENCY_EXT)
88  *
89  * \param outputPrimitiveType the type of graphics primitives the geometry shader will output
90  * (must be one of the following list : GL_POINTS, GL_LINE_STRIP, GL_TRIANGLE_STRIP)
91  */
92  GlShader(GLenum inputPrimitiveType, GLenum outputPrimitiveType);
93 
94  /**
95  * GlShader destructor
96  */
97  ~GlShader();
98 
99  /**
100  * Return the GL identifier of this shader object
101  */
102  GLuint getShaderId() const {
103  return shaderObjectId;
104  }
105 
106  /**
107  * Return the type of the shader (Vertex, Geometry or Fragment)
108  */
109  ShaderType getShaderType() const {
110  return shaderType;
111  }
112 
113 
114  /**
115  * Method only relevant for geometry shaders. Return the graphic primitive type this geometry shader takes as input.
116  */
117  GLenum getInputPrimitiveType() const {
118  return inputPrimitiveType;
119  }
120 
121  /**
122  * Method only relevant for geometry shaders. Return the graphics primitives type this geometry shader will output.
123  */
124  GLenum getOutputPrimitiveType() const {
125  return outputPrimitiveType;
126  }
127 
128  /**
129  * Method only relevant for geometry shaders. Set the graphic primitive type this geometry shader takes as input.
130  * Note that when modifying the input primitive type, the associated shader program (whose object is from type GlShaderProgram)
131  * has to be relinked for changes to take effect.
132  *
133  * \param inputPrimitiveType the type of graphic primitive the geometry shader takes as input.
134  * (must be one from the following list : GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_EXT, GL_TRIANGLES, GL_TRIANGLES_ADJACENCY_EXT)
135  */
136  void setInputPrimitiveType(const GLenum inputPrimitiveType) {
137  this->inputPrimitiveType = inputPrimitiveType;
138  }
139 
140  /**
141  * Method only relevant for geometry shaders. Set the graphics primitives type this geometry shader will output.
142  * Note that when modifying the output primitive type, the associated shader program (whose object is from type GlShaderProgram)
143  * has to be relinked for changes to take effect.
144  *
145  * \param outputPrimitiveType the type of graphics primitives the geometry shader will output
146  * (must be one of the following list : GL_POINTS, GL_LINE_STRIP, GL_TRIANGLE_STRIP)
147  */
148  void setOutputPrimitiveType(const GLenum outputPrimitiveType) {
149  this->outputPrimitiveType = outputPrimitiveType;
150  }
151 
152  /**
153  * Set the shader source code from a C string and compile it.
154  *
155  * \param shaderSrc a C string containing the shader source code
156  */
157  void compileFromSourceCode(const char *shaderSrc);
158 
159  /**
160  * Set the shader source code from a C++ string and compile it.
161  *
162  * \param shaderSrc a C++ string containing the shader source code
163  */
164  void compileFromSourceCode(const std::string &shaderSrc);
165 
166  /**
167  * Set the shader source code from a file and compile it.
168  *
169  * \param shaderSrcFilename the absolute path of the file containing the shader source code
170  */
171  void compileFromSourceFile(const std::string &shaderSrcFilename);
172 
173  /**
174  * Return true if the shader compilation was successfull, false otherwise
175  */
176  bool isCompiled() const {
177  return shaderCompiled;
178  }
179 
180  /**
181  * Return the log output by the shader compiler
182  */
183  std::string getCompilationLog() const {
184  return compilationLog;
185  }
186 
187 private :
188 
189  void setAnonymousCreation(const bool anonymousCreation) {
190  this->anonymousCreation = anonymousCreation;
191  }
192  bool anonymouslyCreated() const {
193  return anonymousCreation;
194  }
195 
196  void compileShaderObject(const char *shaderSrc);
197 
198  ShaderType shaderType;
199  GLuint shaderObjectId;
200  GLenum inputPrimitiveType, outputPrimitiveType;
201  bool shaderCompiled;
202  std::string compilationLog;
203  bool anonymousCreation;
204 
205 };
206 
207 /**
208  * \brief A class to manage OpenGL shader program.
209  *
210  * This class allows to create and use shader programs by linking several shader objects. At least one shader object must be
211  * provided in order to use the shader program. Multiple shader objects of the same type can be added but exactly one
212  * of these shader objects must have a main() function. As in C, in order to use a function defined in a separate shader object
213  * from another shader object, this function has to be declared with the same prototype in the source code of the last one.
214  *
215  * This class also allows to specify uniform and attribute variables values of the shader program.
216  */
217 class TLP_GL_SCOPE GlShaderProgram {
218 
219 public :
220 
221  /**
222  * GlShaderProgram constructor
223  *
224  * \param name An optionnal name can be provided to identify the shader program
225  */
226  GlShaderProgram(const std::string &name = "");
227 
228  /**
229  * GlShaderProgram destructor
230  */
231  ~GlShaderProgram();
232 
233  /**
234  * A static function which returns true if vertex and fragment shaders are supported by the host graphic card
235  */
236  static bool shaderProgramsSupported();
237 
238  /**
239  * A static function which returns true if geometry shaders are supported by the host graphic card
240  */
241  static bool geometryShaderSupported();
242 
243  /**
244  * A static function which returns the current active shader if any
245  */
246  static GlShaderProgram *getCurrentActiveShader();
247 
248  /**
249  * Return the string identifier of this shader program
250  */
251  std::string getName() const {
252  return programName;
253  }
254 
255  /**
256  * Return the OpenGL identifier of this shader program
257  */
258  GLuint getShaderProgramId() const {
259  return programObjectId;
260  }
261 
262  /**
263  * Add a shader object to this shader program
264  *
265  * \param shader the shader object to add to this shader program
266  */
267  void addShader(GlShader *shader);
268 
269  /**
270  * Remove a shader object from this shader program
271  * Note that the shader object will not be destroyed
272  *
273  * \param shader the shader object to remove from this shader program
274  */
275  void removeShader(GlShader *shader);
276 
277  /**
278  * remove all shaders from this shader program
279  */
280  void removeAllShaders();
281 
282  /**
283  * Convenient method to add a shader object (from type Vertex or Fragment) from a source code stored in a C string
284  * The created shader object will be automatically destroyed when removing all attached shader objects
285  * or destroying the shader program
286  *
287  * \param shaderType the type of the shader object to add (must be Vertex or Fragment)
288  * \param shaderSrc the C string containing the shader object source code
289  */
290  void addShaderFromSourceCode(const ShaderType shaderType, const char *shaderSrc);
291 
292  /**
293  * Convenient method to add a shader object (from type Vertex or Fragment) from a source code stored in a C++ string
294  * The created shader object will be automatically destroyed when removing all attached shader objects
295  * or destroying the shader program
296  *
297  * \param shaderType the type of the shader object to add (must be Vertex or Fragment)
298  * \param shaderSrc the C++ string containing the shader object source code
299  */
300  void addShaderFromSourceCode(const ShaderType shaderType, const std::string &shaderSrc);
301 
302  /**
303  * Convenient method to add a shader object (from type Vertex or Fragment) from a source code stored in a file
304  * The created shader object will be automatically destroyed when removing all attached shader objects
305  * or destroying the shader program
306  *
307  * \param shaderType the type of the shader object to add (must be Vertex or Fragment)
308  * \param shaderSrcFilename the aboslute path to the file containing the shader object source code
309  */
310  void addShaderFromSourceFile(const ShaderType shaderType, const std::string &shaderSrcFilename);
311 
312  /**
313  * Convenient method to add a geometry shader object from a source code stored in a C string
314  * The created shader object will be automatically destroyed when removing all attached shader objects
315  * or destroying the shader program
316  *
317  * \param geometryShaderSrc the C string containing the geometry shader object source code
318  * \param inputPrimitiveType the type of graphic primitive the geometry shader takes as input.
319  * (must be one from the following list : GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_EXT, GL_TRIANGLES, GL_TRIANGLES_ADJACENCY_EXT)
320  *
321  * \param outputPrimitiveType the type of graphics primitives the geometry shader will output
322  * (must be one of the following list : GL_POINTS, GL_LINE_STRIP, GL_TRIANGLE_STRIP)
323  */
324  void addGeometryShaderFromSourceCode(const char *geometryShaderSrc, GLenum inputPrimitiveType, GLenum outputPrimitiveType);
325 
326  /**
327  * Convenient method to add a geometry shader object from a source code stored in a C++ string
328  * The created shader object will be automatically destroyed when removing all attached shader objects
329  * or destroying the shader program
330  *
331  * \param geometryShaderSrc the C++ string containing the geometry shader object source code
332  * \param inputPrimitiveType the type of graphic primitive the geometry shader takes as input.
333  * (must be one from the following list : GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_EXT, GL_TRIANGLES, GL_TRIANGLES_ADJACENCY_EXT)
334  *
335  * \param outputPrimitiveType the type of graphics primitives the geometry shader will output
336  * (must be one of the following list : GL_POINTS, GL_LINE_STRIP, GL_TRIANGLE_STRIP)
337  */
338  void addGeometryShaderFromSourceCode(const std::string &geometryShaderSrc, GLenum inputPrimitiveType, GLenum outputPrimitiveType);
339 
340  /**
341  * Convenient method to add a geometry shader object from a source code stored in a file
342  * The created shader object will be automatically destroyed when removing all attached shader objects
343  * or destroying the shader program
344  *
345  * \param geometryShaderSrcFilename the absolute path to the file containing the geometry shader object source code
346  * \param inputPrimitiveType the type of graphic primitive the geometry shader takes as input.
347  * (must be one from the following list : GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_EXT, GL_TRIANGLES, GL_TRIANGLES_ADJACENCY_EXT)
348  *
349  * \param outputPrimitiveType the type of graphics primitives the geometry shader will output
350  * (must be one of the following list : GL_POINTS, GL_LINE_STRIP, GL_TRIANGLE_STRIP)
351  */
352  void addGeometryShaderFromSourceFile(const std::string &geometryShaderSrcFilename, GLenum inputPrimitiveType, GLenum outputPrimitiveType);
353 
354  /**
355  * Link the shader program.
356  */
357  void link();
358 
359  /**
360  * return true if the shader program has been successfully linked, false otherwise
361  */
362  bool isLinked() const {
363  return programLinked;
364  }
365 
366  /**
367  * Print the info log containing errors and warnings related to shader objects compilation and shader program linkage
368  */
369  void printInfoLog();
370 
371  /**
372  * Activate the shader program. If the shader program has not been linked, the link method will be called.
373  */
374  void activate();
375 
376  /**
377  * Deactivate the shader program.
378  */
379  void desactivate();
380 
381  void setUniformFloat(const std::string &variateName, const float f);
382  void setUniformVec2Float(const std::string &variableName, const Vector<float, 2> &vec2f);
383  void setUniformVec2Float(const std::string &variableName, const float f1, const float f2);
384  void setUniformVec3Float(const std::string &variableName, const Vector<float, 3> &vec3f);
385  void setUniformVec3Float(const std::string &variableName, const float f1, const float f2, const float f3);
386  void setUniformVec4Float(const std::string &variableName, const Vector<float, 4> &vec4f);
387  void setUniformVec4Float(const std::string &variableName, const float f1, const float f2, const float f3, const float f4);
388  void setUniformMat2Float(const std::string &variableName, const Matrix<float, 2> &mat2f, const bool transpose = false);
389  void setUniformMat2Float(const std::string &variableName, const float *f, const bool transpose = false);
390  void setUniformMat3Float(const std::string &variableName, const Matrix<float, 3> &mat3f, const bool transpose = false);
391  void setUniformMat3Float(const std::string &variableName, const float *f, const bool transpose = false);
392  void setUniformMat4Float(const std::string &variableName, const Matrix<float, 4> &mat4f, const bool transpose = false);
393  void setUniformMat4Float(const std::string &variableName, const float *f, const bool transpose = false);
394 
395  void setUniformInt(const std::string &variableName, const int f);
396  void setUniformVec2Int(const std::string &variableName, const Vector<int, 2> &vec2i);
397  void setUniformVec2Int(const std::string &variableName, const int i1, const int i2);
398  void setUniformVec3Int(const std::string &variableName, const Vector<int, 3> &vec3i);
399  void setUniformVec3Int(const std::string &variableName, const int i1, const int i2, const int i3);
400  void setUniformVec4Int(const std::string &variableName, const Vector<int, 4> &vec4i);
401  void setUniformVec4Int(const std::string &variableName, const int i1, const int i2, const int i3, const int i4);
402 
403  void setUniformBool(const std::string &variableName, const bool b);
404  void setUniformVec2Bool(const std::string &variableName, const Array<bool, 2> &vec2b);
405  void setUniformVec2Bool(const std::string &variableName, const bool b1, const bool b2);
406  void setUniformVec3Bool(const std::string &variableName, const Array<bool, 3> &vec3b);
407  void setUniformVec3Bool(const std::string &variableName, const bool b1, const bool b2, const bool b3);
408  void setUniformVec4Bool(const std::string &variableName, const Array<bool, 4> &vec4b);
409  void setUniformVec4Bool(const std::string &variableName, const bool i1, const bool i2, const bool i3, const bool i4);
410 
411  void setAttributeFloat(const std::string &variableName, const float f);
412  void setAttributeVec2Float(const std::string &variableName, const Vector<float, 2> &vec2f);
413  void setAttributeVec2Float(const std::string &variableName, const float f1, const float f2);
414  void setAttributeVec3Float(const std::string &variableName, const Vector<float, 3> &vec3f);
415  void setAttributeVec3Float(const std::string &variableName, const float f1, const float f2, const float f3);
416  void setAttributeVec4Float(const std::string &variableName, const Vector<float, 4> &vec4f);
417  void setAttributeVec4Float(const std::string &variableName, const float f1, const float f2, const float f3, const float f4);
418 
419  void setAttributeInt(const std::string &variableName, const int f);
420  void setAttributeVec2Int(const std::string &variableName, const Vector<int, 2> &vec2i);
421  void setAttributeVec2Int(const std::string &variableName, const int i1, const int i2);
422  void setAttributeVec3Int(const std::string &variableName, const Vector<int, 3> &vec3i);
423  void setAttributeVec3Int(const std::string &variableName, const int i1, const int i2, const int i3);
424  void setAttributeVec4Int(const std::string &variableName, const Vector<int, 4> &vec4i);
425  void setAttributeVec4Int(const std::string &variableName, const int i1, const int i2, const int i3, const int i4);
426 
427  void setAttributeBool(const std::string &variableName, const bool b);
428  void setAttributeVec2Bool(const std::string &variableName, const Array<bool, 2> &vec2b);
429  void setAttributeVec2Bool(const std::string &variableName, const bool b1, const bool b2);
430  void setAttributeVec3Bool(const std::string &variableName, const Array<bool, 3> &vec3b);
431  void setAttributeVec3Bool(const std::string &variableName, const bool b1, const bool b2, const bool b3);
432  void setAttributeVec4Bool(const std::string &variableName, const Array<bool, 4> &vec4b);
433  void setAttributeVec4Bool(const std::string &variableName, const bool b1, const bool b2, const bool b3, const bool b4);
434 
435  void setUniformTextureSampler(const std::string &samplerVariateName, const int samplerId);
436  void setUniformColor(const std::string &variableName, const Color &color);
437  void setAttributeColor(const std::string &variableName, const Color &color);
438 
439  template <unsigned int SIZE>
440  void setUniformFloatArray(const std::string &variableName, const Vector<float, SIZE> &vecf);
441  void setUniformFloatArray(const std::string &variableName, const unsigned int fCount, const float *f);
442 
443  template <unsigned int SIZE>
444  void setUniformVec2FloatArray(const std::string &variableName, const Array<Vector<float, 2>, SIZE> &vecvec2f);
445  void setUniformVec2FloatArray(const std::string &variableName, const unsigned int vec2fCount, const float *f);
446 
447  template <unsigned int SIZE>
448  void setUniformVec3FloatArray(const std::string &variableName, const Array<Vector<float, 3>, SIZE> &vecvec3f);
449  void setUniformVec3FloatArray(const std::string &variableName, const unsigned int vec3fCount, const float *f);
450 
451  template <unsigned int SIZE>
452  void setUniformVec4FloatArray(const std::string &variableName, const Array<Vector<float, 4>, SIZE> &vecvec4f);
453  void setUniformVec4FloatArray(const std::string &variableName, const unsigned int vec4fCount, const float *f);
454 
455  template <unsigned int SIZE>
456  void setUniformMat2FloatArray(const std::string &variableName, const Vector<Matrix<float, 2>, SIZE> &vecmat2f, const bool transpose = false);
457  void setUniformMat2FloatArray(const std::string &variableName, const unsigned int mat2fCount, const float *f, const bool transpose = false);
458 
459  template <unsigned int SIZE>
460  void setUniformMat3FloatArray(const std::string &variableName, const Vector<Matrix<float, 3>, SIZE> &vecmat3f, const bool transpose = false);
461  void setUniformMat3FloatArray(const std::string &variableName, const unsigned int mat3fCount, const float *f, const bool transpose = false);
462 
463  template <unsigned int SIZE>
464  void setUniformMat4FloatArray(const std::string &variableName, const Vector<Matrix<float, 4>, SIZE> &vecmat4f, const bool transpose = false);
465  void setUniformMat4FloatArray(const std::string &variableName, const unsigned int mat4fCount, const float *f, const bool transpose = false);
466 
467  template <unsigned int SIZE>
468  void setUniformIntArray(const std::string &variableName, const Vector<int, SIZE> &veci);
469  void setUniformIntArray(const std::string &variableName, const unsigned int iCount, const int *i);
470 
471  template <unsigned int SIZE>
472  void setUniformVec2IntArray(const std::string &variableName, const Array<Vector<int, 2>, SIZE> &vecvec2i);
473  void setUniformVec2IntArray(const std::string &variableName, const unsigned int vec2iCount, const int *i);
474 
475  template <unsigned int SIZE>
476  void setUniformVec3IntArray(const std::string &variableName, const Array<Vector<int, 3>, SIZE> &vecvec3i);
477  void setUniformVec3IntArray(const std::string &variableName, const unsigned int vec3iCount, const int *i);
478 
479  template <unsigned int SIZE>
480  void setUniformVec4IntArray(const std::string &variableName, const Array<Vector<int, 4>, SIZE> &vecvec4i);
481  void setUniformVec4IntArray(const std::string &variableName, const unsigned int vec4iCount, const int *i);
482 
483  template <unsigned int SIZE>
484  void setUniformBoolArray(const std::string &variableName, const Array<bool, SIZE> &vecb);
485  void setUniformBoolArray(const std::string &variableName, const unsigned int bCount, const bool *b);
486 
487  template <unsigned int SIZE>
488  void setUniformVec2BoolArray(const std::string &variableName, const Array<Array<bool, 2>, SIZE> &vecvec2b);
489  void setUniformVec2BoolArray(const std::string &variableName, const unsigned int vec2bCount, const bool *b);
490 
491  template <unsigned int SIZE>
492  void setUniformVec3BoolArray(const std::string &variableName, const Array<Array<bool, 3>, SIZE> &vecvec3b);
493  void setUniformVec3BoolArray(const std::string &variableName, const unsigned int vec3bCount, const bool *b);
494 
495  template <unsigned int SIZE>
496  void setUniformVec4BoolArray(const std::string &variableName, const Array<Array<bool, 4>, SIZE> &vecvec4b);
497  void setUniformVec4BoolArray(const std::string &variableName, const unsigned int vec4bCount, const bool *b);
498 
499  void getUniformFloatVariableValue(const std::string &variableName, float *value);
500  void getUniformIntVariableValue(const std::string &variableName, int *value);
501  void getUniformBoolVariableValue(const std::string &variableName, bool *value);
502  void getUniformVec2BoolVariableValue(const std::string &variableName, bool *value);
503  void getUniformVec3BoolVariableValue(const std::string &variableName, bool *value);
504  void getUniformVec4BoolVariableValue(const std::string &variableName, bool *value);
505 
506  // This method must be called before calling the link method to
507  // set the max number of vertices a geometry shader can output
508  // If not called, the maximum value is set when linking the shader program (not recommended for performance).
509  void setMaxGeometryShaderOutputVertices(const int maxOutputVertices);
510 
511 private :
512 
513  GLint getUniformVariableLocation(const std::string &variableName);
514  GLint getAttributeVariableLocation(const std::string &variableName);
515 
516  std::string programName;
517  GLuint programObjectId;
518 
519  std::string programLinkLog;
520  bool programLinked;
521 
522  std::vector<GlShader *> attachedShaders;
523  int maxGeometryShaderOutputVertices;
524 
525  static GlShaderProgram *currentActiveShaderProgram;
526 
527 
528 
529 };
530 
531 }
532 
533 #endif // GL_SHADER_PROGRAM
534 ///@endcond