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