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