30f0ad28 |
1 | // Created on: 2013-09-26 |
2 | // Created by: Denis BOGOLEPOV |
d5f74e42 |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
30f0ad28 |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
30f0ad28 |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
30f0ad28 |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
30f0ad28 |
15 | |
16 | #ifndef _OpenGl_ShaderManager_HeaderFile |
17 | #define _OpenGl_ShaderManager_HeaderFile |
18 | |
494782f6 |
19 | #include <Graphic3d_ShaderProgram.hxx> |
f978241f |
20 | #include <Graphic3d_StereoMode.hxx> |
30f0ad28 |
21 | |
22 | #include <NCollection_DataMap.hxx> |
23 | #include <NCollection_Sequence.hxx> |
24 | |
67312b79 |
25 | #include <OpenGl_PBREnvironment.hxx> |
256f9ac0 |
26 | #include <OpenGl_SetOfShaderPrograms.hxx> |
30f0ad28 |
27 | #include <OpenGl_ShaderStates.hxx> |
bf5f0ca2 |
28 | #include <OpenGl_Aspects.hxx> |
8613985b |
29 | #include <OpenGl_MaterialState.hxx> |
8625ef7e |
30 | #include <OpenGl_Texture.hxx> |
c357e426 |
31 | |
e6804ff7 |
32 | class OpenGl_View; |
98b15dbf |
33 | class OpenGl_VertexBuffer; |
e6804ff7 |
34 | |
30f0ad28 |
35 | //! List of shader programs. |
36 | typedef NCollection_Sequence<Handle(OpenGl_ShaderProgram)> OpenGl_ShaderProgramList; |
37 | |
30f0ad28 |
38 | //! This class is responsible for managing shader programs. |
39 | class OpenGl_ShaderManager : public Standard_Transient |
40 | { |
8613985b |
41 | DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient) |
30f0ad28 |
42 | friend class OpenGl_ShaderProgram; |
30f0ad28 |
43 | public: |
44 | |
45 | //! Creates new empty shader manager. |
46 | Standard_EXPORT OpenGl_ShaderManager (OpenGl_Context* theContext); |
47 | |
48 | //! Releases resources of shader manager. |
49 | Standard_EXPORT virtual ~OpenGl_ShaderManager(); |
50 | |
05e2200b |
51 | //! Release all resources. |
52 | Standard_EXPORT void clear(); |
53 | |
ba00aab7 |
54 | //! Fetch sRGB state from caps and invalidates programs, if necessary. |
55 | Standard_EXPORT void UpdateSRgbState(); |
56 | |
7c3ef2f7 |
57 | //! Return local camera transformation. |
58 | const gp_XYZ& LocalOrigin() const { return myLocalOrigin; } |
59 | |
60 | //! Setup local camera transformation for compensating float precision issues. |
61 | void SetLocalOrigin (const gp_XYZ& theOrigin) |
62 | { |
63 | myLocalOrigin = theOrigin; |
64 | myHasLocalOrigin = !theOrigin.IsEqual (gp_XYZ(0.0, 0.0, 0.0), gp::Resolution()); |
65 | } |
66 | |
edc4ba21 |
67 | //! Return clipping plane W equation value moved considering local camera transformation. |
68 | Standard_Real LocalClippingPlaneW (const Graphic3d_ClipPlane& thePlane) const |
69 | { |
70 | const Graphic3d_Vec4d& anEq = thePlane.GetEquation(); |
71 | if (myHasLocalOrigin) |
72 | { |
73 | const gp_XYZ aPos = thePlane.ToPlane().Position().Location().XYZ() - myLocalOrigin; |
74 | return -(anEq.x() * aPos.X() + anEq.y() * aPos.Y() + anEq.z() * aPos.Z()); |
75 | } |
76 | return anEq.w(); |
77 | } |
78 | |
392ac980 |
79 | //! Creates new shader program or re-use shared instance. |
80 | //! @param theProxy [IN] program definition |
81 | //! @param theShareKey [OUT] sharing key |
82 | //! @param theProgram [OUT] OpenGL program |
8625ef7e |
83 | //! @return true on success |
84 | Standard_EXPORT Standard_Boolean Create (const Handle(Graphic3d_ShaderProgram)& theProxy, |
85 | TCollection_AsciiString& theShareKey, |
86 | Handle(OpenGl_ShaderProgram)& theProgram); |
30f0ad28 |
87 | |
88 | //! Unregisters specified shader program. |
392ac980 |
89 | Standard_EXPORT void Unregister (TCollection_AsciiString& theShareKey, |
90 | Handle(OpenGl_ShaderProgram)& theProgram); |
30f0ad28 |
91 | |
92 | //! Returns list of registered shader programs. |
93 | Standard_EXPORT const OpenGl_ShaderProgramList& ShaderPrograms() const; |
94 | |
95 | //! Returns true if no program objects are registered in the manager. |
96 | Standard_EXPORT Standard_Boolean IsEmpty() const; |
97 | |
8625ef7e |
98 | //! Bind program for filled primitives rendering |
cc8cbabe |
99 | Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures, |
2a332745 |
100 | Graphic3d_TypeOfShadingModel theShadingModel, |
101 | Graphic3d_AlphaMode theAlphaMode, |
102 | Standard_Boolean theHasVertColor, |
103 | Standard_Boolean theEnableEnvMap, |
104 | const Handle(OpenGl_ShaderProgram)& theCustomProgram) |
105 | { |
6ef0d6f1 |
106 | return BindFaceProgram (theTextures, theShadingModel, theAlphaMode, Aspect_IS_SOLID, |
107 | theHasVertColor, theEnableEnvMap, false, theCustomProgram); |
2a332745 |
108 | } |
109 | |
110 | //! Bind program for filled primitives rendering |
111 | Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures, |
112 | Graphic3d_TypeOfShadingModel theShadingModel, |
113 | Graphic3d_AlphaMode theAlphaMode, |
114 | Aspect_InteriorStyle theInteriorStyle, |
115 | Standard_Boolean theHasVertColor, |
116 | Standard_Boolean theEnableEnvMap, |
117 | Standard_Boolean theEnableMeshEdges, |
299e0ab9 |
118 | const Handle(OpenGl_ShaderProgram)& theCustomProgram) |
8625ef7e |
119 | { |
120 | if (!theCustomProgram.IsNull() |
121 | || myContext->caps->ffpEnable) |
122 | { |
299e0ab9 |
123 | return bindProgramWithState (theCustomProgram); |
8625ef7e |
124 | } |
125 | |
dc89236f |
126 | const Graphic3d_TypeOfShadingModel aShadeModelOnFace = theShadingModel != Graphic3d_TOSM_UNLIT |
127 | && (theTextures.IsNull() || theTextures->IsModulate()) |
128 | ? theShadingModel |
129 | : Graphic3d_TOSM_UNLIT; |
2a332745 |
130 | const Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, theInteriorStyle, theHasVertColor, theEnableEnvMap, theEnableMeshEdges); |
dc89236f |
131 | Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (aShadeModelOnFace, aBits); |
299e0ab9 |
132 | return bindProgramWithState (aProgram); |
8625ef7e |
133 | } |
30f0ad28 |
134 | |
8625ef7e |
135 | //! Bind program for line rendering |
cc8cbabe |
136 | Standard_Boolean BindLineProgram (const Handle(OpenGl_TextureSet)& theTextures, |
dc89236f |
137 | const Aspect_TypeOfLine theLineType, |
138 | const Graphic3d_TypeOfShadingModel theShadingModel, |
c40eb6b9 |
139 | const Graphic3d_AlphaMode theAlphaMode, |
299e0ab9 |
140 | const Standard_Boolean theHasVertColor, |
141 | const Handle(OpenGl_ShaderProgram)& theCustomProgram) |
8625ef7e |
142 | { |
143 | if (!theCustomProgram.IsNull() |
144 | || myContext->caps->ffpEnable) |
145 | { |
299e0ab9 |
146 | return bindProgramWithState (theCustomProgram); |
8625ef7e |
147 | } |
148 | |
2a332745 |
149 | Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, Aspect_IS_SOLID, theHasVertColor, false, false); |
dc89236f |
150 | if (theLineType != Aspect_TOL_SOLID) |
ac116c22 |
151 | { |
152 | aBits |= OpenGl_PO_StippleLine; |
153 | } |
154 | |
dc89236f |
155 | Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theShadingModel, aBits); |
299e0ab9 |
156 | return bindProgramWithState (aProgram); |
8625ef7e |
157 | } |
30f0ad28 |
158 | |
8625ef7e |
159 | //! Bind program for point rendering |
737e9a8d |
160 | Standard_EXPORT Standard_Boolean BindMarkerProgram (const Handle(OpenGl_TextureSet)& theTextures, |
161 | Graphic3d_TypeOfShadingModel theShadingModel, |
162 | Graphic3d_AlphaMode theAlphaMode, |
163 | Standard_Boolean theHasVertColor, |
164 | const Handle(OpenGl_ShaderProgram)& theCustomProgram); |
8625ef7e |
165 | |
166 | //! Bind program for rendering alpha-textured font. |
299e0ab9 |
167 | Standard_Boolean BindFontProgram (const Handle(OpenGl_ShaderProgram)& theCustomProgram) |
8625ef7e |
168 | { |
169 | if (!theCustomProgram.IsNull() |
170 | || myContext->caps->ffpEnable) |
171 | { |
299e0ab9 |
172 | return bindProgramWithState (theCustomProgram); |
8625ef7e |
173 | } |
174 | |
175 | if (myFontProgram.IsNull()) |
176 | { |
177 | prepareStdProgramFont(); |
178 | } |
299e0ab9 |
179 | |
180 | return bindProgramWithState (myFontProgram); |
8625ef7e |
181 | } |
30f0ad28 |
182 | |
6ef0d6f1 |
183 | //! Bind program for outline rendering |
184 | Standard_Boolean BindOutlineProgram() |
185 | { |
186 | if (myContext->caps->ffpEnable) |
187 | { |
188 | return false; |
189 | } |
190 | |
191 | const Standard_Integer aBits = getProgramBits (Handle(OpenGl_TextureSet)(), Graphic3d_AlphaMode_Opaque, Aspect_IS_SOLID, false, false, false); |
192 | if (myOutlinePrograms.IsNull()) |
193 | { |
194 | myOutlinePrograms = new OpenGl_SetOfPrograms(); |
195 | } |
196 | Handle(OpenGl_ShaderProgram)& aProgram = myOutlinePrograms->ChangeValue (aBits); |
197 | if (aProgram.IsNull()) |
198 | { |
199 | prepareStdProgramUnlit (aProgram, aBits, true); |
200 | } |
201 | return bindProgramWithState (aProgram); |
202 | } |
203 | |
b86bb3df |
204 | //! Bind program for FBO blit operation. |
ba00aab7 |
205 | //! @param theNbSamples [in] number of samples within source MSAA texture |
206 | //! @param theIsFallback_sRGB [in] flag indicating that destination buffer is not sRGB-ready |
207 | Standard_EXPORT Standard_Boolean BindFboBlitProgram (Standard_Integer theNbSamples, |
208 | Standard_Boolean theIsFallback_sRGB); |
b86bb3df |
209 | |
a1073ae2 |
210 | //! Bind program for blended order-independent transparency buffers compositing. |
211 | Standard_Boolean BindOitCompositingProgram (const Standard_Boolean theIsMSAAEnabled) |
212 | { |
213 | const Standard_Integer aProgramIdx = theIsMSAAEnabled ? 1 : 0; |
214 | if (myOitCompositingProgram[aProgramIdx].IsNull()) |
215 | { |
216 | prepareStdProgramOitCompositing (theIsMSAAEnabled); |
217 | } |
218 | |
219 | const Handle(OpenGl_ShaderProgram)& aProgram = myOitCompositingProgram [aProgramIdx]; |
220 | return !aProgram.IsNull() && myContext->BindProgram (aProgram); |
221 | } |
222 | |
f978241f |
223 | //! Bind program for rendering stereoscopic image. |
224 | Standard_Boolean BindStereoProgram (const Graphic3d_StereoMode theStereoMode) |
38a0206f |
225 | { |
f978241f |
226 | if (theStereoMode < 0 || theStereoMode >= Graphic3d_StereoMode_NB) |
38a0206f |
227 | { |
f978241f |
228 | return Standard_False; |
38a0206f |
229 | } |
f978241f |
230 | |
231 | if (myStereoPrograms[theStereoMode].IsNull()) |
232 | { |
233 | prepareStdProgramStereo (myStereoPrograms[theStereoMode], theStereoMode); |
234 | } |
235 | const Handle(OpenGl_ShaderProgram)& aProgram = myStereoPrograms[theStereoMode]; |
236 | return !aProgram.IsNull() |
237 | && myContext->BindProgram (aProgram); |
38a0206f |
238 | } |
239 | |
98b15dbf |
240 | //! Bind program for rendering bounding box. |
241 | Standard_Boolean BindBoundBoxProgram() |
242 | { |
243 | if (myBoundBoxProgram.IsNull()) |
244 | { |
245 | prepareStdProgramBoundBox(); |
246 | } |
247 | return bindProgramWithState (myBoundBoxProgram); |
248 | } |
249 | |
250 | //! Returns bounding box vertex buffer. |
251 | const Handle(OpenGl_VertexBuffer)& BoundBoxVertBuffer() const { return myBoundBoxVertBuffer; } |
252 | |
67312b79 |
253 | //! Bind program for IBL maps generation in PBR pipeline. |
254 | Standard_Boolean BindPBREnvBakingProgram() |
255 | { |
256 | if (myPBREnvBakingProgram.IsNull()) |
257 | { |
258 | preparePBREnvBakingProgram(); |
259 | } |
260 | return myContext->BindProgram (myPBREnvBakingProgram); |
261 | } |
262 | |
077a220c |
263 | //! Generates shader program to render environment cubemap as background. |
264 | Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram (); |
265 | |
67312b79 |
266 | //! Resets PBR shading models to corresponding non-PBR ones if PBR is not allowed. |
267 | static Graphic3d_TypeOfShadingModel PBRShadingModelFallback (Graphic3d_TypeOfShadingModel theShadingModel, |
268 | Standard_Boolean theIsPbrAllowed = Standard_False) |
269 | { |
270 | if (theIsPbrAllowed) |
271 | { |
272 | return theShadingModel; |
273 | } |
274 | |
275 | switch (theShadingModel) |
276 | { |
277 | case Graphic3d_TOSM_PBR: return Graphic3d_TOSM_FRAGMENT; |
278 | case Graphic3d_TOSM_PBR_FACET: return Graphic3d_TOSM_FACET; |
279 | default: return theShadingModel; |
280 | } |
281 | } |
282 | |
30f0ad28 |
283 | public: |
284 | |
285 | //! Returns current state of OCCT light sources. |
8613985b |
286 | const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; } |
30f0ad28 |
287 | |
288 | //! Updates state of OCCT light sources. |
67312b79 |
289 | Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights, |
290 | Standard_Integer theSpecIBLMapLevels = 0); |
30f0ad28 |
291 | |
7c3ef2f7 |
292 | //! Invalidate state of OCCT light sources. |
293 | Standard_EXPORT void UpdateLightSourceState(); |
294 | |
8cf3bf84 |
295 | //! Pushes current state of OCCT light sources to specified program (only on state change). |
296 | void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
297 | { |
298 | if (myLightSourceState.Index() != theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)) |
299 | { |
300 | pushLightSourceState (theProgram); |
301 | } |
302 | } |
303 | |
30f0ad28 |
304 | //! Pushes current state of OCCT light sources to specified program. |
8cf3bf84 |
305 | Standard_EXPORT void pushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const; |
30f0ad28 |
306 | |
307 | public: |
308 | |
309 | //! Returns current state of OCCT projection transform. |
8613985b |
310 | const OpenGl_ProjectionState& ProjectionState() const { return myProjectionState; } |
30f0ad28 |
311 | |
312 | //! Updates state of OCCT projection transform. |
c827ea3a |
313 | Standard_EXPORT void UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix); |
30f0ad28 |
314 | |
8cf3bf84 |
315 | //! Pushes current state of OCCT projection transform to specified program (only on state change). |
316 | void PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
317 | { |
318 | if (myProjectionState.Index() != theProgram->ActiveState (OpenGl_PROJECTION_STATE)) |
319 | { |
320 | pushProjectionState (theProgram); |
321 | } |
322 | } |
323 | |
30f0ad28 |
324 | //! Pushes current state of OCCT projection transform to specified program. |
8cf3bf84 |
325 | Standard_EXPORT void pushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const; |
30f0ad28 |
326 | |
327 | public: |
328 | |
329 | //! Returns current state of OCCT model-world transform. |
8613985b |
330 | const OpenGl_ModelWorldState& ModelWorldState() const { return myModelWorldState; } |
30f0ad28 |
331 | |
332 | //! Updates state of OCCT model-world transform. |
c827ea3a |
333 | Standard_EXPORT void UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix); |
30f0ad28 |
334 | |
8cf3bf84 |
335 | //! Pushes current state of OCCT model-world transform to specified program (only on state change). |
336 | void PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
337 | { |
338 | if (myModelWorldState.Index() != theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE)) |
339 | { |
340 | pushModelWorldState (theProgram); |
341 | } |
342 | } |
343 | |
30f0ad28 |
344 | //! Pushes current state of OCCT model-world transform to specified program. |
8cf3bf84 |
345 | Standard_EXPORT void pushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const; |
30f0ad28 |
346 | |
347 | public: |
348 | |
349 | //! Returns current state of OCCT world-view transform. |
8613985b |
350 | const OpenGl_WorldViewState& WorldViewState() const { return myWorldViewState; } |
30f0ad28 |
351 | |
352 | //! Updates state of OCCT world-view transform. |
c827ea3a |
353 | Standard_EXPORT void UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix); |
30f0ad28 |
354 | |
8cf3bf84 |
355 | //! Pushes current state of OCCT world-view transform to specified program (only on state change). |
356 | void PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
357 | { |
358 | if (myWorldViewState.Index() != theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE)) |
359 | { |
360 | pushWorldViewState (theProgram); |
361 | } |
362 | } |
363 | |
30f0ad28 |
364 | //! Pushes current state of OCCT world-view transform to specified program. |
8cf3bf84 |
365 | Standard_EXPORT void pushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const; |
30f0ad28 |
366 | |
367 | public: |
368 | |
369 | //! Updates state of OCCT clipping planes. |
370 | Standard_EXPORT void UpdateClippingState(); |
371 | |
372 | //! Reverts state of OCCT clipping planes. |
373 | Standard_EXPORT void RevertClippingState(); |
374 | |
8cf3bf84 |
375 | //! Pushes current state of OCCT clipping planes to specified program (only on state change). |
376 | void PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
377 | { |
378 | if (myClippingState.Index() != theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE)) |
379 | { |
380 | pushClippingState (theProgram); |
381 | } |
382 | } |
383 | |
30f0ad28 |
384 | //! Pushes current state of OCCT clipping planes to specified program. |
8cf3bf84 |
385 | Standard_EXPORT void pushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const; |
30f0ad28 |
386 | |
8613985b |
387 | public: |
388 | |
389 | //! Returns current state of material. |
390 | const OpenGl_MaterialState& MaterialState() const { return myMaterialState; } |
391 | |
392 | //! Updates state of material. |
393 | void UpdateMaterialStateTo (const OpenGl_Material& theFrontMat, |
394 | const OpenGl_Material& theBackMat, |
c40eb6b9 |
395 | const float theAlphaCutoff, |
8613985b |
396 | const bool theToDistinguish, |
397 | const bool theToMapTexture) |
398 | { |
c40eb6b9 |
399 | myMaterialState.Set (theFrontMat, theBackMat, theAlphaCutoff, theToDistinguish, theToMapTexture); |
8613985b |
400 | myMaterialState.Update(); |
401 | } |
402 | |
403 | //! Updates state of material. |
404 | void UpdateMaterialState() |
405 | { |
406 | myMaterialState.Update(); |
407 | } |
408 | |
8cf3bf84 |
409 | //! Pushes current state of material to specified program (only on state change). |
410 | void PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
411 | { |
412 | if (myMaterialState.Index() != theProgram->ActiveState (OpenGl_MATERIAL_STATE)) |
413 | { |
414 | pushMaterialState (theProgram); |
415 | } |
416 | } |
417 | |
8613985b |
418 | //! Pushes current state of material to specified program. |
8cf3bf84 |
419 | Standard_EXPORT void pushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const; |
8613985b |
420 | |
2a332745 |
421 | public: |
422 | |
423 | //! Setup interior style line edges variables. |
424 | Standard_EXPORT void PushInteriorState (const Handle(OpenGl_ShaderProgram)& theProgram, |
bf5f0ca2 |
425 | const Handle(Graphic3d_Aspects)& theAspect) const; |
2a332745 |
426 | |
a1073ae2 |
427 | public: |
428 | |
726b5d9e |
429 | //! Returns state of OIT uniforms. |
430 | const OpenGl_OitState& OitState() const { return myOitState; } |
431 | |
8cf3bf84 |
432 | //! Set the state of OIT rendering pass (only on state change). |
a1073ae2 |
433 | //! @param theToEnableOitWrite [in] flag indicating whether the special output should be written for OIT algorithm. |
434 | //! @param theDepthFactor [in] the scalar factor of depth influence to the fragment's coverage. |
435 | void SetOitState (const bool theToEnableOitWrite, const float theDepthFactor) |
436 | { |
437 | myOitState.Set (theToEnableOitWrite, theDepthFactor); |
438 | myOitState.Update(); |
439 | } |
440 | |
441 | //! Pushes state of OIT uniforms to the specified program. |
8cf3bf84 |
442 | void PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
443 | { |
444 | if (theProgram->IsValid() |
445 | && myOitState.Index() != theProgram->ActiveState (OpenGL_OIT_STATE)) |
446 | { |
447 | pushOitState (theProgram); |
448 | } |
449 | } |
450 | |
451 | //! Pushes state of OIT uniforms to the specified program. |
452 | Standard_EXPORT void pushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const; |
a1073ae2 |
453 | |
30f0ad28 |
454 | public: |
05e2200b |
455 | |
30f0ad28 |
456 | //! Pushes current state of OCCT graphics parameters to specified program. |
457 | Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const; |
458 | |
392ac980 |
459 | public: |
460 | |
461 | //! Overwrites context |
462 | void SetContext (OpenGl_Context* theCtx) |
463 | { |
464 | myContext = theCtx; |
465 | } |
466 | |
c357e426 |
467 | //! Returns true when provided context is the same as used one by shader manager. |
468 | bool IsSameContext (OpenGl_Context* theCtx) const |
469 | { |
470 | return myContext == theCtx; |
471 | } |
472 | |
db5d29de |
473 | //! Choose Shading Model for filled primitives. |
474 | //! Fallbacks to FACET model if there are no normal attributes. |
67312b79 |
475 | //! Fallbacks to corresponding non-PBR models if PBR is unavailable. |
db5d29de |
476 | Graphic3d_TypeOfShadingModel ChooseFaceShadingModel (Graphic3d_TypeOfShadingModel theCustomModel, |
477 | bool theHasNodalNormals) const |
dc89236f |
478 | { |
479 | if (!myContext->ColorMask()) |
480 | { |
481 | return Graphic3d_TOSM_UNLIT; |
482 | } |
483 | Graphic3d_TypeOfShadingModel aModel = theCustomModel != Graphic3d_TOSM_DEFAULT ? theCustomModel : myShadingModel; |
484 | switch (aModel) |
485 | { |
486 | case Graphic3d_TOSM_DEFAULT: |
487 | case Graphic3d_TOSM_UNLIT: |
488 | case Graphic3d_TOSM_FACET: |
db5d29de |
489 | return aModel; |
dc89236f |
490 | case Graphic3d_TOSM_VERTEX: |
491 | case Graphic3d_TOSM_FRAGMENT: |
db5d29de |
492 | return theHasNodalNormals ? aModel : Graphic3d_TOSM_FACET; |
67312b79 |
493 | case Graphic3d_TOSM_PBR: |
494 | return PBRShadingModelFallback (theHasNodalNormals ? aModel : Graphic3d_TOSM_PBR_FACET, IsPbrAllowed()); |
495 | case Graphic3d_TOSM_PBR_FACET: |
496 | return PBRShadingModelFallback (aModel, IsPbrAllowed()); |
dc89236f |
497 | } |
db5d29de |
498 | return Graphic3d_TOSM_UNLIT; |
499 | } |
500 | |
501 | //! Choose Shading Model for line primitives. |
502 | //! Fallbacks to UNLIT model if there are no normal attributes. |
67312b79 |
503 | //! Fallbacks to corresponding non-PBR models if PBR is unavailable. |
db5d29de |
504 | Graphic3d_TypeOfShadingModel ChooseLineShadingModel (Graphic3d_TypeOfShadingModel theCustomModel, |
505 | bool theHasNodalNormals) const |
506 | { |
507 | if (!myContext->ColorMask()) |
508 | { |
509 | return Graphic3d_TOSM_UNLIT; |
510 | } |
511 | Graphic3d_TypeOfShadingModel aModel = theCustomModel != Graphic3d_TOSM_DEFAULT ? theCustomModel : myShadingModel; |
512 | switch (aModel) |
513 | { |
514 | case Graphic3d_TOSM_DEFAULT: |
515 | case Graphic3d_TOSM_UNLIT: |
516 | case Graphic3d_TOSM_FACET: |
517 | return Graphic3d_TOSM_UNLIT; |
518 | case Graphic3d_TOSM_VERTEX: |
519 | case Graphic3d_TOSM_FRAGMENT: |
520 | return theHasNodalNormals ? aModel : Graphic3d_TOSM_UNLIT; |
67312b79 |
521 | case Graphic3d_TOSM_PBR: |
522 | return PBRShadingModelFallback (theHasNodalNormals ? aModel : Graphic3d_TOSM_UNLIT, IsPbrAllowed()); |
523 | case Graphic3d_TOSM_PBR_FACET: |
524 | return Graphic3d_TOSM_UNLIT; |
db5d29de |
525 | } |
526 | return Graphic3d_TOSM_UNLIT; |
527 | } |
528 | |
529 | //! Choose Shading Model for Marker primitives. |
530 | Graphic3d_TypeOfShadingModel ChooseMarkerShadingModel (Graphic3d_TypeOfShadingModel theCustomModel, |
531 | bool theHasNodalNormals) const |
532 | { |
533 | return ChooseLineShadingModel (theCustomModel, theHasNodalNormals); |
dc89236f |
534 | } |
535 | |
536 | //! Returns default Shading Model. |
537 | Graphic3d_TypeOfShadingModel ShadingModel() const { return myShadingModel; } |
538 | |
8625ef7e |
539 | //! Sets shading model. |
c357e426 |
540 | Standard_EXPORT void SetShadingModel (const Graphic3d_TypeOfShadingModel theModel); |
8625ef7e |
541 | |
e6804ff7 |
542 | //! Sets last view manger used with. |
543 | //! Helps to handle matrix states in multi-view configurations. |
544 | void SetLastView (const OpenGl_View* theLastView) |
545 | { |
546 | myLastView = theLastView; |
547 | } |
548 | |
549 | //! Returns true when provided view is the same as cached one. |
550 | bool IsSameView (const OpenGl_View* theView) const |
551 | { |
552 | return myLastView == theView; |
553 | } |
554 | |
30f0ad28 |
555 | protected: |
556 | |
2a332745 |
557 | //! Define clipping planes program bits. |
558 | Standard_Integer getClipPlaneBits() const |
559 | { |
560 | const Standard_Integer aNbPlanes = myContext->Clipping().NbClippingOrCappingOn(); |
561 | if (aNbPlanes <= 0) |
562 | { |
563 | return 0; |
564 | } |
565 | |
566 | Standard_Integer aBits = 0; |
567 | if (myContext->Clipping().HasClippingChains()) |
568 | { |
569 | aBits |= OpenGl_PO_ClipChains; |
570 | } |
571 | |
572 | if (aNbPlanes == 1) |
573 | { |
574 | aBits |= OpenGl_PO_ClipPlanes1; |
575 | } |
576 | else if (aNbPlanes == 2) |
577 | { |
578 | aBits |= OpenGl_PO_ClipPlanes2; |
579 | } |
580 | else |
581 | { |
582 | aBits |= OpenGl_PO_ClipPlanesN; |
583 | } |
584 | return aBits; |
585 | } |
586 | |
8625ef7e |
587 | //! Define program bits. |
cc8cbabe |
588 | Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures, |
c40eb6b9 |
589 | Graphic3d_AlphaMode theAlphaMode, |
2a332745 |
590 | Aspect_InteriorStyle theInteriorStyle, |
c40eb6b9 |
591 | Standard_Boolean theHasVertColor, |
2a332745 |
592 | Standard_Boolean theEnableEnvMap, |
593 | Standard_Boolean theEnableMeshEdges) const |
8625ef7e |
594 | { |
595 | Standard_Integer aBits = 0; |
c40eb6b9 |
596 | if (theAlphaMode == Graphic3d_AlphaMode_Mask) |
597 | { |
598 | aBits |= OpenGl_PO_AlphaTest; |
599 | } |
1a7ece8f |
600 | |
2a332745 |
601 | aBits |= getClipPlaneBits(); |
602 | if (theEnableMeshEdges |
603 | && myContext->hasGeometryStage != OpenGl_FeatureNotAvailable) |
8625ef7e |
604 | { |
2a332745 |
605 | aBits |= OpenGl_PO_MeshEdges; |
606 | if (theInteriorStyle == Aspect_IS_HOLLOW) |
1a7ece8f |
607 | { |
2a332745 |
608 | aBits |= OpenGl_PO_AlphaTest; |
1a7ece8f |
609 | } |
8625ef7e |
610 | } |
1a7ece8f |
611 | |
83da37b1 |
612 | if (theEnableEnvMap) |
e135a155 |
613 | { |
614 | // Environment map overwrites material texture |
615 | aBits |= OpenGl_PO_TextureEnv; |
616 | } |
cc8cbabe |
617 | else if (!theTextures.IsNull() |
737e9a8d |
618 | && theTextures->HasNonPointSprite()) |
8625ef7e |
619 | { |
737e9a8d |
620 | aBits |= OpenGl_PO_TextureRGB; |
8625ef7e |
621 | } |
2a332745 |
622 | if (theHasVertColor |
623 | && theInteriorStyle != Aspect_IS_HIDDENLINE) |
8625ef7e |
624 | { |
625 | aBits |= OpenGl_PO_VertColor; |
626 | } |
a1073ae2 |
627 | |
628 | if (myOitState.ToEnableWrite()) |
629 | { |
630 | aBits |= OpenGl_PO_WriteOit; |
631 | } |
8625ef7e |
632 | return aBits; |
633 | } |
634 | |
635 | //! Prepare standard GLSL program. |
dc89236f |
636 | Handle(OpenGl_ShaderProgram)& getStdProgram (Graphic3d_TypeOfShadingModel theShadingModel, |
637 | Standard_Integer theBits) |
8625ef7e |
638 | { |
dc89236f |
639 | if (theShadingModel == Graphic3d_TOSM_UNLIT |
640 | || (theBits & OpenGl_PO_TextureEnv) != 0) |
8625ef7e |
641 | { |
dc89236f |
642 | // If environment map is enabled lighting calculations are |
643 | // not needed (in accordance with default OCCT behavior) |
6ef0d6f1 |
644 | Handle(OpenGl_ShaderProgram)& aProgram = myUnlitPrograms->ChangeValue (theBits); |
8625ef7e |
645 | if (aProgram.IsNull()) |
646 | { |
6ef0d6f1 |
647 | prepareStdProgramUnlit (aProgram, theBits, false); |
8625ef7e |
648 | } |
649 | return aProgram; |
650 | } |
651 | |
dc89236f |
652 | Handle(OpenGl_ShaderProgram)& aProgram = myLightPrograms->ChangeValue (theShadingModel, theBits); |
8625ef7e |
653 | if (aProgram.IsNull()) |
654 | { |
dc89236f |
655 | prepareStdProgramLight (aProgram, theShadingModel, theBits); |
8625ef7e |
656 | } |
657 | return aProgram; |
658 | } |
659 | |
299e0ab9 |
660 | //! Prepare standard GLSL program for accessing point sprite alpha. |
737e9a8d |
661 | Standard_EXPORT TCollection_AsciiString pointSpriteAlphaSrc (Standard_Integer theBits); |
299e0ab9 |
662 | |
663 | //! Prepare standard GLSL program for computing point sprite shading. |
737e9a8d |
664 | Standard_EXPORT TCollection_AsciiString pointSpriteShadingSrc (const TCollection_AsciiString& theBaseColorSrc, |
665 | Standard_Integer theBits); |
299e0ab9 |
666 | |
8625ef7e |
667 | //! Prepare standard GLSL program for textured font. |
668 | Standard_EXPORT Standard_Boolean prepareStdProgramFont(); |
669 | |
b86bb3df |
670 | //! Prepare standard GLSL program for FBO blit operation. |
ba00aab7 |
671 | Standard_EXPORT Standard_Boolean prepareStdProgramFboBlit (Handle(OpenGl_ShaderProgram)& theProgram, |
672 | Standard_Integer theNbSamples, |
673 | Standard_Boolean theIsFallback_sRGB); |
b86bb3df |
674 | |
a1073ae2 |
675 | //! Prepare standard GLSL programs for OIT compositing operation. |
676 | Standard_EXPORT Standard_Boolean prepareStdProgramOitCompositing (const Standard_Boolean theMsaa); |
677 | |
8625ef7e |
678 | //! Prepare standard GLSL program without lighting. |
dc89236f |
679 | Standard_EXPORT Standard_Boolean prepareStdProgramUnlit (Handle(OpenGl_ShaderProgram)& theProgram, |
6ef0d6f1 |
680 | Standard_Integer theBits, |
681 | Standard_Boolean theIsOutline = false); |
8625ef7e |
682 | |
683 | //! Prepare standard GLSL program with lighting. |
684 | Standard_Boolean prepareStdProgramLight (Handle(OpenGl_ShaderProgram)& theProgram, |
dc89236f |
685 | Graphic3d_TypeOfShadingModel theShadingModel, |
686 | Standard_Integer theBits) |
8625ef7e |
687 | { |
dc89236f |
688 | switch (theShadingModel) |
8c3237d4 |
689 | { |
67312b79 |
690 | case Graphic3d_TOSM_UNLIT: return prepareStdProgramUnlit (theProgram, theBits, false); |
691 | case Graphic3d_TOSM_FACET: return prepareStdProgramPhong (theProgram, theBits, true); |
692 | case Graphic3d_TOSM_VERTEX: return prepareStdProgramGouraud(theProgram, theBits); |
dc89236f |
693 | case Graphic3d_TOSM_DEFAULT: |
67312b79 |
694 | case Graphic3d_TOSM_FRAGMENT: return prepareStdProgramPhong (theProgram, theBits, false); |
695 | case Graphic3d_TOSM_PBR: return prepareStdProgramPhong (theProgram, theBits, false, true); |
696 | case Graphic3d_TOSM_PBR_FACET: return prepareStdProgramPhong (theProgram, theBits, true, true); |
8c3237d4 |
697 | } |
698 | return false; |
8625ef7e |
699 | } |
700 | |
701 | //! Prepare standard GLSL program with per-vertex lighting. |
702 | Standard_EXPORT Standard_Boolean prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram, |
703 | const Standard_Integer theBits); |
704 | |
705 | //! Prepare standard GLSL program with per-pixel lighting. |
8c3237d4 |
706 | //! @param theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will be computed instead |
67312b79 |
707 | //! @param theIsPBR when TRUE, the PBR pipeline will be activated |
8625ef7e |
708 | Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram, |
8c3237d4 |
709 | const Standard_Integer theBits, |
67312b79 |
710 | const Standard_Boolean theIsFlatNormal = false, |
711 | const Standard_Boolean theIsPBR = false); |
8625ef7e |
712 | |
256f9ac0 |
713 | //! Define computeLighting GLSL function depending on current lights configuration |
daf73ab7 |
714 | //! @param theNbLights [out] number of defined light sources |
715 | //! @param theHasVertColor [in] flag to use getVertColor() instead of Ambient and Diffuse components of active material |
67312b79 |
716 | //! @param theIsPBR [in] flag to activate PBR pipeline |
daf73ab7 |
717 | Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights, |
67312b79 |
718 | Standard_Boolean theHasVertColor, |
719 | Standard_Boolean theIsPBR); |
256f9ac0 |
720 | |
8625ef7e |
721 | //! Bind specified program to current context and apply state. |
299e0ab9 |
722 | Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram); |
8625ef7e |
723 | |
256f9ac0 |
724 | //! Set pointer myLightPrograms to active lighting programs set from myMapOfLightPrograms |
725 | Standard_EXPORT void switchLightPrograms(); |
726 | |
f978241f |
727 | //! Prepare standard GLSL program for stereoscopic image. |
728 | Standard_EXPORT Standard_Boolean prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram, |
729 | const Graphic3d_StereoMode theStereoMode); |
38a0206f |
730 | |
98b15dbf |
731 | //! Prepare standard GLSL program for bounding box. |
732 | Standard_EXPORT Standard_Boolean prepareStdProgramBoundBox(); |
733 | |
2a332745 |
734 | //! Prepare GLSL version header. |
735 | Standard_EXPORT Standard_Integer defaultGlslVersion (const Handle(Graphic3d_ShaderProgram)& theProgram, |
d95f5ce1 |
736 | const TCollection_AsciiString& theName, |
2a332745 |
737 | Standard_Integer theBits, |
738 | bool theUsesDerivates = false) const; |
739 | |
740 | //! Prepare GLSL source for geometry shader according to parameters. |
741 | Standard_EXPORT TCollection_AsciiString prepareGeomMainSrc (OpenGl_ShaderObject::ShaderVariableList& theUnifoms, |
742 | OpenGl_ShaderObject::ShaderVariableList& theStageInOuts, |
743 | Standard_Integer theBits); |
744 | |
67312b79 |
745 | //! Prepare GLSL source for IBL generation used in PBR pipeline. |
746 | Standard_EXPORT Standard_Boolean preparePBREnvBakingProgram(); |
747 | |
748 | //! Checks whether one of PBR shading models is set as default model. |
749 | Standard_Boolean IsPbrAllowed() const { return myShadingModel == Graphic3d_TOSM_PBR |
750 | || myShadingModel == Graphic3d_TOSM_PBR_FACET; } |
751 | |
7c3ef2f7 |
752 | protected: |
753 | |
754 | //! Packed properties of light source |
755 | struct OpenGl_ShaderLightParameters |
756 | { |
757 | OpenGl_Vec4 Color; |
758 | OpenGl_Vec4 Position; |
759 | OpenGl_Vec4 Direction; |
760 | OpenGl_Vec4 Parameters; |
761 | |
762 | //! Returns packed (serialized) representation of light source properties |
763 | const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); } |
764 | static Standard_Integer NbOfVec4() { return 4; } |
765 | }; |
766 | |
767 | //! Packed light source type information |
768 | struct OpenGl_ShaderLightType |
769 | { |
770 | Standard_Integer Type; |
771 | Standard_Integer IsHeadlight; |
772 | |
773 | //! Returns packed (serialized) representation of light source type |
774 | const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); } |
775 | static Standard_Integer NbOfVec2i() { return 1; } |
776 | }; |
777 | |
8613985b |
778 | //! Fake OpenGL program for tracking FFP state in the way consistent to programmable pipeline. |
779 | class OpenGl_ShaderProgramFFP : public OpenGl_ShaderProgram |
780 | { |
781 | DEFINE_STANDARD_RTTI_INLINE(OpenGl_ShaderProgramFFP, OpenGl_ShaderProgram) |
782 | friend class OpenGl_ShaderManager; |
783 | protected: |
784 | OpenGl_ShaderProgramFFP() {} |
785 | }; |
786 | |
25c35042 |
787 | protected: |
788 | |
789 | //! Append clipping plane definition to temporary buffers. |
790 | void addClippingPlane (Standard_Integer& thePlaneId, |
791 | const Graphic3d_ClipPlane& thePlane, |
792 | const Graphic3d_Vec4d& theEq, |
793 | const Standard_Integer theChainFwd) const |
794 | { |
795 | myClipChainArray.SetValue (thePlaneId, theChainFwd); |
796 | OpenGl_Vec4& aPlaneEq = myClipPlaneArray.ChangeValue (thePlaneId); |
797 | aPlaneEq.x() = float(theEq.x()); |
798 | aPlaneEq.y() = float(theEq.y()); |
799 | aPlaneEq.z() = float(theEq.z()); |
800 | aPlaneEq.w() = float(theEq.w()); |
801 | if (myHasLocalOrigin) |
802 | { |
edc4ba21 |
803 | aPlaneEq.w() = float(LocalClippingPlaneW (thePlane)); |
25c35042 |
804 | } |
805 | ++thePlaneId; |
806 | } |
807 | |
8625ef7e |
808 | protected: |
809 | |
8613985b |
810 | Handle(OpenGl_ShaderProgramFFP) myFfpProgram; |
811 | |
c357e426 |
812 | Graphic3d_TypeOfShadingModel myShadingModel; //!< lighting shading model |
256f9ac0 |
813 | OpenGl_ShaderProgramList myProgramList; //!< The list of shader programs |
814 | Handle(OpenGl_SetOfShaderPrograms) myLightPrograms; //!< pointer to active lighting programs matrix |
6ef0d6f1 |
815 | Handle(OpenGl_SetOfPrograms) myUnlitPrograms; //!< programs matrix without lighting |
816 | Handle(OpenGl_SetOfPrograms) myOutlinePrograms; //!< programs matrix without lighting for outline presentation |
256f9ac0 |
817 | Handle(OpenGl_ShaderProgram) myFontProgram; //!< standard program for textured text |
ba00aab7 |
818 | NCollection_Array1<Handle(OpenGl_ShaderProgram)> |
819 | myBlitPrograms[2]; //!< standard program for FBO blit emulation |
98b15dbf |
820 | Handle(OpenGl_ShaderProgram) myBoundBoxProgram; //!< standard program for bounding box |
a1073ae2 |
821 | Handle(OpenGl_ShaderProgram) myOitCompositingProgram[2]; //!< standard program for OIT compositing (default and MSAA). |
dc89236f |
822 | OpenGl_MapOfShaderPrograms myMapOfLightPrograms; //!< map of lighting programs depending on lights configuration |
8625ef7e |
823 | |
67312b79 |
824 | Handle(OpenGl_ShaderProgram) myPBREnvBakingProgram;//!< program for IBL maps generation used in PBR pipeline |
077a220c |
825 | Handle(Graphic3d_ShaderProgram) myBgCubeMapProgram; //!< program for background cubemap rendering |
826 | |
f978241f |
827 | Handle(OpenGl_ShaderProgram) myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs |
38a0206f |
828 | |
98b15dbf |
829 | Handle(OpenGl_VertexBuffer) myBoundBoxVertBuffer; //!< bounding box vertex buffer |
830 | |
67312b79 |
831 | mutable Handle(OpenGl_PBREnvironment) myPBREnvironment; //!< manager of IBL maps used in PBR pipeline |
832 | |
256f9ac0 |
833 | OpenGl_Context* myContext; //!< OpenGL context |
ba00aab7 |
834 | Standard_Boolean mySRgbState; //!< track sRGB state |
8625ef7e |
835 | |
836 | protected: |
837 | |
256f9ac0 |
838 | OpenGl_ProjectionState myProjectionState; //!< State of OCCT projection transformation |
839 | OpenGl_ModelWorldState myModelWorldState; //!< State of OCCT model-world transformation |
840 | OpenGl_WorldViewState myWorldViewState; //!< State of OCCT world-view transformation |
8cf06aa2 |
841 | OpenGl_ClippingState myClippingState; //!< State of OCCT clipping planes |
256f9ac0 |
842 | OpenGl_LightSourceState myLightSourceState; //!< State of OCCT light sources |
8613985b |
843 | OpenGl_MaterialState myMaterialState; //!< State of Front and Back materials |
a1073ae2 |
844 | OpenGl_OitState myOitState; //!< State of OIT uniforms |
8613985b |
845 | |
7c3ef2f7 |
846 | gp_XYZ myLocalOrigin; //!< local camera transformation |
847 | Standard_Boolean myHasLocalOrigin; //!< flag indicating that local camera transformation has been set |
848 | |
daf73ab7 |
849 | mutable NCollection_Array1<OpenGl_ShaderLightType> myLightTypeArray; |
850 | mutable NCollection_Array1<OpenGl_ShaderLightParameters> myLightParamsArray; |
851 | mutable NCollection_Array1<OpenGl_Vec4> myClipPlaneArray; |
852 | mutable NCollection_Array1<OpenGl_Vec4d> myClipPlaneArrayFfp; |
25c35042 |
853 | mutable NCollection_Array1<Standard_Integer> myClipChainArray; |
30f0ad28 |
854 | |
855 | private: |
856 | |
256f9ac0 |
857 | const OpenGl_View* myLastView; //!< Pointer to the last view shader manager used with |
8625ef7e |
858 | |
30f0ad28 |
859 | }; |
860 | |
8613985b |
861 | DEFINE_STANDARD_HANDLE(OpenGl_ShaderManager, Standard_Transient) |
862 | |
30f0ad28 |
863 | #endif // _OpenGl_ShaderManager_HeaderFile |