1 // Created on: 2013-09-26
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #ifndef _OpenGl_ShaderManager_HeaderFile
17 #define _OpenGl_ShaderManager_HeaderFile
19 #include <Graphic3d_ShaderProgram.hxx>
20 #include <Graphic3d_StereoMode.hxx>
21 #include <Graphic3d_TypeOfShadingModel.hxx>
23 #include <NCollection_DataMap.hxx>
24 #include <NCollection_Sequence.hxx>
26 #include <OpenGl_SetOfShaderPrograms.hxx>
27 #include <OpenGl_ShaderStates.hxx>
28 #include <OpenGl_AspectFace.hxx>
29 #include <OpenGl_AspectLine.hxx>
30 #include <OpenGl_AspectText.hxx>
31 #include <OpenGl_AspectMarker.hxx>
32 #include <OpenGl_MaterialState.hxx>
33 #include <OpenGl_Texture.hxx>
37 //! List of shader programs.
38 typedef NCollection_Sequence<Handle(OpenGl_ShaderProgram)> OpenGl_ShaderProgramList;
40 //! This class is responsible for managing shader programs.
41 class OpenGl_ShaderManager : public Standard_Transient
43 DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
44 friend class OpenGl_ShaderProgram;
47 //! Creates new empty shader manager.
48 Standard_EXPORT OpenGl_ShaderManager (OpenGl_Context* theContext);
50 //! Releases resources of shader manager.
51 Standard_EXPORT virtual ~OpenGl_ShaderManager();
53 //! Release all resources.
54 Standard_EXPORT void clear();
56 //! Return local camera transformation.
57 const gp_XYZ& LocalOrigin() const { return myLocalOrigin; }
59 //! Setup local camera transformation for compensating float precision issues.
60 void SetLocalOrigin (const gp_XYZ& theOrigin)
62 myLocalOrigin = theOrigin;
63 myHasLocalOrigin = !theOrigin.IsEqual (gp_XYZ(0.0, 0.0, 0.0), gp::Resolution());
66 //! Creates new shader program or re-use shared instance.
67 //! @param theProxy [IN] program definition
68 //! @param theShareKey [OUT] sharing key
69 //! @param theProgram [OUT] OpenGL program
70 //! @return true on success
71 Standard_EXPORT Standard_Boolean Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
72 TCollection_AsciiString& theShareKey,
73 Handle(OpenGl_ShaderProgram)& theProgram);
75 //! Unregisters specified shader program.
76 Standard_EXPORT void Unregister (TCollection_AsciiString& theShareKey,
77 Handle(OpenGl_ShaderProgram)& theProgram);
79 //! Returns list of registered shader programs.
80 Standard_EXPORT const OpenGl_ShaderProgramList& ShaderPrograms() const;
82 //! Returns true if no program objects are registered in the manager.
83 Standard_EXPORT Standard_Boolean IsEmpty() const;
85 //! Bind program for filled primitives rendering
86 Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures,
87 const Standard_Boolean theToLightOn,
88 const Standard_Boolean theHasVertColor,
89 const Standard_Boolean theEnableEnvMap,
90 const Handle(OpenGl_ShaderProgram)& theCustomProgram)
92 if (!theCustomProgram.IsNull()
93 || myContext->caps->ffpEnable)
95 return bindProgramWithState (theCustomProgram);
98 const Standard_Integer aBits = getProgramBits (theTextures, theHasVertColor, theEnableEnvMap);
99 Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theToLightOn, aBits);
100 return bindProgramWithState (aProgram);
103 //! Bind program for line rendering
104 Standard_Boolean BindLineProgram (const Handle(OpenGl_TextureSet)& theTextures,
105 const Standard_Boolean theStipple,
106 const Standard_Boolean theToLightOn,
107 const Standard_Boolean theHasVertColor,
108 const Handle(OpenGl_ShaderProgram)& theCustomProgram)
110 if (!theCustomProgram.IsNull()
111 || myContext->caps->ffpEnable)
113 return bindProgramWithState (theCustomProgram);
116 Standard_Integer aBits = getProgramBits (theTextures, theHasVertColor);
119 aBits |= OpenGl_PO_StippleLine;
122 Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theToLightOn, aBits);
123 return bindProgramWithState (aProgram);
126 //! Bind program for point rendering
127 Standard_Boolean BindMarkerProgram (const Handle(OpenGl_TextureSet)& theTextures,
128 const Standard_Boolean theToLightOn,
129 const Standard_Boolean theHasVertColor,
130 const Handle(OpenGl_ShaderProgram)& theCustomProgram)
132 if (!theCustomProgram.IsNull()
133 || myContext->caps->ffpEnable)
135 return bindProgramWithState (theCustomProgram);
138 const Standard_Integer aBits = getProgramBits (theTextures, theHasVertColor) | OpenGl_PO_Point;
139 Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theToLightOn, aBits);
140 return bindProgramWithState (aProgram);
143 //! Bind program for rendering alpha-textured font.
144 Standard_Boolean BindFontProgram (const Handle(OpenGl_ShaderProgram)& theCustomProgram)
146 if (!theCustomProgram.IsNull()
147 || myContext->caps->ffpEnable)
149 return bindProgramWithState (theCustomProgram);
152 if (myFontProgram.IsNull())
154 prepareStdProgramFont();
157 return bindProgramWithState (myFontProgram);
160 //! Bind program for FBO blit operation.
161 Standard_Boolean BindFboBlitProgram()
163 if (myBlitProgram.IsNull())
165 prepareStdProgramFboBlit();
167 return !myBlitProgram.IsNull()
168 && myContext->BindProgram (myBlitProgram);
171 //! Bind program for blended order-independent transparency buffers compositing.
172 Standard_Boolean BindOitCompositingProgram (const Standard_Boolean theIsMSAAEnabled)
174 const Standard_Integer aProgramIdx = theIsMSAAEnabled ? 1 : 0;
175 if (myOitCompositingProgram[aProgramIdx].IsNull())
177 prepareStdProgramOitCompositing (theIsMSAAEnabled);
180 const Handle(OpenGl_ShaderProgram)& aProgram = myOitCompositingProgram [aProgramIdx];
181 return !aProgram.IsNull() && myContext->BindProgram (aProgram);
184 //! Bind program for rendering stereoscopic image.
185 Standard_Boolean BindStereoProgram (const Graphic3d_StereoMode theStereoMode)
187 if (theStereoMode < 0 || theStereoMode >= Graphic3d_StereoMode_NB)
189 return Standard_False;
192 if (myStereoPrograms[theStereoMode].IsNull())
194 prepareStdProgramStereo (myStereoPrograms[theStereoMode], theStereoMode);
196 const Handle(OpenGl_ShaderProgram)& aProgram = myStereoPrograms[theStereoMode];
197 return !aProgram.IsNull()
198 && myContext->BindProgram (aProgram);
203 //! Returns current state of OCCT light sources.
204 const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; }
206 //! Updates state of OCCT light sources.
207 Standard_EXPORT void UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights);
209 //! Invalidate state of OCCT light sources.
210 Standard_EXPORT void UpdateLightSourceState();
212 //! Pushes current state of OCCT light sources to specified program.
213 Standard_EXPORT void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
217 //! Returns current state of OCCT projection transform.
218 const OpenGl_ProjectionState& ProjectionState() const { return myProjectionState; }
220 //! Updates state of OCCT projection transform.
221 Standard_EXPORT void UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix);
223 //! Pushes current state of OCCT projection transform to specified program.
224 Standard_EXPORT void PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
228 //! Returns current state of OCCT model-world transform.
229 const OpenGl_ModelWorldState& ModelWorldState() const { return myModelWorldState; }
231 //! Updates state of OCCT model-world transform.
232 Standard_EXPORT void UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix);
234 //! Pushes current state of OCCT model-world transform to specified program.
235 Standard_EXPORT void PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
239 //! Returns current state of OCCT world-view transform.
240 const OpenGl_WorldViewState& WorldViewState() const { return myWorldViewState; }
242 //! Updates state of OCCT world-view transform.
243 Standard_EXPORT void UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix);
245 //! Pushes current state of OCCT world-view transform to specified program.
246 Standard_EXPORT void PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
250 //! Updates state of OCCT clipping planes.
251 Standard_EXPORT void UpdateClippingState();
253 //! Reverts state of OCCT clipping planes.
254 Standard_EXPORT void RevertClippingState();
256 //! Pushes current state of OCCT clipping planes to specified program.
257 Standard_EXPORT void PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
261 //! Returns current state of material.
262 const OpenGl_MaterialState& MaterialState() const { return myMaterialState; }
264 //! Updates state of material.
265 void UpdateMaterialStateTo (const OpenGl_Material& theFrontMat,
266 const OpenGl_Material& theBackMat,
267 const bool theToDistinguish,
268 const bool theToMapTexture)
270 myMaterialState.Set (theFrontMat, theBackMat, theToDistinguish, theToMapTexture);
271 myMaterialState.Update();
274 //! Updates state of material.
275 void UpdateMaterialState()
277 myMaterialState.Update();
280 //! Pushes current state of material to specified program.
281 void PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
285 //! Set the state of OIT rendering pass.
286 //! @param theToEnableOitWrite [in] flag indicating whether the special output should be written for OIT algorithm.
287 //! @param theDepthFactor [in] the scalar factor of depth influence to the fragment's coverage.
288 void SetOitState (const bool theToEnableOitWrite, const float theDepthFactor)
290 myOitState.Set (theToEnableOitWrite, theDepthFactor);
294 //! Pushes state of OIT uniforms to the specified program.
295 Standard_EXPORT void PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
299 //! Pushes current state of OCCT graphics parameters to specified program.
300 Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
304 //! Overwrites context
305 void SetContext (OpenGl_Context* theCtx)
310 //! Returns true when provided context is the same as used one by shader manager.
311 bool IsSameContext (OpenGl_Context* theCtx) const
313 return myContext == theCtx;
316 //! Sets shading model.
317 Standard_EXPORT void SetShadingModel (const Graphic3d_TypeOfShadingModel theModel);
319 //! Sets last view manger used with.
320 //! Helps to handle matrix states in multi-view configurations.
321 void SetLastView (const OpenGl_View* theLastView)
323 myLastView = theLastView;
326 //! Returns true when provided view is the same as cached one.
327 bool IsSameView (const OpenGl_View* theView) const
329 return myLastView == theView;
334 //! Define program bits.
335 Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures,
336 const Standard_Boolean theHasVertColor,
337 const Standard_Boolean theEnableEnvMap = Standard_False)
340 Standard_Integer aBits = 0;
342 const Standard_Integer aNbPlanes = myContext->Clipping().NbClippingOrCappingOn();
345 aBits |= OpenGl_PO_ClipPlanesN;
348 aBits |= OpenGl_PO_ClipPlanes1;
350 else if (aNbPlanes == 2)
352 aBits |= OpenGl_PO_ClipPlanes2;
358 // Environment map overwrites material texture
359 aBits |= OpenGl_PO_TextureEnv;
361 else if (!theTextures.IsNull()
362 && !theTextures->IsEmpty()
363 && !theTextures->First().IsNull())
365 aBits |= theTextures->First()->IsAlpha() ? OpenGl_PO_TextureA : OpenGl_PO_TextureRGB;
369 aBits |= OpenGl_PO_VertColor;
372 if (myOitState.ToEnableWrite())
374 aBits |= OpenGl_PO_WriteOit;
379 //! Prepare standard GLSL program.
380 Handle(OpenGl_ShaderProgram)& getStdProgram (const Standard_Boolean theToLightOn,
381 const Standard_Integer theBits)
383 // If environment map is enabled lighting calculations are
384 // not needed (in accordance with default OCCT behaviour)
385 if (theToLightOn && (theBits & OpenGl_PO_TextureEnv) == 0)
387 Handle(OpenGl_ShaderProgram)& aProgram = myLightPrograms->ChangeValue (theBits);
388 if (aProgram.IsNull())
390 prepareStdProgramLight (aProgram, theBits);
395 Handle(OpenGl_ShaderProgram)& aProgram = myFlatPrograms.ChangeValue (theBits);
396 if (aProgram.IsNull())
398 prepareStdProgramFlat (aProgram, theBits);
403 //! Prepare standard GLSL program for accessing point sprite alpha.
404 Standard_EXPORT TCollection_AsciiString pointSpriteAlphaSrc (const Standard_Integer theBits);
406 //! Prepare standard GLSL program for computing point sprite shading.
407 Standard_EXPORT TCollection_AsciiString pointSpriteShadingSrc (const TCollection_AsciiString theBaseColorSrc, const Standard_Integer theBits);
409 //! Prepare standard GLSL program for textured font.
410 Standard_EXPORT Standard_Boolean prepareStdProgramFont();
412 //! Prepare standard GLSL program for FBO blit operation.
413 Standard_EXPORT Standard_Boolean prepareStdProgramFboBlit();
415 //! Prepare standard GLSL programs for OIT compositing operation.
416 Standard_EXPORT Standard_Boolean prepareStdProgramOitCompositing (const Standard_Boolean theMsaa);
418 //! Prepare standard GLSL program without lighting.
419 Standard_EXPORT Standard_Boolean prepareStdProgramFlat (Handle(OpenGl_ShaderProgram)& theProgram,
420 const Standard_Integer theBits);
422 //! Prepare standard GLSL program with lighting.
423 Standard_Boolean prepareStdProgramLight (Handle(OpenGl_ShaderProgram)& theProgram,
424 const Standard_Integer theBits)
426 switch (myShadingModel)
428 case Graphic3d_TOSM_NONE: return prepareStdProgramFlat (theProgram, theBits);
429 case Graphic3d_TOSM_FACET: return prepareStdProgramPhong (theProgram, theBits, true);
430 case Graphic3d_TOSM_VERTEX: return prepareStdProgramGouraud(theProgram, theBits);
431 case Graphic3d_TOSM_FRAGMENT: return prepareStdProgramPhong (theProgram, theBits, false);
436 //! Prepare standard GLSL program with per-vertex lighting.
437 Standard_EXPORT Standard_Boolean prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
438 const Standard_Integer theBits);
440 //! Prepare standard GLSL program with per-pixel lighting.
441 //! @param theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will be computed instead
442 Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
443 const Standard_Integer theBits,
444 const Standard_Boolean theIsFlatNormal = false);
446 //! Define computeLighting GLSL function depending on current lights configuration
447 //! @param theHasVertColor flag to use getVertColor() instead of Ambient and Diffuse components of active material
448 Standard_EXPORT TCollection_AsciiString stdComputeLighting (const Standard_Boolean theHasVertColor);
450 //! Bind specified program to current context and apply state.
451 Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram);
453 //! Set pointer myLightPrograms to active lighting programs set from myMapOfLightPrograms
454 Standard_EXPORT void switchLightPrograms();
456 //! Prepare standard GLSL program for stereoscopic image.
457 Standard_EXPORT Standard_Boolean prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram,
458 const Graphic3d_StereoMode theStereoMode);
462 //! Packed properties of light source
463 struct OpenGl_ShaderLightParameters
466 OpenGl_Vec4 Position;
467 OpenGl_Vec4 Direction;
468 OpenGl_Vec4 Parameters;
470 //! Returns packed (serialized) representation of light source properties
471 const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
472 static Standard_Integer NbOfVec4() { return 4; }
475 //! Packed light source type information
476 struct OpenGl_ShaderLightType
478 Standard_Integer Type;
479 Standard_Integer IsHeadlight;
481 //! Returns packed (serialized) representation of light source type
482 const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
483 static Standard_Integer NbOfVec2i() { return 1; }
486 //! Fake OpenGL program for tracking FFP state in the way consistent to programmable pipeline.
487 class OpenGl_ShaderProgramFFP : public OpenGl_ShaderProgram
489 DEFINE_STANDARD_RTTI_INLINE(OpenGl_ShaderProgramFFP, OpenGl_ShaderProgram)
490 friend class OpenGl_ShaderManager;
492 OpenGl_ShaderProgramFFP() {}
497 Handle(OpenGl_ShaderProgramFFP) myFfpProgram;
499 Graphic3d_TypeOfShadingModel myShadingModel; //!< lighting shading model
500 OpenGl_ShaderProgramList myProgramList; //!< The list of shader programs
501 Handle(OpenGl_SetOfShaderPrograms) myLightPrograms; //!< pointer to active lighting programs matrix
502 OpenGl_SetOfShaderPrograms myFlatPrograms; //!< programs matrix without lighting
503 Handle(OpenGl_ShaderProgram) myFontProgram; //!< standard program for textured text
504 Handle(OpenGl_ShaderProgram) myBlitProgram; //!< standard program for FBO blit emulation
505 Handle(OpenGl_ShaderProgram) myOitCompositingProgram[2]; //!< standard program for OIT compositing (default and MSAA).
506 OpenGl_MapOfShaderPrograms myMapOfLightPrograms; //!< map of lighting programs depending on shading model and lights configuration
508 Handle(OpenGl_ShaderProgram) myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs
510 OpenGl_Context* myContext; //!< OpenGL context
514 OpenGl_ProjectionState myProjectionState; //!< State of OCCT projection transformation
515 OpenGl_ModelWorldState myModelWorldState; //!< State of OCCT model-world transformation
516 OpenGl_WorldViewState myWorldViewState; //!< State of OCCT world-view transformation
517 OpenGl_ClippingState myClippingState; //!< State of OCCT clipping planes
518 OpenGl_LightSourceState myLightSourceState; //!< State of OCCT light sources
519 OpenGl_MaterialState myMaterialState; //!< State of Front and Back materials
520 OpenGl_OitState myOitState; //!< State of OIT uniforms
522 gp_XYZ myLocalOrigin; //!< local camera transformation
523 Standard_Boolean myHasLocalOrigin; //!< flag indicating that local camera transformation has been set
525 mutable OpenGl_ShaderLightType myLightTypeArray [OpenGLMaxLights];
526 mutable OpenGl_ShaderLightParameters myLightParamsArray[OpenGLMaxLights];
530 const OpenGl_View* myLastView; //!< Pointer to the last view shader manager used with
534 DEFINE_STANDARD_HANDLE(OpenGl_ShaderManager, Standard_Transient)
536 #endif // _OpenGl_ShaderManager_HeaderFile