40dc81fb213f499326b960c76c155fe0dbb5e68e
[occt.git] / src / OpenGl / OpenGl_LayerList.cxx
1 // Created on: 2012-02-02
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2012-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 #include <OpenGl_GlCore15.hxx>
17
18 #include <OpenGl_FrameBuffer.hxx>
19 #include <OpenGl_LayerList.hxx>
20 #include <OpenGl_ShaderManager.hxx>
21 #include <OpenGl_Structure.hxx>
22 #include <OpenGl_VertexBuffer.hxx>
23 #include <OpenGl_View.hxx>
24 #include <OpenGl_Workspace.hxx>
25
26 #include <Graphic3d_GraphicDriver.hxx>
27
28 //=======================================================================
29 //function : OpenGl_LayerList
30 //purpose  : Constructor
31 //=======================================================================
32
33 OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
34 : myDefaultLayerIndex (0),
35   myNbPriorities (theNbPriorities),
36   myNbStructures (0),
37   myImmediateNbStructures (0),
38   myModifStateOfRaytraceable (0),
39   myRenderOpaqueFilter (new OpenGl_OpaqueFilter()),
40   myRenderTranspFilter (new OpenGl_TransparentFilter())
41 {
42   // insert default priority layers
43   myLayers.Append (OpenGl_Layer (myNbPriorities));
44   myLayerIds.Bind (Graphic3d_ZLayerId_BotOSD,  myLayers.Upper());
45
46   myLayers.Append (OpenGl_Layer (myNbPriorities));
47   myLayerIds.Bind (Graphic3d_ZLayerId_Default, myLayers.Upper());
48
49   myLayers.Append (OpenGl_Layer (myNbPriorities));
50   myLayerIds.Bind (Graphic3d_ZLayerId_Top,     myLayers.Upper());
51
52   myLayers.Append (OpenGl_Layer (myNbPriorities));
53   myLayerIds.Bind (Graphic3d_ZLayerId_Topmost, myLayers.Upper());
54
55   myLayers.Append (OpenGl_Layer (myNbPriorities));
56   myLayerIds.Bind (Graphic3d_ZLayerId_TopOSD,  myLayers.Upper());
57
58   myDefaultLayerIndex = myLayerIds.Find (Graphic3d_ZLayerId_Default);
59
60   myTransparentToProcess.Allocate (myLayers.Length());
61 }
62
63 //=======================================================================
64 //function : ~OpenGl_LayerList
65 //purpose  : Destructor
66 //=======================================================================
67
68 OpenGl_LayerList::~OpenGl_LayerList()
69 {
70 }
71
72 //=======================================================================
73 //function : AddLayer
74 //purpose  : 
75 //=======================================================================
76
77 void OpenGl_LayerList::AddLayer (const Graphic3d_ZLayerId theLayerId)
78 {
79   if (myLayerIds.IsBound (theLayerId))
80   {
81     return;
82   }
83
84   // add the new layer
85   myLayers.Append (OpenGl_Layer (myNbPriorities));
86   myLayerIds.Bind (theLayerId, myLayers.Length());
87
88   myTransparentToProcess.Allocate (myLayers.Length());
89 }
90
91 //=======================================================================
92 //function : Layer
93 //purpose  : 
94 //=======================================================================
95 OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId)
96 {
97   return myLayers.ChangeValue (myLayerIds.Find (theLayerId));
98 }
99
100 //=======================================================================
101 //function : Layer
102 //purpose  : 
103 //=======================================================================
104 const OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId) const
105 {
106   return myLayers.Value (myLayerIds.Find (theLayerId));
107 }
108
109 //=======================================================================
110 //function : RemoveLayer
111 //purpose  :
112 //=======================================================================
113
114 void OpenGl_LayerList::RemoveLayer (const Graphic3d_ZLayerId theLayerId)
115 {
116   if (!myLayerIds.IsBound (theLayerId)
117     || theLayerId <= 0)
118   {
119     return;
120   }
121
122   const Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
123   
124   // move all displayed structures to first layer
125   const OpenGl_Layer& aLayerToMove = myLayers.Value (aRemovePos);
126   myLayers.ChangeFirst().Append (aLayerToMove);
127
128   // remove layer
129   myLayers.Remove (aRemovePos);
130   myLayerIds.UnBind (theLayerId);
131
132   // updated sequence indexes in map
133   for (OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds); aMapIt.More(); aMapIt.Next())
134   {
135     Standard_Integer& aSeqIdx = aMapIt.ChangeValue();
136     if (aSeqIdx > aRemovePos)
137       aSeqIdx--;
138   }
139
140   myDefaultLayerIndex = myLayerIds.Find (Graphic3d_ZLayerId_Default);
141
142   myTransparentToProcess.Allocate (myLayers.Length());
143 }
144
145 //=======================================================================
146 //function : AddStructure
147 //purpose  :
148 //=======================================================================
149
150 void OpenGl_LayerList::AddStructure (const OpenGl_Structure*  theStruct,
151                                      const Graphic3d_ZLayerId theLayerId,
152                                      const Standard_Integer   thePriority,
153                                      Standard_Boolean         isForChangePriority)
154 {
155   // add structure to associated layer,
156   // if layer doesn't exists, display structure in default layer
157   Standard_Integer aSeqPos = myLayers.Lower();
158   myLayerIds.Find (theLayerId, aSeqPos);
159
160   OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
161   aLayer.Add (theStruct, thePriority, isForChangePriority);
162   ++myNbStructures;
163   if (aLayer.IsImmediate())
164   {
165     ++myImmediateNbStructures;
166   }
167
168   // Note: In ray-tracing mode we don't modify modification
169   // state here. It is redundant, because the possible changes
170   // will be handled in the loop for structures
171 }
172
173 //=======================================================================
174 //function : RemoveStructure
175 //purpose  :
176 //=======================================================================
177
178 void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure)
179 {
180   const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
181
182   Standard_Integer aSeqPos = myLayers.Lower();
183   myLayerIds.Find (aLayerId, aSeqPos);
184
185   OpenGl_Layer&    aLayer    = myLayers.ChangeValue (aSeqPos);
186   Standard_Integer aPriority = -1;
187
188   // remove structure from associated list
189   // if the structure is not found there,
190   // scan through layers and remove it
191   if (aLayer.Remove (theStructure, aPriority))
192   {
193     --myNbStructures;
194     if (aLayer.IsImmediate())
195     {
196       --myImmediateNbStructures;
197     }
198
199     if (aLayerId == Graphic3d_ZLayerId_Default
200      && theStructure->IsRaytracable())
201     {
202       ++myModifStateOfRaytraceable;
203     }
204
205     return;
206   }
207
208   // scan through layers and remove it
209   Standard_Integer aSeqId = 1;
210   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
211   {
212     OpenGl_Layer& aLayerEx = anIts.ChangeValue();
213     if (aSeqPos == aSeqId)
214     {
215       continue;
216     }
217
218     if (aLayerEx.Remove (theStructure, aPriority))
219     {
220       --myNbStructures;
221       if (aLayerEx.IsImmediate())
222       {
223         --myImmediateNbStructures;
224       }
225
226       if (aSeqId == myDefaultLayerIndex
227        && theStructure->IsRaytracable())
228       {
229         ++myModifStateOfRaytraceable;
230       }
231       return;
232     }
233   }
234 }
235
236 //=======================================================================
237 //function : InvalidateBVHData
238 //purpose  :
239 //=======================================================================
240 void OpenGl_LayerList::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
241 {
242   Standard_Integer aSeqPos = myLayers.Lower();
243   myLayerIds.Find (theLayerId, aSeqPos);
244   OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
245   aLayer.InvalidateBVHData();
246 }
247
248 //=======================================================================
249 //function : ChangeLayer
250 //purpose  :
251 //=======================================================================
252
253 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure*  theStructure,
254                                     const Graphic3d_ZLayerId theOldLayerId,
255                                     const Graphic3d_ZLayerId theNewLayerId)
256 {
257   Standard_Integer aSeqPos = myLayers.Lower();
258   myLayerIds.Find (theOldLayerId, aSeqPos);
259   OpenGl_Layer&    aLayer    = myLayers.ChangeValue (aSeqPos);
260   Standard_Integer aPriority = -1;
261
262   // take priority and remove structure from list found by <theOldLayerId>
263   // if the structure is not found there, scan through all other layers
264   if (aLayer.Remove (theStructure, aPriority, Standard_False))
265   {
266     if (theOldLayerId == Graphic3d_ZLayerId_Default
267      && theStructure->IsRaytracable())
268     {
269       ++myModifStateOfRaytraceable;
270     }
271
272     --myNbStructures;
273     if (aLayer.IsImmediate())
274     {
275       --myImmediateNbStructures;
276     }
277
278     // isForChangePriority should be Standard_False below, because we want
279     // the BVH tree in the target layer to be updated with theStructure
280     AddStructure (theStructure, theNewLayerId, aPriority);
281     return;
282   }
283
284   // scan through layers and remove it
285   Standard_Integer aSeqId = 1;
286   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
287   {
288     if (aSeqPos == aSeqId)
289     {
290       continue;
291     }
292   
293     // try to remove structure and get priority value from this layer
294     OpenGl_Layer& aLayerEx = anIts.ChangeValue();
295     if (aLayerEx.Remove (theStructure, aPriority, Standard_True))
296     {
297       if (aSeqId == myDefaultLayerIndex
298        && theStructure->IsRaytracable())
299       {
300         ++myModifStateOfRaytraceable;
301       }
302
303       --myNbStructures;
304       if (aLayerEx.IsImmediate())
305       {
306         --myImmediateNbStructures;
307       }
308
309       // isForChangePriority should be Standard_False below, because we want
310       // the BVH tree in the target layer to be updated with theStructure
311       AddStructure (theStructure, theNewLayerId, aPriority);
312       return;
313     }
314   }
315 }
316
317 //=======================================================================
318 //function : ChangePriority
319 //purpose  :
320 //=======================================================================
321 void OpenGl_LayerList::ChangePriority (const OpenGl_Structure*  theStructure,
322                                        const Graphic3d_ZLayerId theLayerId,
323                                        const Standard_Integer   theNewPriority)
324 {
325   Standard_Integer aSeqPos = myLayers.Lower();
326   myLayerIds.Find (theLayerId, aSeqPos);
327   OpenGl_Layer&    aLayer        = myLayers.ChangeValue (aSeqPos);
328   Standard_Integer anOldPriority = -1;
329
330   if (aLayer.Remove (theStructure, anOldPriority, Standard_True))
331   {
332     --myNbStructures;
333     if (aLayer.IsImmediate())
334     {
335       --myImmediateNbStructures;
336     }
337
338     AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
339     return;
340   }
341
342   Standard_Integer aSeqId = 1;
343   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
344   {
345     if (aSeqPos == aSeqId)
346     {
347       continue;
348     }
349
350     OpenGl_Layer& aLayerEx = anIts.ChangeValue();
351     if (aLayerEx.Remove (theStructure, anOldPriority, Standard_True))
352     {
353       --myNbStructures;
354       if (aLayerEx.IsImmediate())
355       {
356         --myImmediateNbStructures;
357       }
358
359       AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
360       return;
361     }
362   }
363 }
364
365 //=======================================================================
366 //function : SetLayerSettings
367 //purpose  :
368 //=======================================================================
369 void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId        theLayerId,
370                                          const Graphic3d_ZLayerSettings& theSettings)
371 {
372   OpenGl_Layer& aLayer = Layer (theLayerId);
373   if (aLayer.LayerSettings().IsImmediate() != theSettings.IsImmediate())
374   {
375     if (theSettings.IsImmediate())
376     {
377       myImmediateNbStructures += aLayer.NbStructures();
378     }
379     else
380     {
381       myImmediateNbStructures -= aLayer.NbStructures();
382     }
383   }
384   aLayer.SetLayerSettings (theSettings);
385 }
386
387 //=======================================================================
388 //function : Render
389 //purpose  :
390 //=======================================================================
391 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
392                                const Standard_Boolean          theToDrawImmediate,
393                                const OpenGl_LayerFilter        theLayersToProcess,
394                                OpenGl_FrameBuffer*             theReadDrawFbo,
395                                OpenGl_FrameBuffer*             theOitAccumFbo) const
396 {
397   // Remember global settings for glDepth function and write mask.
398   OpenGl_GlobalLayerSettings aDefaultSettings;
399
400   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
401   aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC,      &aDefaultSettings.DepthFunc);
402   aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aDefaultSettings.DepthMask);
403
404   // Two render filters are used to support transparency draw. Opaque filter accepts
405   // only non-transparent OpenGl elements of a layer and counts number of skipped
406   // transparent ones. If the counter has positive value the layer is added into
407   // transparency post-processing stack. At the end of drawing or once the depth
408   // buffer is to be cleared the layers in the stack should be drawn using
409   // blending and depth mask settings and another transparency filter which accepts
410   // only transparent OpenGl elements of a layer. The stack <myTransparentToProcess>
411   // was preallocated before going into this method and has enough space to keep
412   // maximum number of references to layers, therefore it will not increase memory
413   // fragmentation during regular rendering.
414   const Handle(OpenGl_RenderFilter) aPrevFilter = theWorkspace->GetRenderFilter();
415   myRenderOpaqueFilter->SetPreviousFilter (aPrevFilter);
416   myRenderTranspFilter->SetPreviousFilter (aPrevFilter);
417   theWorkspace->SetRenderFilter (myRenderOpaqueFilter);
418
419   myTransparentToProcess.Clear();
420
421   OpenGl_LayerStack::iterator aStackIter (myTransparentToProcess.Origin());
422   Standard_Integer aSeqId = myLayers.Lower();
423   bool toClearDepth = false;
424   for (OpenGl_SequenceOfLayers::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next(), ++aSeqId)
425   {
426     if (theLayersToProcess == OpenGl_LF_Bottom)
427     {
428       if (aSeqId >= myDefaultLayerIndex) continue;
429     }
430     else if (theLayersToProcess == OpenGl_LF_Upper)
431     {
432       if (aSeqId <= myDefaultLayerIndex) continue;
433     }
434     else if (theLayersToProcess == OpenGl_LF_Default)
435     {
436       if (aSeqId != myDefaultLayerIndex) continue;
437     }
438
439     const OpenGl_Layer& aLayer = aLayerIter.Value();
440     if (aLayer.IsImmediate() != theToDrawImmediate)
441     {
442       continue;
443     }
444     else if (aLayer.NbStructures() < 1)
445     {
446       // Make sure to clear depth of previous layers even if layer has no structures.
447       toClearDepth = toClearDepth || aLayer.LayerSettings().ToClearDepth();
448       continue;
449     }
450
451     // At this point the depth buffer may be set to clear by
452     // previous configuration of layers or configuration of the
453     // current layer. Additional rendering pass to handle transparent
454     // elements of recently drawn layers require use of current depth
455     // buffer so we put remaining layers for processing as one bunch before
456     // erasing the depth buffer.
457     if (toClearDepth
458      || aLayer.LayerSettings().ToClearDepth())
459     {
460       if (!myTransparentToProcess.IsEmpty())
461       {
462         renderTransparent (theWorkspace, aStackIter, aDefaultSettings, theReadDrawFbo, theOitAccumFbo);
463       }
464
465       toClearDepth = false;
466       glDepthMask (GL_TRUE);
467       glClear (GL_DEPTH_BUFFER_BIT);
468     }
469
470     // Render opaque OpenGl elements of a layer and count the number of skipped.
471     // If a layer has skipped (e.g. transparent) elements it should be added into
472     // the transparency post-processing stack.
473     myRenderOpaqueFilter->SetSkippedCounter (0);
474
475     aLayer.Render (theWorkspace, aDefaultSettings);
476
477     if (myRenderOpaqueFilter->NbSkipped() > 0)
478     {
479       myTransparentToProcess.Push (&aLayer);
480     }
481   }
482
483   // Before finishing process the remaining collected layers with transparency.
484   if (!myTransparentToProcess.IsEmpty())
485   {
486     renderTransparent (theWorkspace, aStackIter, aDefaultSettings, theReadDrawFbo, theOitAccumFbo);
487   }
488
489   if (toClearDepth)
490   {
491     glDepthMask (GL_TRUE);
492     glClear (GL_DEPTH_BUFFER_BIT);
493   }
494
495   aCtx->core11fwd->glDepthMask (aDefaultSettings.DepthMask);
496   aCtx->core11fwd->glDepthFunc (aDefaultSettings.DepthFunc);
497
498   theWorkspace->SetRenderFilter (aPrevFilter);
499 }
500
501 //=======================================================================
502 //function : renderTransparent
503 //purpose  : Render transparent objects using blending operator.
504 //=======================================================================
505 void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)&   theWorkspace,
506                                           OpenGl_LayerStack::iterator&      theLayerIter,
507                                           const OpenGl_GlobalLayerSettings& theGlobalSettings,
508                                           OpenGl_FrameBuffer*               theReadDrawFbo,
509                                           OpenGl_FrameBuffer*               theOitAccumFbo) const
510 {
511   // Blended order-independent transparency algorithm require several preconditions
512   // to be enabled. It should be requested by user, at least two outputs from
513   // fragment shader should be supported by GPU, so is the given framebuffer
514   // should contain two additional color buffers to handle accumulated color channels,
515   // blended alpha channel and weight factors - these accumulation buffers are required
516   // to implement commuting blend operator (at least OpenGl 2.0 should be available).
517   const bool isEnabledOit = theOitAccumFbo != NULL
518                          && theOitAccumFbo->NbColorBuffers() >= 2
519                          && theOitAccumFbo->ColorTexture (0)->IsValid()
520                          && theOitAccumFbo->ColorTexture (1)->IsValid();
521
522   // Check if current iterator has already reached the end of the stack.
523   // This should happen if no additional layers has been added to
524   // the processing stack after last transparency pass.
525   if (theLayerIter == myTransparentToProcess.Back())
526   {
527     return;
528   }
529
530   const Handle(OpenGl_Context) aCtx            = theWorkspace->GetGlContext();
531   const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
532   OpenGl_View* aView = theWorkspace->View();
533   const float aDepthFactor =  aView != NULL ? aView->RenderingParams().OitDepthFactor : 0.0f;
534
535   theWorkspace->SetRenderFilter (myRenderTranspFilter);
536
537   aCtx->core11fwd->glEnable (GL_BLEND);
538
539   if (isEnabledOit)
540   {
541     aManager->SetOitState (true, aDepthFactor);
542
543     theOitAccumFbo->BindBuffer (aCtx);
544
545     static const Standard_Integer aDrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0 + 1 };
546     aCtx->SetDrawBuffers (2, aDrawBuffers);
547     aCtx->core11fwd->glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
548     aCtx->core11fwd->glClear (GL_COLOR_BUFFER_BIT);
549     aCtx->core15fwd->glBlendFuncSeparate (GL_ONE, GL_ONE, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
550   }
551   else
552   {
553     aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
554   }
555
556   // During blended order-independent transparency pass the depth test
557   // should be enabled to discard fragments covered by opaque geometry
558   // and depth writing should be disabled, because transparent fragments
559   // overal each other with non unitary coverage factor.
560   OpenGl_GlobalLayerSettings aGlobalSettings = theGlobalSettings;
561   aGlobalSettings.DepthMask   = GL_FALSE;
562   aCtx->core11fwd->glDepthMask (GL_FALSE);
563
564   for (; theLayerIter != myTransparentToProcess.Back(); ++theLayerIter)
565   {
566     (*theLayerIter)->Render (theWorkspace, aGlobalSettings);
567   }
568
569   // Revert state of rendering.
570   if (isEnabledOit)
571   {
572     aManager->SetOitState (false, aDepthFactor);
573     theOitAccumFbo->UnbindBuffer (aCtx);
574     if (theReadDrawFbo)
575     {
576       theReadDrawFbo->BindBuffer (aCtx);
577     }
578
579     static const Standard_Integer aDrawBuffers[] = { GL_COLOR_ATTACHMENT0 };
580     aCtx->SetDrawBuffers (1, aDrawBuffers);
581   }
582
583   theWorkspace->SetRenderFilter (myRenderOpaqueFilter);
584   if (isEnabledOit)
585   {
586     const Standard_Boolean isMSAA = theReadDrawFbo && theReadDrawFbo->NbSamples() > 0;
587     OpenGl_VertexBuffer*   aVerts = theWorkspace->View()->initBlitQuad (Standard_False);
588     if (aVerts->IsValid() && aManager->BindOitCompositingProgram (isMSAA))
589     {
590       aCtx->core11fwd->glDepthFunc (GL_ALWAYS);
591       aCtx->core11fwd->glDepthMask (GL_FALSE);
592
593       // Bind full screen quad buffer and framebuffer resources.
594       aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS);
595
596       const Handle(OpenGl_Texture) aTextureBack = theWorkspace->DisableTexture();
597
598       theOitAccumFbo->ColorTexture (0)->Bind (aCtx, GL_TEXTURE0 + 0);
599       theOitAccumFbo->ColorTexture (1)->Bind (aCtx, GL_TEXTURE0 + 1);
600
601       // Draw full screen quad with special shader to compose the buffers.
602       aCtx->core11fwd->glBlendFunc (GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
603       aCtx->core11fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
604
605       // Unbind OpenGL texture objects and shader program.
606       aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS);
607       theOitAccumFbo->ColorTexture (0)->Unbind (aCtx, GL_TEXTURE0 + 0);
608       theOitAccumFbo->ColorTexture (1)->Unbind (aCtx, GL_TEXTURE0 + 1);
609       aCtx->BindProgram (NULL);
610
611       if (!aTextureBack.IsNull())
612       {
613         theWorkspace->EnableTexture (aTextureBack);
614       }
615     }
616     else
617     {
618       aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
619                          "Initialization of OIT compositing pass has failed.\n"
620                          "  Blended order-independent transparency will not be available.\n");
621       if (aView != NULL)
622       {
623         Standard_Boolean& aOITFlag = isMSAA ? aView->myToDisableOITMSAA : aView->myToDisableOIT;
624         aOITFlag = Standard_True;
625       }
626     }
627   }
628
629   aCtx->core11fwd->glDisable (GL_BLEND);
630   aCtx->core11fwd->glBlendFunc (GL_ONE, GL_ZERO);
631   aCtx->core11fwd->glDepthMask (theGlobalSettings.DepthMask);
632   aCtx->core11fwd->glDepthFunc (theGlobalSettings.DepthFunc);
633 }
634
635 //=======================================================================
636 //class    : OpenGl_OpaqueFilter
637 //function : ShouldRender
638 //purpose  : Checks whether the element should be rendered or skipped.
639 //=======================================================================
640 Standard_Boolean OpenGl_LayerList::OpenGl_OpaqueFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
641                                                                       const OpenGl_Element*           theGlElement)
642 {
643   if (!myFilter.IsNull()
644    && !myFilter->ShouldRender (theWorkspace, theGlElement))
645   {
646     return Standard_False;
647   }
648
649   const OpenGl_PrimitiveArray* aPArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theGlElement);
650   if (aPArray == NULL
651    || aPArray->DrawMode() < OpenGl_PrimitiveArray::THE_FILLPRIM_FROM
652    || aPArray->DrawMode() > OpenGl_PrimitiveArray::THE_FILLPRIM_TO)
653   {
654     return Standard_True;
655   }
656
657   if (OpenGl_Context::CheckIsTransparent (theWorkspace->AspectFace(),
658                                           theWorkspace->HighlightStyle()))
659   {
660     ++mySkippedCounter;
661     return Standard_False;
662   }
663
664   return Standard_True;
665 }
666
667 //=======================================================================
668 //class    : OpenGl_TransparentFilter
669 //function : ShouldRender
670 //purpose  : Checks whether the element should be rendered or skipped.
671 //=======================================================================
672 Standard_Boolean OpenGl_LayerList::OpenGl_TransparentFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
673                                                                            const OpenGl_Element*           theGlElement)
674 {
675   if (!myFilter.IsNull()
676    && !myFilter->ShouldRender (theWorkspace, theGlElement))
677   {
678     return Standard_False;
679   }
680
681   const OpenGl_PrimitiveArray* aPArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theGlElement);
682   if (aPArray == NULL
683    || aPArray->DrawMode() < OpenGl_PrimitiveArray::THE_FILLPRIM_FROM
684    || aPArray->DrawMode() > OpenGl_PrimitiveArray::THE_FILLPRIM_TO)
685   {
686     return dynamic_cast<const OpenGl_AspectFace*> (theGlElement) != NULL;
687   }
688
689   return OpenGl_Context::CheckIsTransparent (theWorkspace->AspectFace(),
690                                              theWorkspace->HighlightStyle());
691 }