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