Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:35

0001 // Created on: 2013-09-26
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_ShaderManager_HeaderFile
0017 #define _OpenGl_ShaderManager_HeaderFile
0018 
0019 #include <Graphic3d_ShaderManager.hxx>
0020 #include <OpenGl_Aspects.hxx>
0021 #include <OpenGl_Context.hxx>
0022 #include <OpenGl_MaterialState.hxx>
0023 #include <OpenGl_PBREnvironment.hxx>
0024 #include <OpenGl_SetOfShaderPrograms.hxx>
0025 #include <OpenGl_ShaderProgram.hxx>
0026 #include <OpenGl_ShaderStates.hxx>
0027 #include <OpenGl_Texture.hxx>
0028 #include <OpenGl_TextureSet.hxx>
0029 
0030 class OpenGl_VertexBuffer;
0031 
0032 //! List of shader programs.
0033 typedef NCollection_Sequence<Handle(OpenGl_ShaderProgram)> OpenGl_ShaderProgramList;
0034 
0035 //! This class is responsible for managing shader programs.
0036 class OpenGl_ShaderManager : public Graphic3d_ShaderManager
0037 {
0038   DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderManager, Graphic3d_ShaderManager)
0039   friend class OpenGl_ShaderProgram;
0040 public:
0041 
0042   //! Creates new empty shader manager.
0043   Standard_EXPORT OpenGl_ShaderManager (OpenGl_Context* theContext);
0044 
0045   //! Releases resources of shader manager.
0046   Standard_EXPORT virtual ~OpenGl_ShaderManager();
0047 
0048   //! Release all resources.
0049   Standard_EXPORT void clear();
0050 
0051   //! Fetch sRGB state from caps and invalidates programs, if necessary.
0052   Standard_EXPORT void UpdateSRgbState();
0053 
0054   //! Return local camera transformation.
0055   const gp_XYZ& LocalOrigin() const { return myLocalOrigin; }
0056 
0057   //! Setup local camera transformation for compensating float precision issues.
0058   void SetLocalOrigin (const gp_XYZ& theOrigin)
0059   {
0060     myLocalOrigin    = theOrigin;
0061     myHasLocalOrigin = !theOrigin.IsEqual (gp_XYZ(0.0, 0.0, 0.0), gp::Resolution());
0062   }
0063 
0064   //! Return clipping plane W equation value moved considering local camera transformation.
0065   Standard_Real LocalClippingPlaneW (const Graphic3d_ClipPlane& thePlane) const
0066   {
0067     const Graphic3d_Vec4d& anEq = thePlane.GetEquation();
0068     if (myHasLocalOrigin)
0069     {
0070       const gp_XYZ aPos = thePlane.ToPlane().Position().Location().XYZ() - myLocalOrigin;
0071       return -(anEq.x() * aPos.X() + anEq.y() * aPos.Y() + anEq.z() * aPos.Z());
0072     }
0073     return anEq.w();
0074   }
0075 
0076   //! Creates new shader program or re-use shared instance.
0077   //! @param theProxy    [IN]  program definition
0078   //! @param theShareKey [OUT] sharing key
0079   //! @param theProgram  [OUT] OpenGL program
0080   //! @return true on success
0081   Standard_EXPORT Standard_Boolean Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
0082                                            TCollection_AsciiString&               theShareKey,
0083                                            Handle(OpenGl_ShaderProgram)&          theProgram);
0084 
0085   //! Unregisters specified shader program.
0086   Standard_EXPORT void Unregister (TCollection_AsciiString&      theShareKey,
0087                                    Handle(OpenGl_ShaderProgram)& theProgram);
0088 
0089   //! Returns list of registered shader programs.
0090   const OpenGl_ShaderProgramList& ShaderPrograms() const { return myProgramList; }
0091 
0092   //! Returns true if no program objects are registered in the manager.
0093   Standard_Boolean IsEmpty() const { return myProgramList.IsEmpty(); }
0094 
0095   //! Bind program for filled primitives rendering
0096   Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures,
0097                                     Graphic3d_TypeOfShadingModel theShadingModel,
0098                                     Graphic3d_AlphaMode theAlphaMode,
0099                                     Standard_Boolean theHasVertColor,
0100                                     Standard_Boolean theEnableEnvMap,
0101                                     const Handle(OpenGl_ShaderProgram)& theCustomProgram)
0102   {
0103     return BindFaceProgram (theTextures, theShadingModel, theAlphaMode, Aspect_IS_SOLID,
0104                             theHasVertColor, theEnableEnvMap, false, theCustomProgram);
0105   }
0106 
0107   //! Bind program for filled primitives rendering
0108   Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures,
0109                                     Graphic3d_TypeOfShadingModel theShadingModel,
0110                                     Graphic3d_AlphaMode theAlphaMode,
0111                                     Aspect_InteriorStyle theInteriorStyle,
0112                                     Standard_Boolean theHasVertColor,
0113                                     Standard_Boolean theEnableEnvMap,
0114                                     Standard_Boolean theEnableMeshEdges,
0115                                     const Handle(OpenGl_ShaderProgram)& theCustomProgram)
0116   {
0117     const Graphic3d_TypeOfShadingModel aShadeModelOnFace = theShadingModel != Graphic3d_TypeOfShadingModel_Unlit
0118                                                         && (theTextures.IsNull() || theTextures->IsModulate())
0119                                                         ? theShadingModel
0120                                                         : Graphic3d_TypeOfShadingModel_Unlit;
0121     if (!theCustomProgram.IsNull()
0122      || myContext->caps->ffpEnable)
0123     {
0124       return bindProgramWithState (theCustomProgram, aShadeModelOnFace);
0125     }
0126 
0127     const Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, theInteriorStyle, theHasVertColor, theEnableEnvMap, theEnableMeshEdges);
0128     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (aShadeModelOnFace, aBits);
0129     return bindProgramWithState (aProgram, aShadeModelOnFace);
0130   }
0131 
0132   //! Bind program for line rendering
0133   Standard_Boolean BindLineProgram (const Handle(OpenGl_TextureSet)&    theTextures,
0134                                     const Aspect_TypeOfLine             theLineType,
0135                                     const Graphic3d_TypeOfShadingModel  theShadingModel,
0136                                     const Graphic3d_AlphaMode           theAlphaMode,
0137                                     const Standard_Boolean              theHasVertColor,
0138                                     const Handle(OpenGl_ShaderProgram)& theCustomProgram)
0139   {
0140     if (!theCustomProgram.IsNull()
0141      || myContext->caps->ffpEnable)
0142     {
0143       return bindProgramWithState (theCustomProgram, theShadingModel);
0144     }
0145 
0146     Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, Aspect_IS_SOLID, theHasVertColor, false, false);
0147     if (theLineType != Aspect_TOL_SOLID)
0148     {
0149       aBits |= Graphic3d_ShaderFlags_StippleLine;
0150     }
0151 
0152     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theShadingModel, aBits);
0153     return bindProgramWithState (aProgram, theShadingModel);
0154   }
0155 
0156   //! Bind program for point rendering
0157   Standard_EXPORT Standard_Boolean BindMarkerProgram (const Handle(OpenGl_TextureSet)& theTextures,
0158                                                       Graphic3d_TypeOfShadingModel theShadingModel,
0159                                                       Graphic3d_AlphaMode theAlphaMode,
0160                                                       Standard_Boolean theHasVertColor,
0161                                                       const Handle(OpenGl_ShaderProgram)& theCustomProgram);
0162 
0163   //! Bind program for rendering alpha-textured font.
0164   Standard_Boolean BindFontProgram (const Handle(OpenGl_ShaderProgram)& theCustomProgram);
0165 
0166   //! Bind program for outline rendering
0167   Standard_Boolean BindOutlineProgram()
0168   {
0169     if (myContext->caps->ffpEnable)
0170     {
0171       return false;
0172     }
0173 
0174     const Standard_Integer aBits = getProgramBits (Handle(OpenGl_TextureSet)(), Graphic3d_AlphaMode_Opaque, Aspect_IS_SOLID, false, false, false);
0175     if (myOutlinePrograms.IsNull())
0176     {
0177       myOutlinePrograms = new OpenGl_SetOfPrograms();
0178     }
0179     Handle(OpenGl_ShaderProgram)& aProgram = myOutlinePrograms->ChangeValue (aBits);
0180     if (aProgram.IsNull())
0181     {
0182       prepareStdProgramUnlit (aProgram, aBits, true);
0183     }
0184     return bindProgramWithState (aProgram, Graphic3d_TypeOfShadingModel_Unlit);
0185   }
0186 
0187   //! Bind program for FBO blit operation.
0188   //! @param theNbSamples       [in] number of samples within source MSAA texture
0189   //! @param theIsFallback_sRGB [in] flag indicating that destination buffer is not sRGB-ready
0190   Standard_EXPORT Standard_Boolean BindFboBlitProgram (Standard_Integer theNbSamples,
0191                                                        Standard_Boolean theIsFallback_sRGB);
0192 
0193   //! Bind program for blended order-independent transparency buffers compositing.
0194   Standard_EXPORT Standard_Boolean BindOitCompositingProgram (Standard_Boolean theIsMSAAEnabled);
0195 
0196   //! Bind program for Depth Peeling order-independent transparency back color blending.
0197   Standard_EXPORT Standard_Boolean BindOitDepthPeelingBlendProgram (bool theIsMSAAEnabled);
0198 
0199   //! Bind program for Depth Peeling order-independent transparency flush.
0200   Standard_EXPORT Standard_Boolean BindOitDepthPeelingFlushProgram (bool theIsMSAAEnabled);
0201 
0202   //! Bind program for rendering stereoscopic image.
0203   Standard_EXPORT Standard_Boolean BindStereoProgram (Graphic3d_StereoMode theStereoMode);
0204 
0205   //! Bind program for rendering bounding box.
0206   Standard_Boolean BindBoundBoxProgram()
0207   {
0208     if (myBoundBoxProgram.IsNull())
0209     {
0210       prepareStdProgramBoundBox();
0211     }
0212     return bindProgramWithState (myBoundBoxProgram, Graphic3d_TypeOfShadingModel_Unlit);
0213   }
0214 
0215   //! Returns bounding box vertex buffer.
0216   const Handle(OpenGl_VertexBuffer)& BoundBoxVertBuffer() const { return myBoundBoxVertBuffer; }
0217 
0218   //! Bind program for IBL maps generation in PBR pipeline.
0219   Standard_Boolean BindPBREnvBakingProgram (Standard_Integer theIndex)
0220   {
0221     if (myPBREnvBakingProgram[theIndex].IsNull())
0222     {
0223       preparePBREnvBakingProgram (theIndex);
0224     }
0225     return myContext->BindProgram (myPBREnvBakingProgram[theIndex]);
0226   }
0227 
0228   //! Generates shader program to render environment cubemap as background.
0229   Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram();
0230 
0231   //! Generates shader program to render skydome background.
0232   Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgSkydomeProgram();
0233 
0234   //! Generates shader program to render correctly colored quad.
0235   Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetColoredQuadProgram();
0236 
0237   //! Resets PBR shading models to corresponding non-PBR ones if PBR is not allowed.
0238   static Graphic3d_TypeOfShadingModel PBRShadingModelFallback (Graphic3d_TypeOfShadingModel theShadingModel,
0239                                                                Standard_Boolean             theIsPbrAllowed = Standard_False)
0240   {
0241     if (theIsPbrAllowed)
0242     {
0243       return theShadingModel;
0244     }
0245 
0246     switch (theShadingModel)
0247     {
0248       case Graphic3d_TypeOfShadingModel_Pbr:      return Graphic3d_TypeOfShadingModel_Phong;
0249       case Graphic3d_TypeOfShadingModel_PbrFacet: return Graphic3d_TypeOfShadingModel_PhongFacet;
0250       default: return theShadingModel;
0251     }
0252   }
0253 
0254 public:
0255 
0256   //! Returns current state of OCCT light sources.
0257   const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; }
0258 
0259   //! Updates state of OCCT light sources.
0260   Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights,
0261                                                  Standard_Integer theSpecIBLMapLevels,
0262                                                  const Handle(OpenGl_ShadowMapArray)& theShadowMaps);
0263 
0264   //! Updates state of OCCT light sources to dynamically enable/disable shadowmap.
0265   //! @param theToCast [in] flag to enable/disable shadowmap
0266   //! @return previous flag state
0267   bool SetCastShadows (const bool theToCast)
0268   {
0269     if (myLightSourceState.ShadowMaps().IsNull()
0270      || myLightSourceState.ToCastShadows() == theToCast)
0271     {
0272       return myLightSourceState.ToCastShadows();
0273     }
0274 
0275     myLightSourceState.SetCastShadows (theToCast);
0276     switchLightPrograms();
0277     return !theToCast;
0278   }
0279 
0280   //! Invalidate state of OCCT light sources.
0281   Standard_EXPORT void UpdateLightSourceState();
0282 
0283   //! Pushes current state of OCCT light sources to specified program (only on state change).
0284   //! Note that light sources definition depends also on WorldViewState.
0285   void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
0286   {
0287     if (myLightSourceState.Index() != theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
0288      || myWorldViewState.Index()   != theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
0289     {
0290       pushLightSourceState (theProgram);
0291     }
0292   }
0293 
0294   //! Pushes current state of OCCT light sources to specified program.
0295   Standard_EXPORT void pushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
0296 
0297 public:
0298 
0299   //! Returns current state of OCCT projection transform.
0300   const OpenGl_ProjectionState& ProjectionState() const { return myProjectionState; }
0301 
0302   //! Updates state of OCCT projection transform.
0303   Standard_EXPORT void UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix);
0304 
0305   //! Pushes current state of OCCT projection transform to specified program (only on state change).
0306   void PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
0307   {
0308     if (myProjectionState.Index() != theProgram->ActiveState (OpenGl_PROJECTION_STATE))
0309     {
0310       pushProjectionState (theProgram);
0311     }
0312   }
0313 
0314   //! Pushes current state of OCCT projection transform to specified program.
0315   Standard_EXPORT void pushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
0316 
0317 public:
0318 
0319   //! Returns current state of OCCT model-world transform.
0320   const OpenGl_ModelWorldState& ModelWorldState() const { return myModelWorldState; }
0321 
0322   //! Updates state of OCCT model-world transform.
0323   Standard_EXPORT void UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix);
0324 
0325   //! Pushes current state of OCCT model-world transform to specified program (only on state change).
0326   void PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
0327   {
0328     if (myModelWorldState.Index() != theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
0329     {
0330       pushModelWorldState (theProgram);
0331     }
0332   }
0333 
0334   //! Pushes current state of OCCT model-world transform to specified program.
0335   Standard_EXPORT void pushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
0336 
0337 public:
0338 
0339   //! Returns current state of OCCT world-view transform.
0340   const OpenGl_WorldViewState& WorldViewState() const { return myWorldViewState; }
0341 
0342   //! Updates state of OCCT world-view transform.
0343   Standard_EXPORT void UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix);
0344 
0345   //! Pushes current state of OCCT world-view transform to specified program (only on state change).
0346   void PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
0347   {
0348     if (myWorldViewState.Index() != theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
0349     {
0350       pushWorldViewState (theProgram);
0351     }
0352   }
0353 
0354   //! Pushes current state of OCCT world-view transform to specified program.
0355   Standard_EXPORT void pushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
0356 
0357 public:
0358 
0359   //! Updates state of OCCT clipping planes.
0360   Standard_EXPORT void UpdateClippingState();
0361 
0362   //! Reverts state of OCCT clipping planes.
0363   Standard_EXPORT void RevertClippingState();
0364 
0365   //! Pushes current state of OCCT clipping planes to specified program (only on state change).
0366   void PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
0367   {
0368     if (myClippingState.Index() != theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
0369     {
0370       pushClippingState (theProgram);
0371     }
0372   }
0373 
0374   //! Pushes current state of OCCT clipping planes to specified program.
0375   Standard_EXPORT void pushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
0376 
0377 public:
0378 
0379   //! Returns current state of material.
0380   const OpenGl_MaterialState& MaterialState() const { return myMaterialState; }
0381 
0382   //! Updates state of material.
0383   void UpdateMaterialStateTo (const OpenGl_Material& theMat,
0384                               const float theAlphaCutoff,
0385                               const bool theToDistinguish,
0386                               const bool theToMapTexture)
0387   {
0388     myMaterialState.Set (theMat, theAlphaCutoff, theToDistinguish, theToMapTexture);
0389     myMaterialState.Update();
0390   }
0391 
0392   //! Updates state of material.
0393   void UpdateMaterialState()
0394   {
0395     myMaterialState.Update();
0396   }
0397 
0398   //! Pushes current state of material to specified program (only on state change).
0399   void PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
0400   {
0401     if (myMaterialState.Index() != theProgram->ActiveState (OpenGl_MATERIAL_STATE))
0402     {
0403       pushMaterialState (theProgram);
0404     }
0405   }
0406 
0407   //! Pushes current state of material to specified program.
0408   Standard_EXPORT void pushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
0409 
0410 public:
0411 
0412   //! Setup interior style line edges variables.
0413   Standard_EXPORT void PushInteriorState (const Handle(OpenGl_ShaderProgram)& theProgram,
0414                                           const Handle(Graphic3d_Aspects)& theAspect) const;
0415 
0416 public:
0417 
0418   //! Returns state of OIT uniforms.
0419   const OpenGl_OitState& OitState() const { return myOitState; }
0420 
0421   //! Reset the state of OIT rendering pass (only on state change).
0422   void ResetOitState()
0423   {
0424     myOitState.Set (Graphic3d_RTM_BLEND_UNORDERED, 0.0f);
0425     myOitState.Update();
0426   }
0427 
0428   //! Set the state of OIT rendering pass (only on state change).
0429   //! @param theMode [in] flag indicating whether the special output should be written for OIT algorithm
0430   void SetOitState (Graphic3d_RenderTransparentMethod theMode)
0431   {
0432     myOitState.Set (theMode, 0.0f);
0433     myOitState.Update();
0434   }
0435 
0436   //! Set the state of weighed OIT rendering pass (only on state change).
0437   //! @param theDepthFactor [in] the scalar factor of depth influence to the fragment's coverage
0438   void SetWeighedOitState (float theDepthFactor)
0439   {
0440     myOitState.Set (Graphic3d_RTM_BLEND_OIT, theDepthFactor);
0441     myOitState.Update();
0442   }
0443 
0444   //! Pushes state of OIT uniforms to the specified program.
0445   void PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const
0446   {
0447     if (theProgram->IsValid()
0448      && myOitState.Index() != theProgram->ActiveState (OpenGL_OIT_STATE))
0449     {
0450       pushOitState (theProgram);
0451     }
0452   }
0453 
0454   //! Pushes state of OIT uniforms to the specified program.
0455   Standard_EXPORT void pushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
0456 
0457 public:
0458 
0459   //! Pushes current state of OCCT graphics parameters to specified program.
0460   Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram,
0461                                   Graphic3d_TypeOfShadingModel theShadingModel = Graphic3d_TypeOfShadingModel_Unlit) const;
0462 
0463 public:
0464 
0465   //! Overwrites context
0466   void SetContext (OpenGl_Context* theCtx)
0467   {
0468     myContext = theCtx;
0469   }
0470 
0471   //! Returns true when provided context is the same as used one by shader manager.
0472   bool IsSameContext (OpenGl_Context* theCtx) const
0473   {
0474     return myContext == theCtx;
0475   }
0476 
0477   //! Choose Shading Model for filled primitives.
0478   //! Fallbacks to FACET model if there are no normal attributes.
0479   //! Fallbacks to corresponding non-PBR models if PBR is unavailable.
0480   Graphic3d_TypeOfShadingModel ChooseFaceShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
0481                                                        bool theHasNodalNormals) const
0482   {
0483     if (!myContext->ColorMask())
0484     {
0485       return Graphic3d_TypeOfShadingModel_Unlit;
0486     }
0487     Graphic3d_TypeOfShadingModel aModel = theCustomModel != Graphic3d_TypeOfShadingModel_DEFAULT ? theCustomModel : myShadingModel;
0488     switch (aModel)
0489     {
0490       case Graphic3d_TypeOfShadingModel_DEFAULT:
0491       case Graphic3d_TypeOfShadingModel_Unlit:
0492       case Graphic3d_TypeOfShadingModel_PhongFacet:
0493         return aModel;
0494       case Graphic3d_TypeOfShadingModel_Gouraud:
0495       case Graphic3d_TypeOfShadingModel_Phong:
0496         return theHasNodalNormals ? aModel : Graphic3d_TypeOfShadingModel_PhongFacet;
0497       case Graphic3d_TypeOfShadingModel_Pbr:
0498         return PBRShadingModelFallback (theHasNodalNormals ? aModel : Graphic3d_TypeOfShadingModel_PbrFacet, IsPbrAllowed());
0499       case Graphic3d_TypeOfShadingModel_PbrFacet:
0500         return PBRShadingModelFallback (aModel, IsPbrAllowed());
0501     }
0502     return Graphic3d_TypeOfShadingModel_Unlit;
0503   }
0504 
0505   //! Choose Shading Model for line primitives.
0506   //! Fallbacks to UNLIT model if there are no normal attributes.
0507   //! Fallbacks to corresponding non-PBR models if PBR is unavailable.
0508   Graphic3d_TypeOfShadingModel ChooseLineShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
0509                                                        bool theHasNodalNormals) const
0510   {
0511     if (!myContext->ColorMask())
0512     {
0513       return Graphic3d_TypeOfShadingModel_Unlit;
0514     }
0515     Graphic3d_TypeOfShadingModel aModel = theCustomModel != Graphic3d_TypeOfShadingModel_DEFAULT ? theCustomModel : myShadingModel;
0516     switch (aModel)
0517     {
0518       case Graphic3d_TypeOfShadingModel_DEFAULT:
0519       case Graphic3d_TypeOfShadingModel_Unlit:
0520       case Graphic3d_TypeOfShadingModel_PhongFacet:
0521         return Graphic3d_TypeOfShadingModel_Unlit;
0522       case Graphic3d_TypeOfShadingModel_Gouraud:
0523       case Graphic3d_TypeOfShadingModel_Phong:
0524         return theHasNodalNormals ? aModel : Graphic3d_TypeOfShadingModel_Unlit;
0525       case Graphic3d_TypeOfShadingModel_Pbr:
0526         return PBRShadingModelFallback (theHasNodalNormals ? aModel : Graphic3d_TypeOfShadingModel_Unlit, IsPbrAllowed());
0527       case Graphic3d_TypeOfShadingModel_PbrFacet:
0528         return Graphic3d_TypeOfShadingModel_Unlit;
0529     }
0530     return Graphic3d_TypeOfShadingModel_Unlit;
0531   }
0532 
0533   //! Choose Shading Model for Marker primitives.
0534   Graphic3d_TypeOfShadingModel ChooseMarkerShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
0535                                                          bool theHasNodalNormals) const
0536   {
0537     return ChooseLineShadingModel (theCustomModel, theHasNodalNormals);
0538   }
0539 
0540   //! Returns default Shading Model.
0541   Graphic3d_TypeOfShadingModel ShadingModel() const { return myShadingModel; }
0542 
0543   //! Sets shading model.
0544   Standard_EXPORT void SetShadingModel (const Graphic3d_TypeOfShadingModel theModel);
0545 
0546 protected:
0547 
0548   //! Define clipping planes program bits.
0549   Standard_Integer getClipPlaneBits() const
0550   {
0551     const Standard_Integer aNbPlanes = myContext->Clipping().NbClippingOrCappingOn();
0552     if (aNbPlanes <= 0)
0553     {
0554       return 0;
0555     }
0556 
0557     Standard_Integer aBits = 0;
0558     if (myContext->Clipping().HasClippingChains())
0559     {
0560       aBits |= Graphic3d_ShaderFlags_ClipChains;
0561     }
0562 
0563     if (aNbPlanes == 1)
0564     {
0565       aBits |= Graphic3d_ShaderFlags_ClipPlanes1;
0566     }
0567     else if (aNbPlanes == 2)
0568     {
0569       aBits |= Graphic3d_ShaderFlags_ClipPlanes2;
0570     }
0571     else
0572     {
0573       aBits |= Graphic3d_ShaderFlags_ClipPlanesN;
0574     }
0575     return aBits;
0576   }
0577 
0578   //! Define program bits.
0579   Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures,
0580                                    Graphic3d_AlphaMode theAlphaMode,
0581                                    Aspect_InteriorStyle theInteriorStyle,
0582                                    Standard_Boolean theHasVertColor,
0583                                    Standard_Boolean theEnableEnvMap,
0584                                    Standard_Boolean theEnableMeshEdges) const
0585   {
0586     Standard_Integer aBits = 0;
0587     if (theAlphaMode == Graphic3d_AlphaMode_Mask
0588      || theAlphaMode == Graphic3d_AlphaMode_MaskBlend)
0589     {
0590       aBits |= Graphic3d_ShaderFlags_AlphaTest;
0591     }
0592 
0593     aBits |= getClipPlaneBits();
0594     if (theEnableMeshEdges
0595      && myContext->hasGeometryStage != OpenGl_FeatureNotAvailable)
0596     {
0597       aBits |= Graphic3d_ShaderFlags_MeshEdges;
0598       if (theInteriorStyle == Aspect_IS_HOLLOW)
0599       {
0600         aBits |= Graphic3d_ShaderFlags_AlphaTest;
0601       }
0602     }
0603 
0604     if (theEnableEnvMap)
0605     {
0606       // Environment map overwrites material texture
0607       aBits |= Graphic3d_ShaderFlags_TextureEnv;
0608     }
0609     else if (!theTextures.IsNull()
0610            && theTextures->HasNonPointSprite())
0611     {
0612       aBits |= Graphic3d_ShaderFlags_TextureRGB;
0613       if ((theTextures->TextureSetBits() & Graphic3d_TextureSetBits_Normal) != 0)
0614       {
0615         aBits |= Graphic3d_ShaderFlags_TextureNormal;
0616       }
0617     }
0618     if (theHasVertColor
0619      && theInteriorStyle != Aspect_IS_HIDDENLINE)
0620     {
0621       aBits |= Graphic3d_ShaderFlags_VertColor;
0622     }
0623 
0624     if (myOitState.ActiveMode() == Graphic3d_RTM_BLEND_OIT)
0625     {
0626       aBits |= Graphic3d_ShaderFlags_WriteOit;
0627     }
0628     else if (myOitState.ActiveMode() == Graphic3d_RTM_DEPTH_PEELING_OIT)
0629     {
0630       aBits |= Graphic3d_ShaderFlags_OitDepthPeeling;
0631     }
0632     return aBits;
0633   }
0634 
0635   //! Prepare standard GLSL program.
0636   Handle(OpenGl_ShaderProgram)& getStdProgram (Graphic3d_TypeOfShadingModel theShadingModel,
0637                                                Standard_Integer theBits)
0638   {
0639     if (theShadingModel == Graphic3d_TypeOfShadingModel_Unlit
0640      || (theBits & Graphic3d_ShaderFlags_HasTextures) == Graphic3d_ShaderFlags_TextureEnv)
0641     {
0642       // If environment map is enabled lighting calculations are
0643       // not needed (in accordance with default OCCT behavior)
0644       Handle(OpenGl_ShaderProgram)& aProgram = myUnlitPrograms->ChangeValue (theBits);
0645       if (aProgram.IsNull())
0646       {
0647         prepareStdProgramUnlit (aProgram, theBits, false);
0648       }
0649       return aProgram;
0650     }
0651 
0652     Handle(OpenGl_ShaderProgram)& aProgram = myLightPrograms->ChangeValue (theShadingModel, theBits);
0653     if (aProgram.IsNull())
0654     {
0655       prepareStdProgramLight (aProgram, theShadingModel, theBits);
0656     }
0657     return aProgram;
0658   }
0659 
0660   //! Prepare standard GLSL program without lighting.
0661   Standard_EXPORT Standard_Boolean prepareStdProgramUnlit (Handle(OpenGl_ShaderProgram)& theProgram,
0662                                                            Standard_Integer theBits,
0663                                                            Standard_Boolean theIsOutline = false);
0664 
0665   //! Prepare standard GLSL program with lighting.
0666   Standard_Boolean prepareStdProgramLight (Handle(OpenGl_ShaderProgram)& theProgram,
0667                                            Graphic3d_TypeOfShadingModel theShadingModel,
0668                                            Standard_Integer theBits)
0669   {
0670     switch (theShadingModel)
0671     {
0672       case Graphic3d_TypeOfShadingModel_Unlit:      return prepareStdProgramUnlit  (theProgram, theBits, false);
0673       case Graphic3d_TypeOfShadingModel_PhongFacet: return prepareStdProgramPhong  (theProgram, theBits, true);
0674       case Graphic3d_TypeOfShadingModel_Gouraud:    return prepareStdProgramGouraud(theProgram, theBits);
0675       case Graphic3d_TypeOfShadingModel_DEFAULT:
0676       case Graphic3d_TypeOfShadingModel_Phong:      return prepareStdProgramPhong  (theProgram, theBits, false);
0677       case Graphic3d_TypeOfShadingModel_Pbr:        return prepareStdProgramPhong  (theProgram, theBits, false, true);
0678       case Graphic3d_TypeOfShadingModel_PbrFacet:   return prepareStdProgramPhong  (theProgram, theBits, true, true);
0679     }
0680     return false;
0681   }
0682 
0683   //! Prepare standard GLSL program with per-vertex lighting.
0684   Standard_EXPORT Standard_Boolean prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
0685                                                              const Standard_Integer        theBits);
0686 
0687   //! Prepare standard GLSL program with per-pixel lighting.
0688   //! @param theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will be computed instead
0689   //! @param theIsPBR when TRUE, the PBR pipeline will be activated
0690   Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
0691                                                            const Standard_Integer        theBits,
0692                                                            const Standard_Boolean        theIsFlatNormal = false,
0693                                                            const Standard_Boolean        theIsPBR = false);
0694 
0695   //! Bind specified program to current context and apply state.
0696   Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram,
0697                                                          Graphic3d_TypeOfShadingModel theShadingModel);
0698 
0699   //! Set pointer myLightPrograms to active lighting programs set from myMapOfLightPrograms
0700   Standard_EXPORT void switchLightPrograms();
0701 
0702   //! Prepare standard GLSL program for bounding box.
0703   Standard_EXPORT Standard_Boolean prepareStdProgramBoundBox();
0704 
0705   //! Prepare GLSL source for IBL generation used in PBR pipeline.
0706   Standard_EXPORT Standard_Boolean preparePBREnvBakingProgram (Standard_Integer theIndex);
0707 
0708   //! Checks whether one of PBR shading models is set as default model.
0709   Standard_Boolean IsPbrAllowed() const { return myShadingModel == Graphic3d_TypeOfShadingModel_Pbr
0710                                               || myShadingModel == Graphic3d_TypeOfShadingModel_PbrFacet; }
0711 
0712 protected:
0713 
0714   //! Packed properties of light source
0715   struct OpenGl_ShaderLightParameters
0716   {
0717     OpenGl_Vec4 Color;      //!< RGB color + Intensity (in .w)
0718     OpenGl_Vec4 Position;   //!< XYZ Direction or Position + IsHeadlight (in .w)
0719     OpenGl_Vec4 Direction;  //!< spot light XYZ direction + Range (in .w)
0720     OpenGl_Vec4 Parameters; //!< same as Graphic3d_CLight::PackedParams()
0721 
0722     //! Returns packed (serialized) representation of light source properties
0723     const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
0724     static Standard_Integer NbOfVec4() { return 4; }
0725   };
0726 
0727   //! Fake OpenGL program for tracking FFP state in the way consistent to programmable pipeline.
0728   class OpenGl_ShaderProgramFFP : public OpenGl_ShaderProgram
0729   {
0730     DEFINE_STANDARD_RTTI_INLINE(OpenGl_ShaderProgramFFP, OpenGl_ShaderProgram)
0731     friend class OpenGl_ShaderManager;
0732   protected:
0733     OpenGl_ShaderProgramFFP() {}
0734   };
0735 
0736 protected:
0737 
0738   //! Append clipping plane definition to temporary buffers.
0739   void addClippingPlane (Standard_Integer& thePlaneId,
0740                          const Graphic3d_ClipPlane& thePlane,
0741                          const Graphic3d_Vec4d& theEq,
0742                          const Standard_Integer theChainFwd) const
0743   {
0744     myClipChainArray.SetValue (thePlaneId, theChainFwd);
0745     OpenGl_Vec4& aPlaneEq = myClipPlaneArray.ChangeValue (thePlaneId);
0746     aPlaneEq.x() = float(theEq.x());
0747     aPlaneEq.y() = float(theEq.y());
0748     aPlaneEq.z() = float(theEq.z());
0749     aPlaneEq.w() = float(theEq.w());
0750     if (myHasLocalOrigin)
0751     {
0752       aPlaneEq.w() = float(LocalClippingPlaneW (thePlane));
0753     }
0754     ++thePlaneId;
0755   }
0756 
0757 protected:
0758 
0759   Handle(OpenGl_ShaderProgramFFP)    myFfpProgram;
0760 
0761   Graphic3d_TypeOfShadingModel       myShadingModel;       //!< lighting shading model
0762   OpenGl_ShaderProgramList           myProgramList;        //!< The list of shader programs
0763   Handle(OpenGl_SetOfShaderPrograms) myLightPrograms;      //!< pointer to active lighting programs matrix
0764   Handle(OpenGl_SetOfPrograms)       myUnlitPrograms;      //!< programs matrix without lighting
0765   Handle(OpenGl_SetOfPrograms)       myOutlinePrograms;    //!< programs matrix without lighting for outline presentation
0766   Handle(OpenGl_ShaderProgram)       myFontProgram;        //!< standard program for textured text
0767   NCollection_Array1<Handle(OpenGl_ShaderProgram)>
0768                                      myBlitPrograms[2];    //!< standard program for FBO blit emulation
0769   Handle(OpenGl_ShaderProgram)       myBoundBoxProgram;    //!< standard program for bounding box
0770   Handle(OpenGl_ShaderProgram)       myOitCompositingProgram[2]; //!< standard program for OIT compositing (default and MSAA).
0771   Handle(OpenGl_ShaderProgram)       myOitDepthPeelingBlendProgram[2]; //!< standard program for OIT Depth Peeling blend (default and MSAA)
0772   Handle(OpenGl_ShaderProgram)       myOitDepthPeelingFlushProgram[2]; //!< standard program for OIT Depth Peeling flush (default and MSAA)
0773   OpenGl_MapOfShaderPrograms         myMapOfLightPrograms; //!< map of lighting programs depending on lights configuration
0774 
0775   Handle(OpenGl_ShaderProgram)       myPBREnvBakingProgram[3]; //!< programs for IBL maps generation used in PBR pipeline (0 for Diffuse; 1 for Specular; 2 for fallback)
0776   Handle(Graphic3d_ShaderProgram)    myBgCubeMapProgram;       //!< program for background cubemap rendering
0777   Handle(Graphic3d_ShaderProgram)    myBgSkydomeProgram;       //!< program for background cubemap rendering
0778   Handle(Graphic3d_ShaderProgram)    myColoredQuadProgram;     //!< program for correct quad rendering
0779 
0780   Handle(OpenGl_ShaderProgram)       myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs
0781 
0782   Handle(OpenGl_VertexBuffer)        myBoundBoxVertBuffer; //!< bounding box vertex buffer
0783 
0784   mutable Handle(OpenGl_PBREnvironment) myPBREnvironment;  //!< manager of IBL maps used in PBR pipeline
0785 
0786   OpenGl_Context*                    myContext;            //!< OpenGL context
0787 
0788 protected:
0789 
0790   OpenGl_ProjectionState             myProjectionState;    //!< State of OCCT projection  transformation
0791   OpenGl_ModelWorldState             myModelWorldState;    //!< State of OCCT model-world transformation
0792   OpenGl_WorldViewState              myWorldViewState;     //!< State of OCCT world-view  transformation
0793   OpenGl_ClippingState               myClippingState;      //!< State of OCCT clipping planes
0794   OpenGl_LightSourceState            myLightSourceState;   //!< State of OCCT light sources
0795   OpenGl_MaterialState               myMaterialState;      //!< State of Front and Back materials
0796   OpenGl_OitState                    myOitState;           //!< State of OIT uniforms
0797 
0798   gp_XYZ                             myLocalOrigin;        //!< local camera transformation
0799   Standard_Boolean                   myHasLocalOrigin;     //!< flag indicating that local camera transformation has been set
0800 
0801   mutable NCollection_Array1<Standard_Integer>             myLightTypeArray;
0802   mutable NCollection_Array1<OpenGl_ShaderLightParameters> myLightParamsArray;
0803   mutable NCollection_Array1<Graphic3d_Mat4>               myShadowMatArray;
0804   mutable NCollection_Array1<OpenGl_Vec4>                  myClipPlaneArray;
0805   mutable NCollection_Array1<OpenGl_Vec4d>                 myClipPlaneArrayFfp;
0806   mutable NCollection_Array1<Standard_Integer>             myClipChainArray;
0807 
0808 };
0809 
0810 #endif // _OpenGl_ShaderManager_HeaderFile