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