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