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