0031096: Visualization, TKOpenGl - support metallic-roughness texture mapping
[occt.git] / src / OpenGl / OpenGl_ShaderProgram.hxx
1 // Created on: 2013-09-19
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _OpenGl_ShaderProgram_Header
17 #define _OpenGl_ShaderProgram_Header
18
19 #include <NCollection_DataMap.hxx>
20 #include <NCollection_Sequence.hxx>
21 #include <TCollection_AsciiString.hxx>
22
23 #include <Graphic3d_ShaderObject.hxx>
24 #include <Graphic3d_ShaderProgram.hxx>
25 #include <Graphic3d_TextureSetBits.hxx>
26
27 #include <OpenGl_Vec.hxx>
28 #include <OpenGl_Matrix.hxx>
29 #include <OpenGl_NamedResource.hxx>
30 #include <OpenGl_ShaderObject.hxx>
31
32 class OpenGl_ShaderProgram;
33 DEFINE_STANDARD_HANDLE(OpenGl_ShaderProgram, OpenGl_NamedResource)
34
35 //! The enumeration of OCCT-specific OpenGL/GLSL variables.
36 enum OpenGl_StateVariable
37 {
38   // OpenGL matrix state
39   OpenGl_OCC_MODEL_WORLD_MATRIX,
40   OpenGl_OCC_WORLD_VIEW_MATRIX,
41   OpenGl_OCC_PROJECTION_MATRIX,
42   OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE,
43   OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE,
44   OpenGl_OCC_PROJECTION_MATRIX_INVERSE,
45   OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE,
46   OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE,
47   OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE,
48   OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE,
49   OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE,
50   OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE,
51
52   // OpenGL clip planes state
53   OpenGl_OCC_CLIP_PLANE_EQUATIONS,
54   OpenGl_OCC_CLIP_PLANE_CHAINS,
55   OpenGl_OCC_CLIP_PLANE_COUNT,
56
57   // OpenGL light state
58   OpenGl_OCC_LIGHT_SOURCE_COUNT,
59   OpenGl_OCC_LIGHT_SOURCE_TYPES,
60   OpenGl_OCC_LIGHT_SOURCE_PARAMS,
61   OpenGl_OCC_LIGHT_AMBIENT,
62
63   // Material state
64   OpenGl_OCCT_TEXTURE_ENABLE,
65   OpenGl_OCCT_DISTINGUISH_MODE,
66   OpenGl_OCCT_PBR_FRONT_MATERIAL,
67   OpenGl_OCCT_PBR_BACK_MATERIAL,
68   OpenGl_OCCT_COMMON_FRONT_MATERIAL,
69   OpenGl_OCCT_COMMON_BACK_MATERIAL,
70   OpenGl_OCCT_ALPHA_CUTOFF,
71   OpenGl_OCCT_COLOR,
72
73   // Weighted, Blended Order-Independent Transparency rendering state
74   OpenGl_OCCT_OIT_OUTPUT,
75   OpenGl_OCCT_OIT_DEPTH_FACTOR,
76
77   // Context-dependent state
78   OpenGl_OCCT_TEXTURE_TRSF2D,
79   OpenGl_OCCT_POINT_SIZE,
80
81   // Wireframe state
82   OpenGl_OCCT_VIEWPORT,
83   OpenGl_OCCT_LINE_WIDTH,
84   OpenGl_OCCT_LINE_FEATHER,
85   OpenGl_OCCT_LINE_STIPPLE_PATTERN, // occStipplePattern
86   OpenGl_OCCT_LINE_STIPPLE_FACTOR,  // occStippleFactor
87   OpenGl_OCCT_WIREFRAME_COLOR,
88   OpenGl_OCCT_QUAD_MODE_STATE,
89
90   // Parameters of outline (silhouette) shader
91   OpenGl_OCCT_ORTHO_SCALE,
92   OpenGl_OCCT_SILHOUETTE_THICKNESS,
93
94   // PBR state
95   OpenGl_OCCT_NB_SPEC_IBL_LEVELS,
96
97   // DON'T MODIFY THIS ITEM (insert new items before it)
98   OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
99 };
100
101 //! Interface for generic setter of user-defined uniform variables.
102 struct OpenGl_SetterInterface
103 {
104   //! Sets user-defined uniform variable to specified program.
105   virtual void Set (const Handle(OpenGl_Context)&           theCtx,
106                     const Handle(Graphic3d_ShaderVariable)& theVariable,
107                     OpenGl_ShaderProgram*                   theProgram) = 0;
108
109   //! Destructor
110   virtual ~OpenGl_SetterInterface() {}
111 };
112
113 //! List of OpenGL shader objects.
114 typedef NCollection_Sequence<Handle(OpenGl_ShaderObject)>    OpenGl_ShaderList;
115
116 //! List of shader variable setters.
117 typedef NCollection_DataMap<size_t, OpenGl_SetterInterface*> OpenGl_SetterList;
118
119 //! Support tool for setting user-defined uniform variables.
120 class OpenGl_VariableSetterSelector
121 {
122 public:
123
124   //! Creates new setter selector.
125   OpenGl_VariableSetterSelector();
126
127   //! Releases memory resources of setter selector.
128   ~OpenGl_VariableSetterSelector();
129
130   //! Sets user-defined uniform variable to specified program.
131   void Set (const Handle(OpenGl_Context)&           theCtx,
132             const Handle(Graphic3d_ShaderVariable)& theVariable,
133             OpenGl_ShaderProgram*                   theProgram) const;
134
135 private:
136
137   //! List of variable setters.
138   OpenGl_SetterList mySetterList;
139 };
140
141 //! Defines types of uniform state variables.
142 enum OpenGl_UniformStateType
143 {
144   OpenGl_LIGHT_SOURCES_STATE,
145   OpenGl_CLIP_PLANES_STATE,
146   OpenGl_MODEL_WORLD_STATE,
147   OpenGl_WORLD_VIEW_STATE,
148   OpenGl_PROJECTION_STATE,
149   OpenGl_MATERIAL_STATE,
150   OpenGl_SURF_DETAIL_STATE,
151   OpenGL_OIT_STATE,
152   OpenGl_UniformStateType_NB
153 };
154
155 //! Simple class represents GLSL program variable location.
156 class OpenGl_ShaderUniformLocation
157 {
158 public:
159   //! Invalid location of uniform/attribute variable.
160   static const GLint INVALID_LOCATION = -1;
161 public:
162
163   //! Construct an invalid location.
164   OpenGl_ShaderUniformLocation() : myLocation (INVALID_LOCATION) {}
165
166   //! Constructor with initialization.
167   explicit OpenGl_ShaderUniformLocation (GLint theLocation) : myLocation (theLocation) {}
168
169   //! Note you may safely put invalid location in functions like glUniform* - the data passed in will be silently ignored.
170   //! @return true if location is not equal to -1.
171   bool IsValid() const { return myLocation != INVALID_LOCATION; }
172
173   //! Return TRUE for non-invalid location.
174   operator bool() const { return myLocation != INVALID_LOCATION; }
175
176   //! Convert operators help silently put object to GL functions like glUniform*.
177   operator GLint() const { return myLocation; }
178
179 private:
180   GLint myLocation;
181 };
182
183 //! Wrapper for OpenGL program object.
184 class OpenGl_ShaderProgram : public OpenGl_NamedResource
185 {
186   friend class OpenGl_View;
187   friend class OpenGl_ShaderManager;
188   DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_NamedResource)
189 public:
190
191   //! Non-valid shader name.
192   static const GLuint NO_PROGRAM = 0;
193
194   //! Invalid location of uniform/attribute variable.
195   static const GLint INVALID_LOCATION = -1;
196
197   //! List of pre-defined OCCT state uniform variables.
198   static Standard_CString PredefinedKeywords[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];
199
200   //! Wrapper for compiling shader object with verbose printing on error.
201   Standard_EXPORT static bool compileShaderVerbose (const Handle(OpenGl_Context)& theCtx,
202                                                     const Handle(OpenGl_ShaderObject)& theShader,
203                                                     const TCollection_AsciiString& theSource,
204                                                     bool theToPrintSource = true);
205
206   //! Creates uninitialized shader program.
207   //!
208   //! WARNING! This constructor is not intended to be called anywhere but from OpenGl_ShaderManager::Create().
209   //! Manager has been designed to synchronize camera position, lights definition and other aspects of the program implicitly,
210   //! as well as sharing same program across rendering groups.
211   //!
212   //! Program created outside the manager will be left detached from these routines,
213   //! and them should be performed manually by caller.
214   //!
215   //! This constructor has been made public to provide more flexibility to re-use OCCT OpenGL classes without OCCT Viewer itself.
216   //! If this is not the case - create the program using shared OpenGl_ShaderManager instance instead.
217   Standard_EXPORT OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy = NULL,
218                                         const TCollection_AsciiString& theId = "");
219
220 protected:
221
222   static OpenGl_VariableSetterSelector mySetterSelector;
223
224 public:
225
226   //! Releases resources of shader program.
227   Standard_EXPORT virtual ~OpenGl_ShaderProgram();
228
229   //! Creates new empty shader program of specified type.
230   Standard_EXPORT Standard_Boolean Create (const Handle(OpenGl_Context)& theCtx);
231
232   //! Destroys shader program.
233   Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE;
234
235   //! Returns estimated GPU memory usage - cannot be easily estimated.
236   virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE { return 0; }
237
238   //! Attaches shader object to the program object.
239   Standard_EXPORT Standard_Boolean AttachShader (const Handle(OpenGl_Context)&      theCtx,
240                                                  const Handle(OpenGl_ShaderObject)& theShader);
241
242   //! Detaches shader object to the program object.
243   Standard_EXPORT Standard_Boolean DetachShader (const Handle(OpenGl_Context)&      theCtx,
244                                                  const Handle(OpenGl_ShaderObject)& theShader);
245
246   //! Initializes program object with the list of shader objects.
247   Standard_EXPORT Standard_Boolean Initialize (const Handle(OpenGl_Context)&     theCtx,
248                                                const Graphic3d_ShaderObjectList& theShaders);
249
250   //! Links the program object.
251   //! @param theCtx bound OpenGL context
252   //! @param theIsVerbose flag to print log on error
253   Standard_EXPORT Standard_Boolean Link (const Handle(OpenGl_Context)& theCtx,
254                                          bool theIsVerbose = true);
255
256   //! Fetches information log of the last link operation.
257   Standard_EXPORT Standard_Boolean FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
258                                                  TCollection_AsciiString&      theLog);
259
260   //! Fetches uniform variables from proxy shader program.
261   Standard_EXPORT Standard_Boolean ApplyVariables (const Handle(OpenGl_Context)& theCtx);
262
263   //! @return true if current object was initialized
264   inline bool IsValid() const
265   {
266     return myProgramID != NO_PROGRAM;
267   }
268
269   //! @return program ID
270   inline GLuint ProgramId() const
271   {
272     return myProgramID;
273   }
274
275 public:
276
277   //! Return TRUE if program defines tessellation stage.
278   Standard_Boolean HasTessellationStage() const { return myHasTessShader; }
279
280   //! Return the length of array of light sources (THE_MAX_LIGHTS),
281   //! to be used for initialization occLightSources (OpenGl_OCC_LIGHT_SOURCE_PARAMS).
282   Standard_Integer NbLightsMax() const { return myNbLightsMax; }
283
284   //! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES),
285   //! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS) and occClipPlaneChains (OpenGl_OCC_CLIP_PLANE_CHAINS).
286   Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; }
287
288   //! Return the length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS),
289   //! to be used for initialization occFragColorArray/occFragColorN.
290   Standard_Integer NbFragmentOutputs() const { return myNbFragOutputs; }
291
292   //! Return true if Fragment Shader should perform alpha test; FALSE by default.
293   Standard_Boolean HasAlphaTest() const { return myHasAlphaTest; }
294
295   //! Return true if Fragment Shader color should output the weighted OIT coverage; FALSE by default.
296   Standard_Boolean HasWeightOitOutput() const { return myHasWeightOitOutput; }
297
298   //! Return texture units declared within the program, @sa Graphic3d_TextureSetBits.
299   Standard_Integer TextureSetBits() const { return myTextureSetBits; }
300
301 private:
302
303   //! Returns index of last modification of variables of specified state type.
304   Standard_Size ActiveState (const OpenGl_UniformStateType theType) const
305   {
306     return theType < OpenGl_UniformStateType_NB
307          ? myCurrentState[theType]
308          : 0;
309   }
310
311   //! Updates index of last modification of variables of specified state type.
312   void UpdateState (const OpenGl_UniformStateType theType,
313                     const Standard_Size           theIndex)
314   {
315     if (theType < OpenGl_UniformStateType_NB)
316     {
317       myCurrentState[theType] = theIndex;
318     }
319   }
320
321 public:
322
323   //! Returns location of the specific uniform variable.
324   Standard_EXPORT OpenGl_ShaderUniformLocation GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
325                                                                    const GLchar*                 theName) const;
326
327   //! Returns index of the generic vertex attribute by variable name.
328   Standard_EXPORT GLint GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
329                                               const GLchar*                 theName) const;
330
331   //! Returns location of the OCCT state uniform variable.
332   const OpenGl_ShaderUniformLocation& GetStateLocation (OpenGl_StateVariable theVariable) const { return myStateLocations[theVariable]; }
333
334 public:
335
336   //! Returns the value of the integer uniform variable.
337   Standard_EXPORT Standard_Boolean GetUniform (const Handle(OpenGl_Context)& theCtx,
338                                                const GLchar*                 theName,
339                                                OpenGl_Vec4i&                 theValue) const;
340
341   Standard_EXPORT Standard_Boolean GetUniform (const Handle(OpenGl_Context)& theCtx,
342                                                GLint                         theLocation,
343                                                OpenGl_Vec4i&                 theValue) const;
344
345   //! Returns the value of the float uniform variable.
346   Standard_EXPORT Standard_Boolean GetUniform (const Handle(OpenGl_Context)& theCtx,
347                                                const GLchar*                 theName,
348                                                OpenGl_Vec4&                  theValue) const;
349
350   //! Returns the value of the float uniform variable.
351   Standard_EXPORT Standard_Boolean GetUniform (const Handle(OpenGl_Context)& theCtx,
352                                                GLint                         theLocation,
353                                                OpenGl_Vec4&                  theValue) const;
354
355 public:
356
357   //! Returns the integer vertex attribute.
358   Standard_EXPORT Standard_Boolean GetAttribute (const Handle(OpenGl_Context)& theCtx,
359                                                  const GLchar*                 theName,
360                                                  OpenGl_Vec4i&                 theValue) const;
361
362   //! Returns the integer vertex attribute.
363   Standard_EXPORT Standard_Boolean GetAttribute (const Handle(OpenGl_Context)& theCtx,
364                                                  GLint                         theIndex,
365                                                  OpenGl_Vec4i&                 theValue) const;
366
367   //! Returns the float vertex attribute.
368   Standard_EXPORT Standard_Boolean GetAttribute (const Handle(OpenGl_Context)& theCtx,
369                                                  const GLchar*                 theName,
370                                                  OpenGl_Vec4&                  theValue) const;
371
372   //! Returns the float vertex attribute.
373   Standard_EXPORT Standard_Boolean GetAttribute (const Handle(OpenGl_Context)& theCtx,
374                                                  GLint                         theIndex,
375                                                  OpenGl_Vec4&                  theValue) const;
376
377 public:
378
379   //! Wrapper for glBindAttribLocation()
380   Standard_EXPORT Standard_Boolean SetAttributeName (const Handle(OpenGl_Context)& theCtx,
381                                                      GLint                         theIndex,
382                                                      const GLchar*                 theName);
383
384   //! Wrapper for glVertexAttrib1f()
385   Standard_EXPORT Standard_Boolean SetAttribute (const Handle(OpenGl_Context)& theCtx,
386                                                  const GLchar*                 theName,
387                                                  GLfloat                       theValue);
388
389   //! Wrapper for glVertexAttrib1f()
390   Standard_EXPORT Standard_Boolean SetAttribute (const Handle(OpenGl_Context)& theCtx,
391                                                  GLint                         theIndex,
392                                                  GLfloat                       theValue);
393
394   //! Wrapper for glVertexAttrib2fv()
395   Standard_EXPORT Standard_Boolean SetAttribute (const Handle(OpenGl_Context)& theCtx,
396                                                  const GLchar*                 theName,
397                                                  const OpenGl_Vec2&            theValue);
398
399   //! Wrapper for glVertexAttrib2fv()
400   Standard_EXPORT Standard_Boolean SetAttribute (const Handle(OpenGl_Context)& theCtx,
401                                                  GLint                         theIndex,
402                                                  const OpenGl_Vec2&            theValue);
403
404   //! Wrapper for glVertexAttrib3fv()
405   Standard_EXPORT Standard_Boolean SetAttribute (const Handle(OpenGl_Context)& theCtx,
406                                                  const GLchar*                 theName,
407                                                  const OpenGl_Vec3&            theValue);
408
409   //! Wrapper for glVertexAttrib3fv()
410   Standard_EXPORT Standard_Boolean SetAttribute (const Handle(OpenGl_Context)& theCtx,
411                                                  GLint                         theIndex,
412                                                  const OpenGl_Vec3&            theValue);
413
414   //! Wrapper for glVertexAttrib4fv()
415   Standard_EXPORT Standard_Boolean SetAttribute (const Handle(OpenGl_Context)& theCtx,
416                                                  const GLchar*                 theName,
417                                                  const OpenGl_Vec4&            theValue);
418
419   //! Wrapper for glVertexAttrib4fv()
420   Standard_EXPORT Standard_Boolean SetAttribute (const Handle(OpenGl_Context)& theCtx,
421                                                  GLint                         theIndex,
422                                                  const OpenGl_Vec4&            theValue);
423
424 public:
425
426   //! Specifies the value of the integer uniform variable.
427   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
428                                                const GLchar*                 theName,
429                                                GLint                         theValue);
430
431   //! Specifies the value of the integer uniform variable.
432   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
433                                                GLint                         theLocation,
434                                                GLint                         theValue);
435
436   //! Specifies the value of the integer uniform 2D vector.
437   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
438                                                const GLchar*                 theName,
439                                                const OpenGl_Vec2i&           theValue);
440
441   //! Specifies the value of the integer uniform 2D vector.
442   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
443                                                GLint                         theLocation,
444                                                const OpenGl_Vec2i&           theValue);
445
446   //! Specifies the value of the integer uniform 3D vector.
447   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
448                                                const GLchar*                 theName,
449                                                const OpenGl_Vec3i&           theValue);
450
451   //! Specifies the value of the integer uniform 3D vector.
452   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
453                                                GLint                         theLocation,
454                                                const OpenGl_Vec3i&           theValue);
455
456   //! Specifies the value of the integer uniform 4D vector.
457   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
458                                                const GLchar*                 theName,
459                                                const OpenGl_Vec4i&           theValue);
460
461   //! Specifies the value of the integer uniform 4D vector.
462   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
463                                                GLint                         theLocation,
464                                                const OpenGl_Vec4i&           theValue);
465
466 public:
467
468   //! Specifies the value of the unsigned integer uniform 2D vector (uvec2).
469   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
470                                                const GLchar*                 theName,
471                                                const OpenGl_Vec2u&           theValue);
472
473   //! Specifies the value of the unsigned integer uniform 2D vector (uvec2).
474   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
475                                                GLint                         theLocation,
476                                                const OpenGl_Vec2u&           theValue);
477
478   //! Specifies the value of the uvec2 uniform array
479   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
480                                                const GLchar*                 theName,
481                                                const GLsizei                 theCount,
482                                                const OpenGl_Vec2u*           theValue);
483
484   //! Specifies the value of the uvec2 uniform array
485   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
486                                                GLint                         theLocation,
487                                                const GLsizei                 theCount,
488                                                const OpenGl_Vec2u*           theValue);
489
490 public:
491
492   //! Specifies the value of the float uniform variable.
493   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
494                                                const GLchar*                 theName,
495                                                GLfloat                       theValue);
496
497   //! Specifies the value of the float uniform variable.
498   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
499                                                GLint                         theLocation,
500                                                GLfloat                       theValue);
501
502   //! Specifies the value of the float uniform 2D vector.
503   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
504                                                const GLchar*                 theName,
505                                                const OpenGl_Vec2&            theValue);
506
507   //! Specifies the value of the float uniform 2D vector.
508   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
509                                                GLint                         theLocation,
510                                                const OpenGl_Vec2&            theValue);
511
512   //! Specifies the value of the float uniform 3D vector.
513   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
514                                                const GLchar*                 theName,
515                                                const OpenGl_Vec3&            theValue);
516
517   //! Specifies the value of the float uniform 3D vector.
518   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
519                                                GLint                         theLocation,
520                                                const OpenGl_Vec3&            theValue);
521
522   //! Specifies the value of the float uniform 4D vector.
523   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
524                                                const GLchar*                 theName,
525                                                const OpenGl_Vec4&            theValue);
526
527   //! Specifies the value of the float uniform 4D vector.
528   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
529                                                GLint                         theLocation,
530                                                const OpenGl_Vec4&            theValue);
531
532 public:
533
534   //! Specifies the value of the float uniform 4x4 matrix.
535   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
536                                                const GLchar*                 theName,
537                                                const OpenGl_Mat4&            theValue,
538                                                GLboolean                     theTranspose = GL_FALSE);
539
540   //! Specifies the value of the float uniform 4x4 matrix.
541   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
542                                                GLint                         theLocation,
543                                                const OpenGl_Mat4&            theValue,
544                                                GLboolean                     theTranspose = GL_FALSE);
545
546   //! Specifies the value of the float uniform 4x4 matrix.
547   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
548                                                const GLchar*                 theName,
549                                                const OpenGl_Matrix&          theValue,
550                                                GLboolean                     theTranspose = GL_FALSE);
551
552   //! Specifies the value of the float uniform 4x4 matrix.
553   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
554                                                GLint                         theLocation,
555                                                const OpenGl_Matrix&          theValue,
556                                                GLboolean                     theTranspose = GL_FALSE);
557
558   //! Specifies the value of the float uniform array
559   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
560                                                GLint                         theLocation,
561                                                GLuint                        theCount,
562                                                const Standard_ShortReal*     theData);
563
564   //! Specifies the value of the float2 uniform array
565   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
566                                                GLint                         theLocation,
567                                                GLuint                        theCount,
568                                                const OpenGl_Vec2*            theData);
569
570   //! Specifies the value of the float3 uniform array
571   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
572                                                GLint                         theLocation,
573                                                GLuint                        theCount,
574                                                const OpenGl_Vec3*            theData);
575
576   //! Specifies the value of the float4 uniform array
577   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
578                                                GLint                         theLocation,
579                                                GLuint                        theCount,
580                                                const OpenGl_Vec4*            theData);
581
582   //! Specifies the value of the integer uniform array
583   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
584                                                GLint                         theLocation,
585                                                GLuint                        theCount,
586                                                const Standard_Integer*       theData);
587
588   //! Specifies the value of the int2 uniform array
589   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
590                                                GLint                         theLocation,
591                                                GLuint                        theCount,
592                                                const OpenGl_Vec2i*           theData);
593
594   //! Specifies the value of the int3 uniform array
595   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
596                                                GLint                         theLocation,
597                                                GLuint                        theCount,
598                                                const OpenGl_Vec3i*           theData);
599
600   //! Specifies the value of the int4 uniform array
601   Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
602                                                GLint                         theLocation,
603                                                GLuint                        theCount,
604                                                const OpenGl_Vec4i*           theData);
605
606 public:
607
608   //! Specifies the value of the sampler uniform variable.
609   Standard_EXPORT Standard_Boolean SetSampler (const Handle(OpenGl_Context)& theCtx,
610                                                const GLchar*                 theName,
611                                                const Graphic3d_TextureUnit   theTextureUnit);
612
613   //! Specifies the value of the sampler uniform variable.
614   Standard_EXPORT Standard_Boolean SetSampler (const Handle(OpenGl_Context)& theCtx,
615                                                GLint                         theLocation,
616                                                const Graphic3d_TextureUnit   theTextureUnit);
617
618 public:
619
620   //! Update the shader program from external files (per shader stage) in the following way:
621   //! 1) If external file does not exist, then it will be created (current source code will be dumped, no recompilation) and FALSE will be returned.
622   //! 2) If external file exists and it has the same timestamp as   myDumpDate, nothing will be done and FALSE will be returned.
623   //! 3) If external file exists and it has    newer timestamp than myDumpDate, shader  will be recompiled and relinked and TRUE will be returned.
624   //! @param theCtx OpenGL context bound to this working thread
625   //! @param theFolder folder to store files; when unspecified, $CSF_ShadersDirectoryDump or current folder will be used instead
626   //! @param theToBeautify flag improving formatting (add extra newlines)
627   //! @param theToReset when TRUE, existing dumps will be overridden
628   Standard_EXPORT Standard_Boolean UpdateDebugDump (const Handle(OpenGl_Context)& theCtx,
629                                                     const TCollection_AsciiString& theFolder = "",
630                                                     Standard_Boolean theToBeautify = Standard_False,
631                                                     Standard_Boolean theToReset = Standard_False);
632
633 protected:
634
635   //! Increments counter of users.
636   //! Used by OpenGl_ShaderManager.
637   //! @return true when resource has been restored from delayed release queue
638   bool Share()
639   {
640     return ++myShareCount == 1;
641   }
642
643   //! Decrements counter of users.
644   //! Used by OpenGl_ShaderManager.
645   //! @return true when there are no more users of this program has been left
646   bool UnShare()
647   {
648     return --myShareCount == 0;
649   }
650
651   //! Links the program object.
652   Standard_EXPORT Standard_Boolean link (const Handle(OpenGl_Context)& theCtx);
653
654 protected:
655
656   GLuint                          myProgramID;     //!< Handle of OpenGL shader program
657   OpenGl_ShaderList               myShaderObjects; //!< List of attached shader objects
658   Handle(Graphic3d_ShaderProgram) myProxy;         //!< Proxy shader program (from application layer)
659   Standard_Integer                myShareCount;    //!< program users count, initialized with 1 (already shared by one user)
660   Standard_Integer                myNbLightsMax;   //!< length of array of light sources (THE_MAX_LIGHTS)
661   Standard_Integer                myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
662   Standard_Integer                myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
663   Standard_Integer                myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits
664   Standard_Boolean                myHasAlphaTest;  //!< flag indicating that Fragment Shader should perform alpha-test
665   Standard_Boolean                myHasWeightOitOutput; //!< flag indicating that Fragment Shader includes weighted OIT coverage
666   Standard_Boolean                myHasTessShader; //!< flag indicating that program defines tessellation stage
667
668 protected:
669
670   Standard_Size myCurrentState[OpenGl_UniformStateType_NB]; //!< defines last modification for variables of each state type
671
672   //! Stores locations of OCCT state uniform variables.
673   OpenGl_ShaderUniformLocation myStateLocations[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];
674
675 };
676
677 template<class T>
678 struct OpenGl_VariableSetter : public OpenGl_SetterInterface
679 {
680   virtual void Set (const Handle(OpenGl_Context)&           theCtx,
681                     const Handle(Graphic3d_ShaderVariable)& theVariable,
682                     OpenGl_ShaderProgram*                   theProgram)
683   {
684     theProgram->SetUniform (theCtx,
685                             theVariable->Name().ToCString(),
686                             theVariable->Value()->As<T>());
687   }
688 };
689
690 namespace OpenGl_HashMapInitializer
691 {
692   template<class K, class V>
693   struct MapListOfType
694   {
695     NCollection_DataMap<K, V> myDictionary;
696
697     MapListOfType (K theKey, V theValue)
698     {
699       myDictionary.Bind (theKey, theValue);
700     }
701
702     MapListOfType& operator() (K theKey, V theValue)
703     {
704       myDictionary.Bind (theKey, theValue);
705       return *this;
706     }
707
708     operator const NCollection_DataMap<K, V>& () const
709     {
710       return myDictionary;
711     }
712   };
713
714   template<class K, class V>
715   MapListOfType<K, V> CreateListOf (K theKey, V theValue)
716   {
717     return MapListOfType<K, V> (theKey, theValue);
718   }
719 }
720
721 #endif // _OpenGl_ShaderProgram_Header