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