Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/opencascade/OpenGl_ShaderProgram.hxx was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Created on: 2013-09-19
0002 // Created by: Denis BOGOLEPOV
0003 // Copyright (c) 2013-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef OpenGl_ShaderProgram_HeaderFile
0017 #define OpenGl_ShaderProgram_HeaderFile
0018 
0019 #include <NCollection_DataMap.hxx>
0020 #include <NCollection_Sequence.hxx>
0021 #include <TCollection_AsciiString.hxx>
0022 
0023 #include <Graphic3d_ShaderProgram.hxx>
0024 #include <Graphic3d_TextureSetBits.hxx>
0025 
0026 #include <OpenGl_Vec.hxx>
0027 #include <OpenGl_NamedResource.hxx>
0028 #include <OpenGl_ShaderObject.hxx>
0029 
0030 //! The enumeration of OCCT-specific OpenGL/GLSL variables.
0031 enum OpenGl_StateVariable
0032 {
0033   // OpenGL matrix state
0034   OpenGl_OCC_MODEL_WORLD_MATRIX,
0035   OpenGl_OCC_WORLD_VIEW_MATRIX,
0036   OpenGl_OCC_PROJECTION_MATRIX,
0037   OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE,
0038   OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE,
0039   OpenGl_OCC_PROJECTION_MATRIX_INVERSE,
0040   OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE,
0041   OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE,
0042   OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE,
0043   OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE,
0044   OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE,
0045   OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE,
0046 
0047   // OpenGL clip planes state
0048   OpenGl_OCC_CLIP_PLANE_EQUATIONS,
0049   OpenGl_OCC_CLIP_PLANE_CHAINS,
0050   OpenGl_OCC_CLIP_PLANE_COUNT,
0051 
0052   // OpenGL light state
0053   OpenGl_OCC_LIGHT_SOURCE_COUNT,
0054   OpenGl_OCC_LIGHT_SOURCE_TYPES,
0055   OpenGl_OCC_LIGHT_SOURCE_PARAMS,
0056   OpenGl_OCC_LIGHT_AMBIENT,
0057   OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS, // occShadowMapSizeBias
0058   OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS,  // occShadowMapSamplers
0059   OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES,  // occShadowMapMatrices
0060 
0061   // Material state
0062   OpenGl_OCCT_TEXTURE_ENABLE,
0063   OpenGl_OCCT_DISTINGUISH_MODE,
0064   OpenGl_OCCT_PBR_MATERIAL,
0065   OpenGl_OCCT_COMMON_MATERIAL,
0066   OpenGl_OCCT_ALPHA_CUTOFF,
0067   OpenGl_OCCT_COLOR,
0068   OpenGl_OCCT_BACK_COLOR,
0069 
0070   // Weighted, Blended Order-Independent Transparency rendering state
0071   OpenGl_OCCT_OIT_OUTPUT,
0072   OpenGl_OCCT_OIT_DEPTH_FACTOR,
0073 
0074   // Context-dependent state
0075   OpenGl_OCCT_TEXTURE_TRSF2D,
0076   OpenGl_OCCT_POINT_SIZE,
0077 
0078   // Wireframe state
0079   OpenGl_OCCT_VIEWPORT,
0080   OpenGl_OCCT_LINE_WIDTH,
0081   OpenGl_OCCT_LINE_FEATHER,
0082   OpenGl_OCCT_LINE_STIPPLE_PATTERN, // occStipplePattern
0083   OpenGl_OCCT_LINE_STIPPLE_FACTOR,  // occStippleFactor
0084   OpenGl_OCCT_WIREFRAME_COLOR,
0085   OpenGl_OCCT_QUAD_MODE_STATE,
0086 
0087   // Parameters of outline (silhouette) shader
0088   OpenGl_OCCT_ORTHO_SCALE,
0089   OpenGl_OCCT_SILHOUETTE_THICKNESS,
0090 
0091   // PBR state
0092   OpenGl_OCCT_NB_SPEC_IBL_LEVELS,
0093 
0094   // DON'T MODIFY THIS ITEM (insert new items before it)
0095   OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
0096 };
0097 
0098 //! Interface for generic setter of user-defined uniform variables.
0099 struct OpenGl_SetterInterface
0100 {
0101   //! Sets user-defined uniform variable to specified program.
0102   virtual void Set(const occ::handle<OpenGl_Context>&           theCtx,
0103                    const occ::handle<Graphic3d_ShaderVariable>& theVariable,
0104                    OpenGl_ShaderProgram*                        theProgram) = 0;
0105 
0106   //! Destructor
0107   virtual ~OpenGl_SetterInterface() = default;
0108 };
0109 
0110 //! List of OpenGL shader objects.
0111 
0112 //! List of shader variable setters.
0113 
0114 //! Support tool for setting user-defined uniform variables.
0115 class OpenGl_VariableSetterSelector
0116 {
0117 public:
0118   //! Creates new setter selector.
0119   OpenGl_VariableSetterSelector();
0120 
0121   //! Releases memory resources of setter selector.
0122   ~OpenGl_VariableSetterSelector();
0123 
0124   //! Sets user-defined uniform variable to specified program.
0125   void Set(const occ::handle<OpenGl_Context>&           theCtx,
0126            const occ::handle<Graphic3d_ShaderVariable>& theVariable,
0127            OpenGl_ShaderProgram*                        theProgram) const;
0128 
0129 private:
0130   //! List of variable setters.
0131   NCollection_DataMap<size_t, OpenGl_SetterInterface*> mySetterList;
0132 };
0133 
0134 //! Defines types of uniform state variables.
0135 enum OpenGl_UniformStateType
0136 {
0137   OpenGl_LIGHT_SOURCES_STATE,
0138   OpenGl_CLIP_PLANES_STATE,
0139   OpenGl_MODEL_WORLD_STATE,
0140   OpenGl_WORLD_VIEW_STATE,
0141   OpenGl_PROJECTION_STATE,
0142   OpenGl_MATERIAL_STATE,
0143   OpenGl_SURF_DETAIL_STATE,
0144   OpenGL_OIT_STATE,
0145   OpenGl_UniformStateType_NB
0146 };
0147 
0148 //! Simple class represents GLSL program variable location.
0149 class OpenGl_ShaderUniformLocation
0150 {
0151 public:
0152   //! Invalid location of uniform/attribute variable.
0153   static const GLint INVALID_LOCATION = -1;
0154 
0155 public:
0156   //! Construct an invalid location.
0157   OpenGl_ShaderUniformLocation()
0158       : myLocation(INVALID_LOCATION)
0159   {
0160   }
0161 
0162   //! Constructor with initialization.
0163   explicit OpenGl_ShaderUniformLocation(GLint theLocation)
0164       : myLocation(theLocation)
0165   {
0166   }
0167 
0168   //! Note you may safely put invalid location in functions like glUniform* - the data passed in
0169   //! will be silently ignored.
0170   //! @return true if location is not equal to -1.
0171   bool IsValid() const { return myLocation != INVALID_LOCATION; }
0172 
0173   //! Return TRUE for non-invalid location.
0174   operator bool() const { return myLocation != INVALID_LOCATION; }
0175 
0176   //! Convert operators help silently put object to GL functions like glUniform*.
0177   operator GLint() const { return myLocation; }
0178 
0179 private:
0180   GLint myLocation;
0181 };
0182 
0183 //! Wrapper for OpenGL program object.
0184 class OpenGl_ShaderProgram : public OpenGl_NamedResource
0185 {
0186   friend class OpenGl_View;
0187   friend class OpenGl_ShaderManager;
0188   DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_NamedResource)
0189 public:
0190   //! Non-valid shader name.
0191   static const GLuint NO_PROGRAM = 0;
0192 
0193   //! Invalid location of uniform/attribute variable.
0194   static const GLint INVALID_LOCATION = -1;
0195 
0196   //! List of pre-defined OCCT state uniform variables.
0197   static const char* PredefinedKeywords[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];
0198 
0199   //! Wrapper for compiling shader object with verbose printing on error.
0200   Standard_EXPORT static bool compileShaderVerbose(
0201     const occ::handle<OpenGl_Context>&      theCtx,
0202     const occ::handle<OpenGl_ShaderObject>& theShader,
0203     const TCollection_AsciiString&          theSource,
0204     bool                                    theToPrintSource = true);
0205 
0206   //! Creates uninitialized shader program.
0207   //!
0208   //! WARNING! This constructor is not intended to be called anywhere but from
0209   //! OpenGl_ShaderManager::Create(). Manager has been designed to synchronize camera position,
0210   //! lights definition and other aspects of the program implicitly, as well as sharing same program
0211   //! across rendering groups.
0212   //!
0213   //! Program created outside the manager will be left detached from these routines,
0214   //! and them should be performed manually by caller.
0215   //!
0216   //! This constructor has been made public to provide more flexibility to re-use OCCT OpenGL
0217   //! classes without OCCT Viewer itself. If this is not the case - create the program using shared
0218   //! OpenGl_ShaderManager instance instead.
0219   Standard_EXPORT OpenGl_ShaderProgram(
0220     const occ::handle<Graphic3d_ShaderProgram>& theProxy = nullptr,
0221     const TCollection_AsciiString&              theId    = "");
0222 
0223 protected:
0224   static OpenGl_VariableSetterSelector mySetterSelector;
0225 
0226 public:
0227   //! Releases resources of shader program.
0228   Standard_EXPORT ~OpenGl_ShaderProgram() override;
0229 
0230   //! Creates new empty shader program of specified type.
0231   Standard_EXPORT bool Create(const occ::handle<OpenGl_Context>& theCtx);
0232 
0233   //! Destroys shader program.
0234   Standard_EXPORT void Release(OpenGl_Context* theCtx) override;
0235 
0236   //! Returns estimated GPU memory usage - cannot be easily estimated.
0237   size_t EstimatedDataSize() const override { return 0; }
0238 
0239   //! Attaches shader object to the program object.
0240   Standard_EXPORT bool AttachShader(const occ::handle<OpenGl_Context>&      theCtx,
0241                                     const occ::handle<OpenGl_ShaderObject>& theShader);
0242 
0243   //! Detaches shader object to the program object.
0244   Standard_EXPORT bool DetachShader(const occ::handle<OpenGl_Context>&      theCtx,
0245                                     const occ::handle<OpenGl_ShaderObject>& theShader);
0246 
0247   //! Initializes program object with the list of shader objects.
0248   Standard_EXPORT bool Initialize(
0249     const occ::handle<OpenGl_Context>&                               theCtx,
0250     const NCollection_Sequence<occ::handle<Graphic3d_ShaderObject>>& theShaders);
0251 
0252   //! Links the program object.
0253   //! @param theCtx bound OpenGL context
0254   //! @param theIsVerbose flag to print log on error
0255   Standard_EXPORT bool Link(const occ::handle<OpenGl_Context>& theCtx, bool theIsVerbose = true);
0256 
0257   //! Fetches information log of the last link operation.
0258   Standard_EXPORT bool FetchInfoLog(const occ::handle<OpenGl_Context>& theCtx,
0259                                     TCollection_AsciiString&           theLog);
0260 
0261   //! Fetches uniform variables from proxy shader program.
0262   Standard_EXPORT bool ApplyVariables(const occ::handle<OpenGl_Context>& theCtx);
0263 
0264   //! @return proxy shader program.
0265   const occ::handle<Graphic3d_ShaderProgram>& Proxy() const { return myProxy; }
0266 
0267   //! @return true if current object was initialized
0268   inline bool IsValid() const { return myProgramID != NO_PROGRAM; }
0269 
0270   //! @return program ID
0271   inline GLuint ProgramId() const { return myProgramID; }
0272 
0273 public:
0274   //! Return TRUE if program defines tessellation stage.
0275   bool HasTessellationStage() const { return myHasTessShader; }
0276 
0277   //! Return the length of array of light sources (THE_MAX_LIGHTS),
0278   //! to be used for initialization occLightSources (OpenGl_OCC_LIGHT_SOURCE_PARAMS).
0279   int NbLightsMax() const { return myNbLightsMax; }
0280 
0281   //! Return the length of array of shadow maps (THE_NB_SHADOWMAPS); 0 by default.
0282   int NbShadowMaps() const { return myNbShadowMaps; }
0283 
0284   //! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES),
0285   //! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS) and
0286   //! occClipPlaneChains (OpenGl_OCC_CLIP_PLANE_CHAINS).
0287   int NbClipPlanesMax() const { return myNbClipPlanesMax; }
0288 
0289   //! Return the length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS),
0290   //! to be used for initialization occFragColorArray/occFragColorN.
0291   int NbFragmentOutputs() const { return myNbFragOutputs; }
0292 
0293   //! Return true if Fragment Shader should perform alpha test; FALSE by default.
0294   bool HasAlphaTest() const { return myHasAlphaTest; }
0295 
0296   //! Return if Fragment Shader color should output the OIT values; OFF by default.
0297   Graphic3d_RenderTransparentMethod OitOutput() const { return myOitOutput; }
0298 
0299   //! Return texture units declared within the program, @sa Graphic3d_TextureSetBits.
0300   int TextureSetBits() const { return myTextureSetBits; }
0301 
0302 private:
0303   //! Returns index of last modification of variables of specified state type.
0304   size_t ActiveState(const OpenGl_UniformStateType theType) const
0305   {
0306     return theType < OpenGl_UniformStateType_NB ? myCurrentState[theType] : 0;
0307   }
0308 
0309   //! Updates index of last modification of variables of specified state type.
0310   void UpdateState(const OpenGl_UniformStateType theType, const size_t theIndex)
0311   {
0312     if (theType < OpenGl_UniformStateType_NB)
0313     {
0314       myCurrentState[theType] = theIndex;
0315     }
0316   }
0317 
0318 public:
0319   //! Returns location of the specific uniform variable.
0320   Standard_EXPORT OpenGl_ShaderUniformLocation
0321     GetUniformLocation(const occ::handle<OpenGl_Context>& theCtx, const GLchar* theName) const;
0322 
0323   //! Returns index of the generic vertex attribute by variable name.
0324   Standard_EXPORT GLint GetAttributeLocation(const occ::handle<OpenGl_Context>& theCtx,
0325                                              const GLchar*                      theName) const;
0326 
0327   //! Returns location of the OCCT state uniform variable.
0328   const OpenGl_ShaderUniformLocation& GetStateLocation(OpenGl_StateVariable theVariable) const
0329   {
0330     return myStateLocations[theVariable];
0331   }
0332 
0333 public:
0334   //! Returns the value of the uniform variable from given name.
0335   template <typename ValueType>
0336   bool GetUniform(const occ::handle<OpenGl_Context>& theCtx,
0337                   const GLchar*                      theName,
0338                   ValueType&                         theValue) const
0339   {
0340     return GetUniform(theCtx, GetUniformLocation(theCtx, theName), theValue);
0341   }
0342 
0343   //! Returns the value of the integer uniform variable.
0344   //! Wrapper for glGetUniformiv()
0345   Standard_EXPORT bool GetUniform(const occ::handle<OpenGl_Context>& theCtx,
0346                                   GLint                              theLocation,
0347                                   NCollection_Vec4<int>&             theValue) const;
0348 
0349   //! Returns the value of the float uniform variable.
0350   //! Wrapper for glGetUniformfv()
0351   Standard_EXPORT bool GetUniform(const occ::handle<OpenGl_Context>& theCtx,
0352                                   GLint                              theLocation,
0353                                   NCollection_Vec4<float>&           theValue) const;
0354 
0355 public:
0356   //! Returns the vertex attribute from given name.
0357   template <typename ValueType>
0358   bool GetAttribute(const occ::handle<OpenGl_Context>& theCtx,
0359                     const GLchar*                      theName,
0360                     ValueType&                         theValue) const
0361   {
0362     return GetAttribute(theCtx, GetAttributeLocation(theCtx, theName), theValue);
0363   }
0364 
0365   //! Returns the integer vertex attribute.
0366   //! Wrapper for glGetVertexAttribiv()
0367   Standard_EXPORT bool GetAttribute(const occ::handle<OpenGl_Context>& theCtx,
0368                                     GLint                              theIndex,
0369                                     NCollection_Vec4<int>&             theValue) const;
0370 
0371   //! Returns the float vertex attribute.
0372   //! Wrapper for glGetVertexAttribfv()
0373   Standard_EXPORT bool GetAttribute(const occ::handle<OpenGl_Context>& theCtx,
0374                                     GLint                              theIndex,
0375                                     NCollection_Vec4<float>&           theValue) const;
0376 
0377 public:
0378   //! Wrapper for glBindAttribLocation()
0379   Standard_EXPORT bool SetAttributeName(const occ::handle<OpenGl_Context>& theCtx,
0380                                         GLint                              theIndex,
0381                                         const GLchar*                      theName);
0382 
0383   //! Wrapper for glVertexAttrib*() for attribute with the given name.
0384   template <typename ValueType>
0385   bool SetAttribute(const occ::handle<OpenGl_Context>& theCtx,
0386                     const GLchar*                      theName,
0387                     const ValueType&                   theValue)
0388   {
0389     return SetAttribute(theCtx, GetAttributeLocation(theCtx, theName), theValue);
0390   }
0391 
0392   //! Wrapper for glVertexAttrib1f()
0393   Standard_EXPORT bool SetAttribute(const occ::handle<OpenGl_Context>& theCtx,
0394                                     GLint                              theIndex,
0395                                     GLfloat                            theValue);
0396 
0397   //! Wrapper for glVertexAttrib2fv()
0398   Standard_EXPORT bool SetAttribute(const occ::handle<OpenGl_Context>& theCtx,
0399                                     GLint                              theIndex,
0400                                     const NCollection_Vec2<float>&     theValue);
0401 
0402   //! Wrapper for glVertexAttrib3fv()
0403   Standard_EXPORT bool SetAttribute(const occ::handle<OpenGl_Context>& theCtx,
0404                                     GLint                              theIndex,
0405                                     const NCollection_Vec3<float>&     theValue);
0406 
0407   //! Wrapper for glVertexAttrib4fv()
0408   Standard_EXPORT bool SetAttribute(const occ::handle<OpenGl_Context>& theCtx,
0409                                     GLint                              theIndex,
0410                                     const NCollection_Vec4<float>&     theValue);
0411 
0412 public:
0413   //! Specifies the value of the uniform variable with given name.
0414   template <typename ValueType>
0415   bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0416                   const GLchar*                      theName,
0417                   const ValueType&                   theValue)
0418   {
0419     return SetUniform(theCtx, GetUniformLocation(theCtx, theName), theValue);
0420   }
0421 
0422   //! Specifies the value of the integer uniform variable.
0423   //! Wrapper for glUniform1i()
0424   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0425                                   GLint                              theLocation,
0426                                   GLint                              theValue);
0427 
0428   //! Specifies the value of the integer uniform 2D vector.
0429   //! Wrapper for glUniform2iv()
0430   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0431                                   GLint                              theLocation,
0432                                   const NCollection_Vec2<int>&       theValue);
0433 
0434   //! Specifies the value of the integer uniform 3D vector.
0435   //! Wrapper for glUniform3iv()
0436   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0437                                   GLint                              theLocation,
0438                                   const NCollection_Vec3<int>&       theValue);
0439 
0440   //! Specifies the value of the integer uniform 4D vector.
0441   //! Wrapper for glUniform4iv()
0442   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0443                                   GLint                              theLocation,
0444                                   const NCollection_Vec4<int>&       theValue);
0445 
0446 public:
0447   //! Specifies the value of the unsigned integer uniform 2D vector (uvec2).
0448   //! Wrapper for glUniform2uiv()
0449   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>&    theCtx,
0450                                   GLint                                 theLocation,
0451                                   const NCollection_Vec2<unsigned int>& theValue);
0452 
0453   //! Specifies the value of the uvec2 uniform array
0454   //! Wrapper for glUniform2uiv()
0455   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>&    theCtx,
0456                                   const GLchar*                         theName,
0457                                   const GLsizei                         theCount,
0458                                   const NCollection_Vec2<unsigned int>* theValue);
0459 
0460   //! Specifies the value of the uvec2 uniform array
0461   //! Wrapper for glUniform2uiv()
0462   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>&    theCtx,
0463                                   GLint                                 theLocation,
0464                                   const GLsizei                         theCount,
0465                                   const NCollection_Vec2<unsigned int>* theValue);
0466 
0467 public:
0468   //! Specifies the value of the float uniform variable.
0469   //! Wrapper for glUniform1f()
0470   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0471                                   GLint                              theLocation,
0472                                   GLfloat                            theValue);
0473 
0474   //! Specifies the value of the float uniform 2D vector.
0475   //! Wrapper for glUniform2fv()
0476   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0477                                   GLint                              theLocation,
0478                                   const NCollection_Vec2<float>&     theValue);
0479 
0480   //! Specifies the value of the float uniform 3D vector.
0481   //! Wrapper for glUniform3fv()
0482   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0483                                   GLint                              theLocation,
0484                                   const NCollection_Vec3<float>&     theValue);
0485 
0486   //! Specifies the value of the float uniform 4D vector.
0487   //! Wrapper for glUniform4fv()
0488   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0489                                   GLint                              theLocation,
0490                                   const NCollection_Vec4<float>&     theValue);
0491 
0492 public:
0493   //! Specifies the value of the array of float uniform 3x3 matrices.
0494   //! Wrapper over glUniformMatrix3fv().
0495   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0496                                   GLint                              theLocation,
0497                                   GLuint                             theCount,
0498                                   const NCollection_Mat3<float>*     theData);
0499 
0500   //! Specifies the value of the float uniform 3x3 matrix.
0501   //! Wrapper for glUniformMatrix3fv()
0502   bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0503                   const GLchar*                      theName,
0504                   const NCollection_Mat3<float>&     theValue,
0505                   GLboolean                          theTranspose = GL_FALSE)
0506   {
0507     return SetUniform(theCtx, GetUniformLocation(theCtx, theName), theValue, theTranspose);
0508   }
0509 
0510   //! Specifies the value of the float uniform 3x3 matrix.
0511   //! Wrapper for glUniformMatrix3fv()
0512   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0513                                   GLint                              theLocation,
0514                                   const NCollection_Mat3<float>&     theValue,
0515                                   GLboolean                          theTranspose = GL_FALSE);
0516 
0517   //! Specifies the value of the float uniform 4x4 matrix.
0518   //! Wrapper for glUniformMatrix4fv()
0519   bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0520                   const GLchar*                      theName,
0521                   const NCollection_Mat4<float>&     theValue,
0522                   GLboolean                          theTranspose = GL_FALSE)
0523   {
0524     return SetUniform(theCtx, GetUniformLocation(theCtx, theName), theValue, theTranspose);
0525   }
0526 
0527   //! Specifies the value of the float uniform 4x4 matrix.
0528   //! Wrapper for glUniformMatrix4fv()
0529   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0530                                   GLint                              theLocation,
0531                                   const NCollection_Mat4<float>&     theValue,
0532                                   GLboolean                          theTranspose = GL_FALSE);
0533 
0534   //! Specifies the value of the array of float uniform 4x4 matrices.
0535   //! Wrapper over glUniformMatrix4fv().
0536   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0537                                   GLint                              theLocation,
0538                                   GLuint                             theCount,
0539                                   const NCollection_Mat4<float>*     theData);
0540 
0541   //! Specifies the value of the float uniform array
0542   //! Wrapper over glUniform1fv()
0543   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0544                                   GLint                              theLocation,
0545                                   GLuint                             theCount,
0546                                   const float*                       theData);
0547 
0548   //! Specifies the value of the float2 uniform array
0549   //! Wrapper over glUniform2fv()
0550   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0551                                   GLint                              theLocation,
0552                                   GLuint                             theCount,
0553                                   const NCollection_Vec2<float>*     theData);
0554 
0555   //! Specifies the value of the float3 uniform array
0556   //! Wrapper over glUniform3fv()
0557   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0558                                   GLint                              theLocation,
0559                                   GLuint                             theCount,
0560                                   const NCollection_Vec3<float>*     theData);
0561 
0562   //! Specifies the value of the float4 uniform array
0563   //! Wrapper over glUniform4fv()
0564   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0565                                   GLint                              theLocation,
0566                                   GLuint                             theCount,
0567                                   const NCollection_Vec4<float>*     theData);
0568 
0569   //! Specifies the value of the integer uniform array
0570   //! Wrapper over glUniform1iv()
0571   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0572                                   GLint                              theLocation,
0573                                   GLuint                             theCount,
0574                                   const int*                         theData);
0575 
0576   //! Specifies the value of the int2 uniform array
0577   //! Wrapper over glUniform2iv()
0578   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0579                                   GLint                              theLocation,
0580                                   GLuint                             theCount,
0581                                   const NCollection_Vec2<int>*       theData);
0582 
0583   //! Specifies the value of the int3 uniform array
0584   //! Wrapper over glUniform3iv()
0585   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0586                                   GLint                              theLocation,
0587                                   GLuint                             theCount,
0588                                   const NCollection_Vec3<int>*       theData);
0589 
0590   //! Specifies the value of the int4 uniform array
0591   //! Wrapper over glUniform4iv()
0592   Standard_EXPORT bool SetUniform(const occ::handle<OpenGl_Context>& theCtx,
0593                                   GLint                              theLocation,
0594                                   GLuint                             theCount,
0595                                   const NCollection_Vec4<int>*       theData);
0596 
0597 public:
0598   //! Specifies the value of the sampler uniform variable.
0599   bool SetSampler(const occ::handle<OpenGl_Context>& theCtx,
0600                   const GLchar*                      theName,
0601                   const Graphic3d_TextureUnit        theTextureUnit)
0602   {
0603     return SetSampler(theCtx, GetUniformLocation(theCtx, theName), theTextureUnit);
0604   }
0605 
0606   //! Specifies the value of the sampler uniform variable.
0607   Standard_EXPORT bool SetSampler(const occ::handle<OpenGl_Context>& theCtx,
0608                                   GLint                              theLocation,
0609                                   const Graphic3d_TextureUnit        theTextureUnit);
0610 
0611 public:
0612   //! Update the shader program from external files (per shader stage) in the following way:
0613   //! 1) If external file does not exist, then it will be created (current source code will be
0614   //! dumped, no recompilation) and FALSE will be returned. 2) If external file exists and it has
0615   //! the same timestamp as myDumpDate, nothing will be done and FALSE will be returned. 3) If
0616   //! external file exists and it has newer timestamp than myDumpDate, shader will be recompiled
0617   //! and relinked and TRUE will be returned.
0618   //! @param theCtx OpenGL context bound to this working thread
0619   //! @param theFolder folder to store files; when unspecified, $CSF_ShadersDirectoryDump or current
0620   //! folder will be used instead
0621   //! @param theToBeautify flag improving formatting (add extra newlines)
0622   //! @param theToReset when TRUE, existing dumps will be overridden
0623   Standard_EXPORT bool UpdateDebugDump(const occ::handle<OpenGl_Context>& theCtx,
0624                                        const TCollection_AsciiString&     theFolder     = "",
0625                                        bool                               theToBeautify = false,
0626                                        bool                               theToReset    = false);
0627 
0628 protected:
0629   //! Increments counter of users.
0630   //! Used by OpenGl_ShaderManager.
0631   //! @return true when resource has been restored from delayed release queue
0632   bool Share() { return ++myShareCount == 1; }
0633 
0634   //! Decrements counter of users.
0635   //! Used by OpenGl_ShaderManager.
0636   //! @return true when there are no more users of this program has been left
0637   bool UnShare() { return --myShareCount == 0; }
0638 
0639   //! Links the program object.
0640   Standard_EXPORT bool link(const occ::handle<OpenGl_Context>& theCtx);
0641 
0642 protected:
0643   GLuint myProgramID; //!< Handle of OpenGL shader program
0644   NCollection_Sequence<occ::handle<OpenGl_ShaderObject>>
0645     myShaderObjects;                                //!< List of attached shader objects
0646                                                     // clang-format off
0647   occ::handle<Graphic3d_ShaderProgram> myProxy;         //!< Proxy shader program (from application layer)
0648   int                myShareCount;    //!< program users count, initialized with 1 (already shared by one user)
0649   int                myNbLightsMax;   //!< length of array of light sources (THE_MAX_LIGHTS)
0650   int                myNbShadowMaps;  //!< length of array of shadow maps (THE_NB_SHADOWMAPS)
0651   int                myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
0652   int                myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
0653   int                myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits
0654   Graphic3d_RenderTransparentMethod myOitOutput;   //!< flag indicating that Fragment Shader includes OIT outputs
0655   bool                myHasAlphaTest;  //!< flag indicating that Fragment Shader should perform alpha-test
0656   bool                myHasTessShader; //!< flag indicating that program defines tessellation stage
0657 
0658 protected:
0659 
0660   size_t myCurrentState[OpenGl_UniformStateType_NB]; //!< defines last modification for variables of each state type
0661                                                     // clang-format on
0662 
0663   //! Stores locations of OCCT state uniform variables.
0664   OpenGl_ShaderUniformLocation myStateLocations[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];
0665 };
0666 
0667 template <class T>
0668 struct OpenGl_VariableSetter : public OpenGl_SetterInterface
0669 {
0670   void Set(const occ::handle<OpenGl_Context>&           theCtx,
0671            const occ::handle<Graphic3d_ShaderVariable>& theVariable,
0672            OpenGl_ShaderProgram*                        theProgram) override
0673   {
0674     theProgram->SetUniform(theCtx, theVariable->Name().ToCString(), theVariable->Value()->As<T>());
0675   }
0676 };
0677 
0678 namespace OpenGl_HashMapInitializer
0679 {
0680 template <class K, class V>
0681 struct MapListOfType
0682 {
0683   NCollection_DataMap<K, V> myDictionary;
0684 
0685   MapListOfType(K theKey, V theValue) { myDictionary.Bind(theKey, theValue); }
0686 
0687   MapListOfType& operator()(K theKey, V theValue)
0688   {
0689     myDictionary.Bind(theKey, theValue);
0690     return *this;
0691   }
0692 
0693   operator const NCollection_DataMap<K, V>&() const { return myDictionary; }
0694 };
0695 
0696 template <class K, class V>
0697 MapListOfType<K, V> CreateListOf(K theKey, V theValue)
0698 {
0699   return MapListOfType<K, V>(theKey, theValue);
0700 }
0701 } // namespace OpenGl_HashMapInitializer
0702 
0703 #endif // _OpenGl_ShaderProgram_Header