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