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