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