// Copyright (c) 2013-2021 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _Graphic3d_ShaderManager_HeaderFile #define _Graphic3d_ShaderManager_HeaderFile #include "Aspect_GraphicsLibrary.hxx" #include "Graphic3d_ShaderFlags.hxx" #include "Graphic3d_StereoMode.hxx" #include "NCollection_Vec2.hxx" #include "Standard_TypeDef.hxx" #include "Standard_Transient.hxx" #include "TCollection_AsciiString.hxx" class Graphic3d_LightSet; class Graphic3d_ShaderProgram; //! GLSL syntax extensions. enum Graphic3d_GlslExtension { Graphic3d_GlslExtension_GL_OES_standard_derivatives, //!< OpenGL ES 2.0 extension //!< GL_OES_standard_derivatives Graphic3d_GlslExtension_GL_EXT_shader_texture_lod, //!< OpenGL ES 2.0 extension //!< GL_EXT_shader_texture_lod Graphic3d_GlslExtension_GL_EXT_frag_depth, //!< OpenGL ES 2.0 extension GL_EXT_frag_depth Graphic3d_GlslExtension_GL_EXT_gpu_shader4, //!< OpenGL 2.0 extension GL_EXT_gpu_shader4 }; enum { Graphic3d_GlslExtension_NB = Graphic3d_GlslExtension_GL_EXT_gpu_shader4 + 1 }; //! This class is responsible for generation of shader programs. class Graphic3d_ShaderManager : public Standard_Transient { DEFINE_STANDARD_RTTIEXT(Graphic3d_ShaderManager, Standard_Transient) public: //! Creates new empty shader manager. Standard_EXPORT Graphic3d_ShaderManager(Aspect_GraphicsLibrary theGapi); //! Releases resources of shader manager. Standard_EXPORT ~Graphic3d_ShaderManager() override; //! @return true if detected GL version is greater or equal to requested one. bool IsGapiGreaterEqual(int theVerMajor, int theVerMinor) const { return (myGapiVersion[0] > theVerMajor) || (myGapiVersion[0] == theVerMajor && myGapiVersion[1] >= theVerMinor); } //! Return GAPI version major number. int GapiVersionMajor() const { return myGapiVersion[0]; } //! Return GAPI version minor number. int GapiVersionMinor() const { return myGapiVersion[1]; } //! Return GAPI version major number. void SetGapiVersion(int theVerMajor, int theVerMinor) { myGapiVersion.SetValues(theVerMajor, theVerMinor); } //! Return TRUE if RED channel should be used instead of ALPHA for single-channel textures //! (e.g. GAPI supports only GL_RED textures and not GL_ALPHA). bool UseRedAlpha() const { return myUseRedAlpha; } //! Set if RED channel should be used instead of ALPHA for single-channel textures. void SetUseRedAlpha(bool theUseRedAlpha) { myUseRedAlpha = theUseRedAlpha; } //! Return flag indicating flat shading usage; TRUE by default. bool HasFlatShading() const { return myHasFlatShading; } //! Return flag indicating flat shading should reverse normal flag; FALSE by default. bool ToReverseDFdxSign() const { return myToReverseDFdxSign; } //! Set flag indicating flat shading usage. void SetFlatShading(bool theToUse, bool theToReverseSign) { myHasFlatShading = theToUse; myToReverseDFdxSign = theToReverseSign; } //! Return TRUE if depth clamping should be emulated by GLSL program; TRUE by default. bool ToEmulateDepthClamp() const { return myToEmulateDepthClamp; } //! Set if depth clamping should be emulated by GLSL program. void SetEmulateDepthClamp(bool theToEmulate) { myToEmulateDepthClamp = theToEmulate; } //! Return TRUE if specified extension is available. bool HasGlslExtension(Graphic3d_GlslExtension theExt) const { return myGlslExtensions[theExt]; } //! Set if specified extension is available or not. void EnableGlslExtension(Graphic3d_GlslExtension theExt, bool theToEnable = true) { myGlslExtensions[theExt] = theToEnable; } protected: //! Generate map key for light sources configuration. //! @param[in] theLights list of light sources //! @param[in] theHasShadowMap flag indicating shadow maps usage Standard_EXPORT TCollection_AsciiString genLightKey(const occ::handle& theLights, const bool theHasShadowMap) const; //! Prepare standard GLSL program for textured font. Standard_EXPORT occ::handle getStdProgramFont() const; //! Prepare standard GLSL program without lighting. //! @param[in] theBits program bits //! @param[in] theIsOutline draw silhouette Standard_EXPORT occ::handle getStdProgramUnlit( int theBits, bool theIsOutline = false) const; //! Prepare standard GLSL program with per-vertex lighting. //! @param[in] theLights list of light sources //! @param[in] theBits program bits Standard_EXPORT occ::handle getStdProgramGouraud( const occ::handle& theLights, int theBits) const; //! Prepare standard GLSL program with per-pixel lighting. //! @param[in] theLights list of light sources //! @param[in] theBits program bits //! @param[in] theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will //! be computed instead //! @param[in] theIsPBR when TRUE, the PBR pipeline will be activated //! @param[in] theNbShadowMaps number of shadow maps Standard_EXPORT occ::handle getStdProgramPhong( const occ::handle& theLights, const int theBits, const bool theIsFlatNormal, const bool theIsPBR, const int theNbShadowMaps) const; //! Prepare standard GLSL program for bounding box. Standard_EXPORT occ::handle getStdProgramBoundBox() const; //! Generates shader program to render environment cubemap as background. Standard_EXPORT occ::handle getBgCubeMapProgram() const; //! Generates shader program to render skydome background. Standard_EXPORT occ::handle getBgSkydomeProgram() const; //! Generates shader program to render correctly colored quad. Standard_EXPORT occ::handle getColoredQuadProgram() const; //! Generates shader program to render a GPU grid on an arbitrary plane. //! Uses a screen-space triangle unprojected to world rays and ray-plane intersection //! driven by uniforms uPlaneOrigin / uPlaneX / uPlaneY / uPlaneN. Standard_EXPORT occ::handle getGridProgram() const; //! Prepare GLSL source for IBL generation used in PBR pipeline. Standard_EXPORT occ::handle getPBREnvBakingProgram(int theIndex) const; //! Prepare standard GLSL program for FBO blit operation. Standard_EXPORT occ::handle getStdProgramFboBlit( int theNbSamples, bool theIsFallback_sRGB) const; //! Prepare standard GLSL program for stereoscopic image. Standard_EXPORT occ::handle getStdProgramStereo( Graphic3d_StereoMode theStereoMode) const; //! Prepare standard GLSL programs for OIT compositing operation. Standard_EXPORT occ::handle getStdProgramOitCompositing( bool theMsaa) const; //! Prepare standard GLSL programs for OIT Depth Peeling blend operation. Standard_EXPORT occ::handle getStdProgramOitDepthPeelingBlend( bool theMsaa) const; //! Prepare standard GLSL programs for OIT Depth Peeling flush operation. Standard_EXPORT occ::handle getStdProgramOitDepthPeelingFlush( bool theMsaa) const; protected: //! Return TRUE if bitwise operations can be used in GLSL program. Standard_EXPORT bool hasGlslBitwiseOps() const; //! Prepare GLSL version header. //! @param[in][out] theProgram program to set version header //! @param[in] theName program id suffix //! @param[in] theBits program bits //! @param[in] theUsesDerivates program uses standard derivatives functions or not //! @return filtered program bits with unsupported features disabled Standard_EXPORT int defaultGlslVersion(const occ::handle& theProgram, const TCollection_AsciiString& theName, int theBits, bool theUsesDerivates = false) const; //! Prepare GLSL version header for OIT composition programs. //! @param[in][out] theProgram program to set version header //! @param[in] theName program id suffix //! @param[in] theMsaa multisampling flag Standard_EXPORT void defaultOitGlslVersion(const occ::handle& theProgram, const TCollection_AsciiString& theName, bool theMsaa) const; //! Prepare standard GLSL program for accessing point sprite alpha. Standard_EXPORT TCollection_AsciiString pointSpriteAlphaSrc(int theBits) const; //! Prepare standard GLSL program for computing point sprite shading. Standard_EXPORT TCollection_AsciiString pointSpriteShadingSrc(const TCollection_AsciiString& theBaseColorSrc, int theBits) const; //! Define computeLighting GLSL function depending on current lights configuration //! @param[out] theNbLights number of defined light sources //! @param[in] theLights light sources list //! @param[in] theHasVertColor flag to use getVertColor() instead of Ambient and Diffuse //! components of active material //! @param[in] theIsPBR flag to activate PBR pipeline //! @param[in] theHasTexColor flag to include color texturing //! @param[in] theNbShadowMaps flag to include shadow map Standard_EXPORT TCollection_AsciiString stdComputeLighting(int& theNbLights, const occ::handle& theLights, bool theHasVertColor, bool theIsPBR, bool theHasTexColor, int theNbShadowMaps) const; protected: Aspect_GraphicsLibrary myGapi; //!< GAPI name NCollection_Vec2 myGapiVersion; //!< GAPI version major/minor number pair bool myGlslExtensions[Graphic3d_GlslExtension_NB]; bool myHasFlatShading; //!< flag indicating flat shading usage bool myToReverseDFdxSign; //!< flag to reverse flat shading normal (workaround) bool mySetPointSize; //!< always set gl_PointSize variable // clang-format off bool myUseRedAlpha; //!< use RED channel instead of ALPHA (e.g. GAPI supports only GL_RED textures and not GL_ALPHA) // clang-format on bool myToEmulateDepthClamp; //!< emulate depth clamping in GLSL program bool mySRgbState; //!< track sRGB state }; #endif // _Graphic3d_ShaderManager_HeaderFile