0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / OpenGl / OpenGl_PBREnvironment.hxx
CommitLineData
67312b79 1// Author: Ilya Khramov
2// Copyright (c) 2019 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15#ifndef _OpenGl_PBREnvironment_HeaderFile
16#define _OpenGl_PBREnvironment_HeaderFile
17
18#include <OpenGl_Texture.hxx>
19#include <OpenGl_VertexBuffer.hxx>
20
21//! This class contains specular and diffuse maps required for Image Base Lighting (IBL) in PBR shading model with it's generation methods.
22class OpenGl_PBREnvironment : public OpenGl_NamedResource
23{
24 DEFINE_STANDARD_RTTIEXT(OpenGl_PBREnvironment, OpenGl_NamedResource)
25public:
26
27 //! Creates and initializes new PBR environment. It is the only way to create OpenGl_PBREnvironment.
28 //! @param theCtx OpenGL context where environment will be created
29 //! @param thePow2Size final size of texture's sides can be calculated as 2^thePow2Size;
30 //! if thePow2Size less than 1 it will be set to 1
31 //! @param theSpecMapLevelsNum number of mipmap levels used in specular IBL map;
32 //! if theSpecMapLevelsNum less than 2 or less than Pow2Size + 1 it will be set to the corresponding values.
33 //! @param theId OpenGl_Resource name
34 //! @return handle to created PBR environment or NULL handle in case of fail
35 Standard_EXPORT static Handle(OpenGl_PBREnvironment) Create (const Handle(OpenGl_Context)& theCtx,
36 unsigned int thePow2Size = 9,
37 unsigned int theSpecMapLevelsNum = 6,
38 const TCollection_AsciiString& theId = "PBREnvironment");
39
40public:
41
42 //! Binds diffuse and specular IBL maps to the corresponding texture units.
43 Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx);
44
45 //! Unbinds diffuse and specular IBL maps.
46 Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx);
47
48 //! Fills all mipmaps of specular IBL map and diffuse IBL map with one color.
49 //! So that environment illumination will be constant.
50 Standard_EXPORT void Clear (const Handle(OpenGl_Context)& theCtx,
51 const Graphic3d_Vec3& theColor = Graphic3d_Vec3 (1.f));
52
53 //! Generates specular and diffuse (irradiance) IBL maps.
54 //! @param theCtx OpenGL context
55 //! @param theEnvMap source environment map
56 //! @param theZIsInverted flags indicates whether environment cubemap has inverted Z axis or not
57 //! @param theIsTopDown flags indicates whether environment cubemap has top-down memory layout or not
58 //! @param theDiffMapNbSamples number of samples in Monte-Carlo integration for diffuse IBL spherical harmonics calculation
59 //! @param theSpecMapNbSamples number of samples in Monte-Carlo integration for specular IBL map generation
60 //! @param theProbability controls strength of samples number reducing strategy during specular IBL map baking (see 'SpecIBLMapSamplesFactor' for details)
61 //! theZIsInverted and theIsTopDown can be taken from Graphic3d_CubeMap source of environment cubemap.
62 //! theDiffMapNbSamples and theSpecMapNbSamples is the main parameter directly affected to performance.
63 Standard_EXPORT void Bake (const Handle(OpenGl_Context)& theCtx,
64 const Handle(OpenGl_Texture)& theEnvMap,
65 Standard_Boolean theZIsInverted = Standard_False,
66 Standard_Boolean theIsTopDown = Standard_True,
67 Standard_Size theDiffMapNbSamples = 1024,
68 Standard_Size theSpecMapNbSamples = 256,
69 Standard_ShortReal theProbability = 0.99f);
70
71 //! Returns number of mipmap levels used in specular IBL map.
72 //! It can be different from value passed to creation method.
73 unsigned int SpecMapLevelsNumber() const { return mySpecMapLevelsNumber; }
74
75 //! Returns size of IBL maps sides as power of 2.
76 //! So that the real size can be calculated as 2^Pow2Size()
77 unsigned int Pow2Size() const { return myPow2Size; }
78
79 //! Checks whether the given sizes affects to the current ones.
80 //! It can be imagined as creation of new PBR environment.
81 //! If creation method with this values returns the PBR environment having real sizes which are equals to current ones
82 //! then this method will return false.
83 //! It is handful when sizes are required to be changed.
84 //! If this method returns false there is no reason to recreate PBR environment in order to change sizes.
85 Standard_EXPORT bool SizesAreDifferent (unsigned int thePow2Size,
86 unsigned int theSpecMapLevelsNumber) const;
87
88 //! Indicates whether IBL map's textures have to be bound or it is not obligate.
89 bool IsNeededToBeBound() const
90 {
91 return myIsNeededToBeBound;
92 }
93
94 //! Releases all OpenGL resources.
95 //! It must be called before destruction.
96 Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE;
97
98 //! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
99 virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE
100 {
101 unsigned int aDiffIBLMapSidePixelsCount = 1 << myPow2Size;
102 aDiffIBLMapSidePixelsCount *= aDiffIBLMapSidePixelsCount;
103 Standard_Size anEstimatedDataSize = aDiffIBLMapSidePixelsCount;
104 for (unsigned int i = 0; i < mySpecMapLevelsNumber; ++i)
105 {
106 anEstimatedDataSize += aDiffIBLMapSidePixelsCount >> (2 * i);
107 }
108 anEstimatedDataSize *= 6; // cubemap sides
109 anEstimatedDataSize *= 3; // channels
110 return anEstimatedDataSize;
111 }
112
113 //! Checks completeness of PBR environment.
114 //! Creation method returns only completed objects or null handles otherwise.
115 Standard_Boolean IsComplete() const { return myIsComplete; }
116
117 //! Destructor.
118 //! Warning! 'Release' method must be called before destruction.
119 //! Otherwise unhandled critical error will be generated.
120 Standard_EXPORT virtual ~OpenGl_PBREnvironment();
121
122private:
123
124 //! Creates new PBR environment.
125 //! Parameters and logic are described in 'Create' method documentation.
126 Standard_EXPORT OpenGl_PBREnvironment (const Handle(OpenGl_Context)& theCtx,
127 unsigned int thePowOf2Size = 9,
128 unsigned int theSpecMapLevelsNumber = 6,
129 const TCollection_AsciiString& theId = "PBREnvironment");
130
131private:
132
133 //! Enum classified the type of IBL map
134 enum OpenGl_TypeOfIBLMap
135 {
136 OpenGl_TypeOfIBLMap_DiffuseSH,
137 OpenGl_TypeOfIBLMap_Specular
138 };
139
140 //! Initializes all textures.
141 //! @return false in case of failed texture initialization
142 //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
143 bool initTextures (const Handle(OpenGl_Context)& theCtx);
144
145 //! Creates frame buffer object for IBL maps generation.
146 //! @return false in case of failed FBO initialization
147 //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
148 bool initFBO (const Handle(OpenGl_Context)& theCtx);
149
150 //! Initializes vertex buffer object of screen rectangle.
151 //! @return false in case of failed creation
152 //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
153 bool initVAO (const Handle(OpenGl_Context)& theCtx);
154
155 //! Responses for diffuse (irradiance) IBL map processing.
156 //! @return false in case of failed baking or clearing
157 //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
158 bool processDiffIBLMap (const Handle(OpenGl_Context)& theCtx,
159 Standard_Boolean theIsDrawAction,
160 Standard_Size theNbSamples = 0);
161
162 //! Responses for specular IBL map processing.
163 //! @return false in case of failed baking or clearing
164 //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
165 bool processSpecIBLMap (const Handle(OpenGl_Context)& theCtx,
166 Standard_Boolean theIsDrawAction,
167 Standard_Integer theEnvMapSize = 1024,
168 Standard_Size theNbSamples = 0,
169 Standard_ShortReal theProbability = 1.f);
170
171 //! Checks completeness of frame buffer object for all targets
172 //! (all cube map sides and levels of IBL maps).
173 //! @return false in case of uncompleted frame buffer object.
174 //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
175 bool checkFBOComplentess (const Handle(OpenGl_Context)& theCtx) const;
176
177 //! Version of 'Bake' without OpenGl_PBREnvironmentSetnry.
178 //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
179 void bake (const Handle(OpenGl_Context)& theCtx,
180 const Handle(OpenGl_Texture)& theEnvMap,
181 Standard_Boolean theZIsInverted = Standard_False,
182 Standard_Boolean theIsTopDown = Standard_True,
183 Standard_Size theDiffMapNbSamples = 1024,
184 Standard_Size theSpecMapNbSamples = 256,
185 Standard_ShortReal theProbability = 1.f);
186
187 //! Version of 'Clear' without OpenGl_PBREnvironmentSetnry.
188 //! Warning! Requires using of OpenGl_PBREnvironmentSentry.
189 void clear (const Handle(OpenGl_Context)& theCtx,
190 const Graphic3d_Vec3& theColor = Graphic3d_Vec3 (1.f));
191
192private:
193
194 unsigned int myPow2Size; //!< size of IBL maps sides (real size can be calculated as 2^myPow2Size)
195 unsigned int mySpecMapLevelsNumber; //!< number of mipmap levels used in specular IBL map
196
197 OpenGl_Texture myIBLMaps[2]; //!< IBL maps
198 OpenGl_VertexBuffer myVBO; //!< vertex buffer object of screen rectangular
199 GLuint myFBO; //!< frame buffer object to generate or clear IBL maps
200
201 Standard_Boolean myIsComplete; //!< completeness of PBR environment
202 Standard_Boolean myIsNeededToBeBound; //!< indicates whether IBL map's textures have to be bound or it is not obligate
203
204};
205
206#endif // _OpenGl_PBREnvironment_HeaderFile