3fdacc2976d6ec4ade2601d1117f6612f77ccaa5
[occt.git] / src / OpenGl / OpenGl_ShaderManager.hxx
1 // Created on: 2013-09-26
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _OpenGl_ShaderManager_HeaderFile
17 #define _OpenGl_ShaderManager_HeaderFile
18
19 #include <Graphic3d_ShaderProgram.hxx>
20 #include <Graphic3d_StereoMode.hxx>
21
22 #include <NCollection_DataMap.hxx>
23 #include <NCollection_Sequence.hxx>
24
25 #include <OpenGl_SetOfShaderPrograms.hxx>
26 #include <OpenGl_ShaderStates.hxx>
27 #include <OpenGl_Aspects.hxx>
28 #include <OpenGl_MaterialState.hxx>
29 #include <OpenGl_Texture.hxx>
30
31 class OpenGl_View;
32 class OpenGl_VertexBuffer;
33
34 //! List of shader programs.
35 typedef NCollection_Sequence<Handle(OpenGl_ShaderProgram)> OpenGl_ShaderProgramList;
36
37 //! This class is responsible for managing shader programs.
38 class OpenGl_ShaderManager : public Standard_Transient
39 {
40   DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
41   friend class OpenGl_ShaderProgram;
42 public:
43
44   //! Creates new empty shader manager.
45   Standard_EXPORT OpenGl_ShaderManager (OpenGl_Context* theContext);
46
47   //! Releases resources of shader manager.
48   Standard_EXPORT virtual ~OpenGl_ShaderManager();
49
50   //! Release all resources.
51   Standard_EXPORT void clear();
52
53   //! Return local camera transformation.
54   const gp_XYZ& LocalOrigin() const { return myLocalOrigin; }
55
56   //! Setup local camera transformation for compensating float precision issues.
57   void SetLocalOrigin (const gp_XYZ& theOrigin)
58   {
59     myLocalOrigin    = theOrigin;
60     myHasLocalOrigin = !theOrigin.IsEqual (gp_XYZ(0.0, 0.0, 0.0), gp::Resolution());
61   }
62
63   //! Creates new shader program or re-use shared instance.
64   //! @param theProxy    [IN]  program definition
65   //! @param theShareKey [OUT] sharing key
66   //! @param theProgram  [OUT] OpenGL program
67   //! @return true on success
68   Standard_EXPORT Standard_Boolean Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
69                                            TCollection_AsciiString&               theShareKey,
70                                            Handle(OpenGl_ShaderProgram)&          theProgram);
71
72   //! Unregisters specified shader program.
73   Standard_EXPORT void Unregister (TCollection_AsciiString&      theShareKey,
74                                    Handle(OpenGl_ShaderProgram)& theProgram);
75
76   //! Returns list of registered shader programs.
77   Standard_EXPORT const OpenGl_ShaderProgramList& ShaderPrograms() const;
78
79   //! Returns true if no program objects are registered in the manager.
80   Standard_EXPORT Standard_Boolean IsEmpty() const;
81
82   //! Bind program for filled primitives rendering
83   Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures,
84                                     Graphic3d_TypeOfShadingModel theShadingModel,
85                                     Graphic3d_AlphaMode theAlphaMode,
86                                     Standard_Boolean theHasVertColor,
87                                     Standard_Boolean theEnableEnvMap,
88                                     const Handle(OpenGl_ShaderProgram)& theCustomProgram)
89   {
90     return BindFaceProgram (theTextures, theShadingModel, theAlphaMode, Aspect_IS_SOLID,
91                             theHasVertColor, theEnableEnvMap, false, theCustomProgram);
92   }
93
94   //! Bind program for filled primitives rendering
95   Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures,
96                                     Graphic3d_TypeOfShadingModel theShadingModel,
97                                     Graphic3d_AlphaMode theAlphaMode,
98                                     Aspect_InteriorStyle theInteriorStyle,
99                                     Standard_Boolean theHasVertColor,
100                                     Standard_Boolean theEnableEnvMap,
101                                     Standard_Boolean theEnableMeshEdges,
102                                     const Handle(OpenGl_ShaderProgram)& theCustomProgram)
103   {
104     if (!theCustomProgram.IsNull()
105      || myContext->caps->ffpEnable)
106     {
107       return bindProgramWithState (theCustomProgram);
108     }
109
110     const Graphic3d_TypeOfShadingModel aShadeModelOnFace = theShadingModel != Graphic3d_TOSM_UNLIT
111                                                         && (theTextures.IsNull() || theTextures->IsModulate())
112                                                         ? theShadingModel
113                                                         : Graphic3d_TOSM_UNLIT;
114     const Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, theInteriorStyle, theHasVertColor, theEnableEnvMap, theEnableMeshEdges);
115     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (aShadeModelOnFace, aBits);
116     return bindProgramWithState (aProgram);
117   }
118
119   //! Bind program for line rendering
120   Standard_Boolean BindLineProgram (const Handle(OpenGl_TextureSet)&    theTextures,
121                                     const Aspect_TypeOfLine             theLineType,
122                                     const Graphic3d_TypeOfShadingModel  theShadingModel,
123                                     const Graphic3d_AlphaMode           theAlphaMode,
124                                     const Standard_Boolean              theHasVertColor,
125                                     const Handle(OpenGl_ShaderProgram)& theCustomProgram)
126   {
127     if (!theCustomProgram.IsNull()
128      || myContext->caps->ffpEnable)
129     {
130       return bindProgramWithState (theCustomProgram);
131     }
132
133     Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, Aspect_IS_SOLID, theHasVertColor, false, false);
134     if (theLineType != Aspect_TOL_SOLID)
135     {
136       aBits |= OpenGl_PO_StippleLine;
137     }
138
139     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theShadingModel, aBits);
140     return bindProgramWithState (aProgram);
141   }
142
143   //! Bind program for point rendering
144   Standard_Boolean BindMarkerProgram (const Handle(OpenGl_TextureSet)&    theTextures,
145                                       const Graphic3d_TypeOfShadingModel  theShadingModel,
146                                       const Graphic3d_AlphaMode           theAlphaMode,
147                                       const Standard_Boolean              theHasVertColor,
148                                       const Handle(OpenGl_ShaderProgram)& theCustomProgram)
149   {
150     if (!theCustomProgram.IsNull()
151      || myContext->caps->ffpEnable)
152     {
153       return bindProgramWithState (theCustomProgram);
154     }
155
156     const Standard_Integer        aBits    = getProgramBits (theTextures, theAlphaMode, Aspect_IS_SOLID, theHasVertColor, false, false) | OpenGl_PO_Point;
157     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theShadingModel, aBits);
158     return bindProgramWithState (aProgram);
159   }
160
161   //! Bind program for rendering alpha-textured font.
162   Standard_Boolean BindFontProgram (const Handle(OpenGl_ShaderProgram)& theCustomProgram)
163   {
164     if (!theCustomProgram.IsNull()
165      || myContext->caps->ffpEnable)
166     {
167       return bindProgramWithState (theCustomProgram);
168     }
169
170     if (myFontProgram.IsNull())
171     {
172       prepareStdProgramFont();
173     }
174
175     return bindProgramWithState (myFontProgram);
176   }
177
178   //! Bind program for outline rendering
179   Standard_Boolean BindOutlineProgram()
180   {
181     if (myContext->caps->ffpEnable)
182     {
183       return false;
184     }
185
186     const Standard_Integer aBits = getProgramBits (Handle(OpenGl_TextureSet)(), Graphic3d_AlphaMode_Opaque, Aspect_IS_SOLID, false, false, false);
187     if (myOutlinePrograms.IsNull())
188     {
189       myOutlinePrograms = new OpenGl_SetOfPrograms();
190     }
191     Handle(OpenGl_ShaderProgram)& aProgram = myOutlinePrograms->ChangeValue (aBits);
192     if (aProgram.IsNull())
193     {
194       prepareStdProgramUnlit (aProgram, aBits, true);
195     }
196     return bindProgramWithState (aProgram);
197   }
198
199   //! Bind program for FBO blit operation.
200   Standard_Boolean BindFboBlitProgram()
201   {
202     if (myBlitProgram.IsNull())
203     {
204       prepareStdProgramFboBlit();
205     }
206     return !myBlitProgram.IsNull()
207          && myContext->BindProgram (myBlitProgram);
208   }
209
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
223   //! Bind program for rendering stereoscopic image.
224   Standard_Boolean BindStereoProgram (const Graphic3d_StereoMode theStereoMode)
225   {
226     if (theStereoMode < 0 || theStereoMode >= Graphic3d_StereoMode_NB)
227     {
228       return Standard_False;
229     }
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);
238   }
239
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
253 public:
254
255   //! Returns current state of OCCT light sources.
256   const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; }
257
258   //! Updates state of OCCT light sources.
259   Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights);
260
261   //! Invalidate state of OCCT light sources.
262   Standard_EXPORT void UpdateLightSourceState();
263
264   //! Pushes current state of OCCT light sources to specified program.
265   Standard_EXPORT void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
266
267 public:
268
269   //! Returns current state of OCCT projection transform.
270   const OpenGl_ProjectionState& ProjectionState() const { return myProjectionState; }
271
272   //! Updates state of OCCT projection transform.
273   Standard_EXPORT void UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix);
274
275   //! Pushes current state of OCCT projection transform to specified program.
276   Standard_EXPORT void PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
277
278 public:
279
280   //! Returns current state of OCCT model-world transform.
281   const OpenGl_ModelWorldState& ModelWorldState() const { return myModelWorldState; }
282
283   //! Updates state of OCCT model-world transform.
284   Standard_EXPORT void UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix);
285
286   //! Pushes current state of OCCT model-world transform to specified program.
287   Standard_EXPORT void PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
288
289 public:
290
291   //! Returns current state of OCCT world-view transform.
292   const OpenGl_WorldViewState& WorldViewState() const { return myWorldViewState; }
293
294   //! Updates state of OCCT world-view transform.
295   Standard_EXPORT void UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix);
296
297   //! Pushes current state of OCCT world-view transform to specified program.
298   Standard_EXPORT void PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
299
300 public:
301
302   //! Updates state of OCCT clipping planes.
303   Standard_EXPORT void UpdateClippingState();
304
305   //! Reverts state of OCCT clipping planes.
306   Standard_EXPORT void RevertClippingState();
307
308   //! Pushes current state of OCCT clipping planes to specified program.
309   Standard_EXPORT void PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
310
311 public:
312
313   //! Returns current state of material.
314   const OpenGl_MaterialState& MaterialState() const { return myMaterialState; }
315
316   //! Updates state of material.
317   void UpdateMaterialStateTo (const OpenGl_Material& theFrontMat,
318                               const OpenGl_Material& theBackMat,
319                               const float theAlphaCutoff,
320                               const bool theToDistinguish,
321                               const bool theToMapTexture)
322   {
323     myMaterialState.Set (theFrontMat, theBackMat, theAlphaCutoff, theToDistinguish, theToMapTexture);
324     myMaterialState.Update();
325   }
326
327   //! Updates state of material.
328   void UpdateMaterialState()
329   {
330     myMaterialState.Update();
331   }
332
333   //! Pushes current state of material to specified program.
334   void PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
335
336 public:
337
338   //! Setup interior style line edges variables.
339   Standard_EXPORT void PushInteriorState (const Handle(OpenGl_ShaderProgram)& theProgram,
340                                           const Handle(Graphic3d_Aspects)& theAspect) const;
341
342 public:
343
344   //! Returns state of OIT uniforms.
345   const OpenGl_OitState& OitState() const { return myOitState; }
346
347   //! Set the state of OIT rendering pass.
348   //! @param theToEnableOitWrite [in] flag indicating whether the special output should be written for OIT algorithm.
349   //! @param theDepthFactor [in] the scalar factor of depth influence to the fragment's coverage.
350   void SetOitState (const bool theToEnableOitWrite, const float theDepthFactor)
351   {
352     myOitState.Set (theToEnableOitWrite, theDepthFactor);
353     myOitState.Update();
354   }
355
356   //! Pushes state of OIT uniforms to the specified program.
357   Standard_EXPORT void PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
358
359 public:
360
361   //! Pushes current state of OCCT graphics parameters to specified program.
362   Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
363
364 public:
365
366   //! Overwrites context
367   void SetContext (OpenGl_Context* theCtx)
368   {
369     myContext = theCtx;
370   }
371
372   //! Returns true when provided context is the same as used one by shader manager.
373   bool IsSameContext (OpenGl_Context* theCtx) const
374   {
375     return myContext == theCtx;
376   }
377
378   //! Choose Shading Model for filled primitives.
379   //! Fallbacks to FACET model if there are no normal attributes.
380   Graphic3d_TypeOfShadingModel ChooseFaceShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
381                                                        bool theHasNodalNormals) const
382   {
383     if (!myContext->ColorMask())
384     {
385       return Graphic3d_TOSM_UNLIT;
386     }
387     Graphic3d_TypeOfShadingModel aModel = theCustomModel != Graphic3d_TOSM_DEFAULT ? theCustomModel : myShadingModel;
388     switch (aModel)
389     {
390       case Graphic3d_TOSM_DEFAULT:
391       case Graphic3d_TOSM_UNLIT:
392       case Graphic3d_TOSM_FACET:
393         return aModel;
394       case Graphic3d_TOSM_VERTEX:
395       case Graphic3d_TOSM_FRAGMENT:
396         return theHasNodalNormals ? aModel : Graphic3d_TOSM_FACET;
397     }
398     return Graphic3d_TOSM_UNLIT;
399   }
400
401   //! Choose Shading Model for line primitives.
402   //! Fallbacks to UNLIT model if there are no normal attributes.
403   Graphic3d_TypeOfShadingModel ChooseLineShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
404                                                        bool theHasNodalNormals) const
405   {
406     if (!myContext->ColorMask())
407     {
408       return Graphic3d_TOSM_UNLIT;
409     }
410     Graphic3d_TypeOfShadingModel aModel = theCustomModel != Graphic3d_TOSM_DEFAULT ? theCustomModel : myShadingModel;
411     switch (aModel)
412     {
413       case Graphic3d_TOSM_DEFAULT:
414       case Graphic3d_TOSM_UNLIT:
415       case Graphic3d_TOSM_FACET:
416         return Graphic3d_TOSM_UNLIT;
417       case Graphic3d_TOSM_VERTEX:
418       case Graphic3d_TOSM_FRAGMENT:
419         return theHasNodalNormals ? aModel : Graphic3d_TOSM_UNLIT;
420     }
421     return Graphic3d_TOSM_UNLIT;
422   }
423
424   //! Choose Shading Model for Marker primitives.
425   Graphic3d_TypeOfShadingModel ChooseMarkerShadingModel (Graphic3d_TypeOfShadingModel theCustomModel,
426                                                          bool theHasNodalNormals) const
427   {
428     return ChooseLineShadingModel (theCustomModel, theHasNodalNormals);
429   }
430
431   //! Returns default Shading Model.
432   Graphic3d_TypeOfShadingModel ShadingModel() const { return myShadingModel; }
433
434   //! Sets shading model.
435   Standard_EXPORT void SetShadingModel (const Graphic3d_TypeOfShadingModel theModel);
436
437   //! Sets last view manger used with.
438   //! Helps to handle matrix states in multi-view configurations.
439   void SetLastView (const OpenGl_View* theLastView)
440   {
441     myLastView = theLastView;
442   }
443
444   //! Returns true when provided view is the same as cached one.
445   bool IsSameView (const OpenGl_View* theView) const
446   {
447     return myLastView == theView;
448   }
449
450 protected:
451
452   //! Define clipping planes program bits.
453   Standard_Integer getClipPlaneBits() const
454   {
455     const Standard_Integer aNbPlanes = myContext->Clipping().NbClippingOrCappingOn();
456     if (aNbPlanes <= 0)
457     {
458       return 0;
459     }
460
461     Standard_Integer aBits = 0;
462     if (myContext->Clipping().HasClippingChains())
463     {
464       aBits |= OpenGl_PO_ClipChains;
465     }
466
467     if (aNbPlanes == 1)
468     {
469       aBits |= OpenGl_PO_ClipPlanes1;
470     }
471     else if (aNbPlanes == 2)
472     {
473       aBits |= OpenGl_PO_ClipPlanes2;
474     }
475     else
476     {
477       aBits |= OpenGl_PO_ClipPlanesN;
478     }
479     return aBits;
480   }
481
482   //! Define program bits.
483   Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures,
484                                    Graphic3d_AlphaMode theAlphaMode,
485                                    Aspect_InteriorStyle theInteriorStyle,
486                                    Standard_Boolean theHasVertColor,
487                                    Standard_Boolean theEnableEnvMap,
488                                    Standard_Boolean theEnableMeshEdges) const
489   {
490     Standard_Integer aBits = 0;
491     if (theAlphaMode == Graphic3d_AlphaMode_Mask)
492     {
493       aBits |= OpenGl_PO_AlphaTest;
494     }
495
496     aBits |= getClipPlaneBits();
497     if (theEnableMeshEdges
498      && myContext->hasGeometryStage != OpenGl_FeatureNotAvailable)
499     {
500       aBits |= OpenGl_PO_MeshEdges;
501       if (theInteriorStyle == Aspect_IS_HOLLOW)
502       {
503         aBits |= OpenGl_PO_AlphaTest;
504       }
505     }
506
507     if (theEnableEnvMap)
508     {
509       // Environment map overwrites material texture
510       aBits |= OpenGl_PO_TextureEnv;
511     }
512     else if (!theTextures.IsNull()
513           && !theTextures->IsEmpty()
514           && !theTextures->First().IsNull())
515     {
516       aBits |= theTextures->First()->IsAlpha() ? OpenGl_PO_TextureA : OpenGl_PO_TextureRGB;
517     }
518     if (theHasVertColor
519      && theInteriorStyle != Aspect_IS_HIDDENLINE)
520     {
521       aBits |= OpenGl_PO_VertColor;
522     }
523
524     if (myOitState.ToEnableWrite())
525     {
526       aBits |= OpenGl_PO_WriteOit;
527     }
528     return aBits;
529   }
530
531   //! Prepare standard GLSL program.
532   Handle(OpenGl_ShaderProgram)& getStdProgram (Graphic3d_TypeOfShadingModel theShadingModel,
533                                                Standard_Integer theBits)
534   {
535     if (theShadingModel == Graphic3d_TOSM_UNLIT
536      || (theBits & OpenGl_PO_TextureEnv) != 0)
537     {
538       // If environment map is enabled lighting calculations are
539       // not needed (in accordance with default OCCT behavior)
540       Handle(OpenGl_ShaderProgram)& aProgram = myUnlitPrograms->ChangeValue (theBits);
541       if (aProgram.IsNull())
542       {
543         prepareStdProgramUnlit (aProgram, theBits, false);
544       }
545       return aProgram;
546     }
547
548     Handle(OpenGl_ShaderProgram)& aProgram = myLightPrograms->ChangeValue (theShadingModel, theBits);
549     if (aProgram.IsNull())
550     {
551       prepareStdProgramLight (aProgram, theShadingModel, theBits);
552     }
553     return aProgram;
554   }
555
556   //! Prepare standard GLSL program for accessing point sprite alpha.
557   Standard_EXPORT TCollection_AsciiString pointSpriteAlphaSrc (const Standard_Integer theBits);
558
559   //! Prepare standard GLSL program for computing point sprite shading.
560   Standard_EXPORT TCollection_AsciiString pointSpriteShadingSrc (const TCollection_AsciiString theBaseColorSrc, const Standard_Integer theBits);
561
562   //! Prepare standard GLSL program for textured font.
563   Standard_EXPORT Standard_Boolean prepareStdProgramFont();
564
565   //! Prepare standard GLSL program for FBO blit operation.
566   Standard_EXPORT Standard_Boolean prepareStdProgramFboBlit();
567
568   //! Prepare standard GLSL programs for OIT compositing operation.
569   Standard_EXPORT Standard_Boolean prepareStdProgramOitCompositing (const Standard_Boolean theMsaa);
570
571   //! Prepare standard GLSL program without lighting.
572   Standard_EXPORT Standard_Boolean prepareStdProgramUnlit (Handle(OpenGl_ShaderProgram)& theProgram,
573                                                            Standard_Integer theBits,
574                                                            Standard_Boolean theIsOutline = false);
575
576   //! Prepare standard GLSL program with lighting.
577   Standard_Boolean prepareStdProgramLight (Handle(OpenGl_ShaderProgram)& theProgram,
578                                            Graphic3d_TypeOfShadingModel theShadingModel,
579                                            Standard_Integer theBits)
580   {
581     switch (theShadingModel)
582     {
583       case Graphic3d_TOSM_UNLIT:    return prepareStdProgramUnlit  (theProgram, theBits, false);
584       case Graphic3d_TOSM_FACET:    return prepareStdProgramPhong  (theProgram, theBits, true);
585       case Graphic3d_TOSM_VERTEX:   return prepareStdProgramGouraud(theProgram, theBits);
586       case Graphic3d_TOSM_DEFAULT:
587       case Graphic3d_TOSM_FRAGMENT: return prepareStdProgramPhong  (theProgram, theBits, false);
588     }
589     return false;
590   }
591
592   //! Prepare standard GLSL program with per-vertex lighting.
593   Standard_EXPORT Standard_Boolean prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
594                                                              const Standard_Integer        theBits);
595
596   //! Prepare standard GLSL program with per-pixel lighting.
597   //! @param theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will be computed instead
598   Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
599                                                            const Standard_Integer        theBits,
600                                                            const Standard_Boolean        theIsFlatNormal = false);
601
602   //! Define computeLighting GLSL function depending on current lights configuration
603   //! @param theNbLights     [out] number of defined light sources
604   //! @param theHasVertColor [in]  flag to use getVertColor() instead of Ambient and Diffuse components of active material
605   Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights,
606                                                               Standard_Boolean  theHasVertColor);
607
608   //! Bind specified program to current context and apply state.
609   Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram);
610
611   //! Set pointer myLightPrograms to active lighting programs set from myMapOfLightPrograms
612   Standard_EXPORT void switchLightPrograms();
613
614   //! Prepare standard GLSL program for stereoscopic image.
615   Standard_EXPORT Standard_Boolean prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram,
616                                                             const Graphic3d_StereoMode    theStereoMode);
617
618   //! Prepare standard GLSL program for bounding box.
619   Standard_EXPORT Standard_Boolean prepareStdProgramBoundBox();
620
621   //! Prepare GLSL version header.
622   Standard_EXPORT Standard_Integer defaultGlslVersion (const Handle(Graphic3d_ShaderProgram)& theProgram,
623                                                        const TCollection_AsciiString& theName,
624                                                        Standard_Integer theBits,
625                                                        bool theUsesDerivates = false) const;
626
627   //! Prepare GLSL source for geometry shader according to parameters.
628   Standard_EXPORT TCollection_AsciiString prepareGeomMainSrc (OpenGl_ShaderObject::ShaderVariableList& theUnifoms,
629                                                               OpenGl_ShaderObject::ShaderVariableList& theStageInOuts,
630                                                               Standard_Integer theBits);
631
632 protected:
633
634   //! Packed properties of light source
635   struct OpenGl_ShaderLightParameters
636   {
637     OpenGl_Vec4 Color;
638     OpenGl_Vec4 Position;
639     OpenGl_Vec4 Direction;
640     OpenGl_Vec4 Parameters;
641
642     //! Returns packed (serialized) representation of light source properties
643     const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
644     static Standard_Integer NbOfVec4() { return 4; }
645   };
646
647   //! Packed light source type information
648   struct OpenGl_ShaderLightType
649   {
650     Standard_Integer Type;
651     Standard_Integer IsHeadlight;
652
653     //! Returns packed (serialized) representation of light source type
654     const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
655     static Standard_Integer NbOfVec2i() { return 1; }
656   };
657
658   //! Fake OpenGL program for tracking FFP state in the way consistent to programmable pipeline.
659   class OpenGl_ShaderProgramFFP : public OpenGl_ShaderProgram
660   {
661     DEFINE_STANDARD_RTTI_INLINE(OpenGl_ShaderProgramFFP, OpenGl_ShaderProgram)
662     friend class OpenGl_ShaderManager;
663   protected:
664     OpenGl_ShaderProgramFFP() {}
665   };
666
667 protected:
668
669   //! Append clipping plane definition to temporary buffers.
670   void addClippingPlane (Standard_Integer& thePlaneId,
671                          const Graphic3d_ClipPlane& thePlane,
672                          const Graphic3d_Vec4d& theEq,
673                          const Standard_Integer theChainFwd) const
674   {
675     myClipChainArray.SetValue (thePlaneId, theChainFwd);
676     OpenGl_Vec4& aPlaneEq = myClipPlaneArray.ChangeValue (thePlaneId);
677     aPlaneEq.x() = float(theEq.x());
678     aPlaneEq.y() = float(theEq.y());
679     aPlaneEq.z() = float(theEq.z());
680     aPlaneEq.w() = float(theEq.w());
681     if (myHasLocalOrigin)
682     {
683       const gp_XYZ        aPos = thePlane.ToPlane().Position().Location().XYZ() - myLocalOrigin;
684       const Standard_Real aD   = -(theEq.x() * aPos.X() + theEq.y() * aPos.Y() + theEq.z() * aPos.Z());
685       aPlaneEq.w() = float(aD);
686     }
687     ++thePlaneId;
688   }
689
690 protected:
691
692   Handle(OpenGl_ShaderProgramFFP)    myFfpProgram;
693
694   Graphic3d_TypeOfShadingModel       myShadingModel;       //!< lighting shading model
695   OpenGl_ShaderProgramList           myProgramList;        //!< The list of shader programs
696   Handle(OpenGl_SetOfShaderPrograms) myLightPrograms;      //!< pointer to active lighting programs matrix
697   Handle(OpenGl_SetOfPrograms)       myUnlitPrograms;      //!< programs matrix without lighting
698   Handle(OpenGl_SetOfPrograms)       myOutlinePrograms;    //!< programs matrix without lighting for outline presentation
699   Handle(OpenGl_ShaderProgram)       myFontProgram;        //!< standard program for textured text
700   Handle(OpenGl_ShaderProgram)       myBlitProgram;        //!< standard program for FBO blit emulation
701   Handle(OpenGl_ShaderProgram)       myBoundBoxProgram;    //!< standard program for bounding box
702   Handle(OpenGl_ShaderProgram)       myOitCompositingProgram[2]; //!< standard program for OIT compositing (default and MSAA).
703   OpenGl_MapOfShaderPrograms         myMapOfLightPrograms; //!< map of lighting programs depending on lights configuration
704
705   Handle(OpenGl_ShaderProgram)       myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs
706
707   Handle(OpenGl_VertexBuffer)        myBoundBoxVertBuffer; //!< bounding box vertex buffer
708
709   OpenGl_Context*                    myContext;            //!< OpenGL context
710
711 protected:
712
713   OpenGl_ProjectionState             myProjectionState;    //!< State of OCCT projection  transformation
714   OpenGl_ModelWorldState             myModelWorldState;    //!< State of OCCT model-world transformation
715   OpenGl_WorldViewState              myWorldViewState;     //!< State of OCCT world-view  transformation
716   OpenGl_ClippingState               myClippingState;      //!< State of OCCT clipping planes
717   OpenGl_LightSourceState            myLightSourceState;   //!< State of OCCT light sources
718   OpenGl_MaterialState               myMaterialState;      //!< State of Front and Back materials
719   OpenGl_OitState                    myOitState;           //!< State of OIT uniforms
720
721   gp_XYZ                             myLocalOrigin;        //!< local camera transformation
722   Standard_Boolean                   myHasLocalOrigin;     //!< flag indicating that local camera transformation has been set
723
724   mutable NCollection_Array1<OpenGl_ShaderLightType>       myLightTypeArray;
725   mutable NCollection_Array1<OpenGl_ShaderLightParameters> myLightParamsArray;
726   mutable NCollection_Array1<OpenGl_Vec4>                  myClipPlaneArray;
727   mutable NCollection_Array1<OpenGl_Vec4d>                 myClipPlaneArrayFfp;
728   mutable NCollection_Array1<Standard_Integer>             myClipChainArray;
729
730 private:
731
732   const OpenGl_View*                 myLastView;           //!< Pointer to the last view shader manager used with
733
734 };
735
736 DEFINE_STANDARD_HANDLE(OpenGl_ShaderManager, Standard_Transient)
737
738 #endif // _OpenGl_ShaderManager_HeaderFile