Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Author: Ilya Khramov
0002 // Copyright (c) 2019 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #ifndef _OpenGl_PBREnvironment_HeaderFile
0016 #define _OpenGl_PBREnvironment_HeaderFile
0017 
0018 #include <OpenGl_Texture.hxx>
0019 #include <OpenGl_VertexBuffer.hxx>
0020 
0021 //! This class contains specular and diffuse maps required for Image Base Lighting (IBL) in PBR shading model with it's generation methods.
0022 class OpenGl_PBREnvironment : public OpenGl_NamedResource
0023 {
0024   DEFINE_STANDARD_RTTIEXT(OpenGl_PBREnvironment, OpenGl_NamedResource)
0025 public:
0026 
0027   //! Creates and initializes new PBR environment. It is the only way to create OpenGl_PBREnvironment.
0028   //! @param theCtx OpenGL context where environment will be created
0029   //! @param thePow2Size final size of texture's sides can be calculated as 2^thePow2Size;
0030   //!                    if thePow2Size less than 1 it will be set to 1
0031   //! @param theSpecMapLevelsNum number of mipmap levels used in specular IBL map;
0032   //!                            if theSpecMapLevelsNum less than 2 or less than Pow2Size + 1 it will be set to the corresponding values.
0033   //! @param theId OpenGl_Resource name
0034   //! @return handle to created PBR environment or NULL handle in case of fail
0035   Standard_EXPORT static Handle(OpenGl_PBREnvironment) Create (const Handle(OpenGl_Context)&  theCtx,
0036                                                                unsigned int                   thePow2Size = 9,
0037                                                                unsigned int                   theSpecMapLevelsNum = 6,
0038                                                                const TCollection_AsciiString& theId = "PBREnvironment");
0039 
0040 public:
0041 
0042   //! Binds diffuse and specular IBL maps to the corresponding texture units.
0043   Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx);
0044 
0045   //! Unbinds diffuse and specular IBL maps.
0046   Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx);
0047 
0048   //! Fills all mipmaps of specular IBL map and diffuse IBL map with one color.
0049   //! So that environment illumination will be constant.
0050   Standard_EXPORT void Clear (const Handle(OpenGl_Context)& theCtx,
0051                               const Graphic3d_Vec3&         theColor = Graphic3d_Vec3 (1.f));
0052 
0053   //! Generates specular and diffuse (irradiance) IBL maps.
0054   //! @param theCtx OpenGL context
0055   //! @param theEnvMap source environment map
0056   //! @param theZIsInverted flags indicates whether environment cubemap has inverted Z axis or not
0057   //! @param theIsTopDown flags indicates whether environment cubemap has top-down memory layout or not
0058   //! @param theDiffMapNbSamples number of samples in Monte-Carlo integration for diffuse IBL spherical harmonics calculation
0059   //! @param theSpecMapNbSamples number of samples in Monte-Carlo integration for specular IBL map generation
0060   //! @param theProbability controls strength of samples number reducing strategy during specular IBL map baking (see 'SpecIBLMapSamplesFactor' for details)
0061   //! theZIsInverted and theIsTopDown can be taken from Graphic3d_CubeMap source of environment cubemap.
0062   //! theDiffMapNbSamples and theSpecMapNbSamples is the main parameter directly affected to performance.
0063   Standard_EXPORT void Bake (const Handle(OpenGl_Context)& theCtx,
0064                              const Handle(OpenGl_Texture)& theEnvMap,
0065                              Standard_Boolean              theZIsInverted = Standard_False,
0066                              Standard_Boolean              theIsTopDown = Standard_True,
0067                              Standard_Size                 theDiffMapNbSamples = 1024,
0068                              Standard_Size                 theSpecMapNbSamples = 256,
0069                              Standard_ShortReal            theProbability = 0.99f);
0070 
0071   //! Returns number of mipmap levels used in specular IBL map.
0072   //! It can be different from value passed to creation method.
0073   unsigned int SpecMapLevelsNumber() const { return mySpecMapLevelsNumber; }
0074 
0075   //! Returns size of IBL maps sides as power of 2.
0076   //! So that the real size can be calculated as 2^Pow2Size()
0077   unsigned int Pow2Size() const { return myPow2Size; }
0078 
0079   //! Checks whether the given sizes affects to the current ones.
0080   //! It can be imagined as creation of new PBR environment.
0081   //! If creation method with this values returns the PBR environment having real sizes which are equals to current ones
0082   //! then this method will return false.
0083   //! It is handful when sizes are required to be changed.
0084   //! If this method returns false there is no reason to recreate PBR environment in order to change sizes.
0085   Standard_EXPORT bool SizesAreDifferent (unsigned int thePow2Size,
0086                                           unsigned int theSpecMapLevelsNumber) const;
0087 
0088   //! Indicates whether IBL map's textures have to be bound or it is not obligate.
0089   bool IsNeededToBeBound() const
0090   {
0091     return myIsNeededToBeBound;
0092   }
0093 
0094   //! Releases all OpenGL resources.
0095   //! It must be called before destruction.
0096   Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE;
0097 
0098   //! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
0099   virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE
0100   {
0101     unsigned int aDiffIBLMapSidePixelsCount = 1 << myPow2Size;
0102     aDiffIBLMapSidePixelsCount *= aDiffIBLMapSidePixelsCount;
0103     Standard_Size anEstimatedDataSize = aDiffIBLMapSidePixelsCount;
0104     for (unsigned int i = 0; i < mySpecMapLevelsNumber; ++i)
0105     {
0106       anEstimatedDataSize += aDiffIBLMapSidePixelsCount >> (2 * i);
0107     }
0108     anEstimatedDataSize *= 6; // cubemap sides
0109     anEstimatedDataSize *= 3; // channels
0110     return anEstimatedDataSize;
0111   }
0112 
0113   //! Checks completeness of PBR environment.
0114   //! Creation method returns only completed objects or null handles otherwise.
0115   Standard_Boolean IsComplete() const { return myIsComplete; }
0116 
0117   //! Destructor.
0118   //! Warning! 'Release' method must be called before destruction.
0119   //! Otherwise unhandled critical error will be generated.
0120   Standard_EXPORT virtual ~OpenGl_PBREnvironment();
0121 
0122 private:
0123 
0124   //! Creates new PBR environment.
0125   //! Parameters and logic are described in 'Create' method documentation.
0126   Standard_EXPORT OpenGl_PBREnvironment (const Handle(OpenGl_Context)&  theCtx,
0127                                          unsigned int                   thePowOf2Size = 9,
0128                                          unsigned int                   theSpecMapLevelsNumber = 6,
0129                                          const TCollection_AsciiString& theId = "PBREnvironment");
0130 
0131 private:
0132 
0133   //! Enum classified the type of IBL map
0134   enum OpenGl_TypeOfIBLMap
0135   {
0136     OpenGl_TypeOfIBLMap_DiffuseSH,
0137     OpenGl_TypeOfIBLMap_Specular,
0138     OpenGl_TypeOfIBLMap_DiffuseFallback,
0139   };
0140 
0141   //! Parameters for baking IBL.
0142   struct BakingParams
0143   {
0144     Standard_Size      NbSpecSamples;
0145     Standard_Size      NbDiffSamples;
0146     Standard_Integer   EnvMapSize;
0147     Standard_ShortReal Probability;
0148     Standard_Boolean   IsZInverted;
0149     Standard_Boolean   IsTopDown;
0150 
0151     BakingParams()
0152     : NbSpecSamples (0), NbDiffSamples (0), EnvMapSize (1024), Probability (1.0f), IsZInverted (false), IsTopDown (false) {}
0153   };
0154 
0155   //! Initializes all textures.
0156   //! @return false in case of failed texture initialization
0157   //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
0158   bool initTextures (const Handle(OpenGl_Context)& theCtx);
0159 
0160   //! Creates frame buffer object for IBL maps generation.
0161   //! @return false in case of failed FBO initialization
0162   //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
0163   bool initFBO (const Handle(OpenGl_Context)& theCtx);
0164 
0165   //! Initializes vertex buffer object of screen rectangle.
0166   //! @return false in case of failed creation
0167   //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
0168   bool initVAO (const Handle(OpenGl_Context)& theCtx);
0169 
0170   //! Responses for diffuse (irradiance) IBL map processing.
0171   //! @return false in case of failed baking or clearing
0172   //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
0173   bool processDiffIBLMap (const Handle(OpenGl_Context)& theCtx,
0174                           const BakingParams* theDrawParams);
0175 
0176   //! Responses for specular IBL map processing.
0177   //! @return false in case of failed baking or clearing
0178   //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
0179   bool processSpecIBLMap (const Handle(OpenGl_Context)& theCtx,
0180                           const BakingParams* theDrawParams);
0181 
0182   //! Checks completeness of frame buffer object for all targets
0183   //! (all cube map sides and levels of IBL maps).
0184   //! @return false in case of uncompleted frame buffer object.
0185   //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
0186   bool checkFBOComplentess (const Handle(OpenGl_Context)& theCtx);
0187 
0188   //! Version of 'Bake' without OpenGl_PBREnvironmentSetnry.
0189   //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
0190   void bake (const Handle(OpenGl_Context)& theCtx,
0191              const Handle(OpenGl_Texture)& theEnvMap,
0192              Standard_Boolean              theZIsInverted = Standard_False,
0193              Standard_Boolean              theIsTopDown = Standard_True,
0194              Standard_Size                 theDiffMapNbSamples = 1024,
0195              Standard_Size                 theSpecMapNbSamples = 256,
0196              Standard_ShortReal            theProbability = 1.f);
0197 
0198   //! Version of 'Clear' without OpenGl_PBREnvironmentSetnry.
0199   //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
0200   void clear (const Handle(OpenGl_Context)& theCtx,
0201               const Graphic3d_Vec3&         theColor = Graphic3d_Vec3 (1.f));
0202 
0203 private:
0204 
0205   unsigned int        myPow2Size;            //!< size of IBL maps sides (real size can be calculated as 2^myPow2Size)
0206   unsigned int        mySpecMapLevelsNumber; //!< number of mipmap levels used in specular IBL map
0207 
0208   OpenGl_Texture      myIBLMaps[3];          //!< IBL maps
0209   OpenGl_VertexBuffer myVBO;                 //!< vertex buffer object of screen rectangular
0210   GLuint              myFBO;                 //!< frame buffer object to generate or clear IBL maps
0211 
0212   Standard_Boolean    myIsComplete;          //!< completeness of PBR environment
0213   Standard_Boolean    myIsNeededToBeBound;   //!< indicates whether IBL map's textures have to be bound or it is not obligate
0214   Standard_Boolean    myCanRenderFloat;      //!< indicates whether driver supports rendering into floating point texture or not
0215 
0216 };
0217 
0218 #endif // _OpenGl_PBREnvironment_HeaderFile