1 // Created on: 2012-02-02
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_GlCore15.hxx>
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>
27 #include <Graphic3d_GraphicDriver.hxx>
31 //! Auxiliary class extending sequence iterator with index.
32 class OpenGl_IndexedLayerIterator : public OpenGl_SequenceOfLayers::Iterator
36 OpenGl_IndexedLayerIterator (const OpenGl_SequenceOfLayers& theSeq)
37 : OpenGl_SequenceOfLayers::Iterator (theSeq),
38 myIndex (theSeq.Lower()) {}
40 //! Return index of current position.
41 Standard_Integer Index() const { return myIndex; }
43 //! Move to the next position.
46 OpenGl_SequenceOfLayers::Iterator::Next();
51 Standard_Integer myIndex;
54 //! Iterator through layers with filter.
55 class OpenGl_FilteredIndexedLayerIterator
59 OpenGl_FilteredIndexedLayerIterator (const OpenGl_SequenceOfLayers& theSeq,
60 Standard_Integer theDefaultLayerIndex,
61 Standard_Boolean theToDrawImmediate,
62 OpenGl_LayerFilter theLayersToProcess)
64 myDefaultLayerIndex (theDefaultLayerIndex),
65 myLayersToProcess (theLayersToProcess),
66 myToDrawImmediate (theToDrawImmediate)
71 //! Return true if iterator points to the valid value.
72 bool More() const { return myIter.More(); }
74 //! Return layer at current position.
75 const OpenGl_Layer& Value() const { return *myIter.Value(); }
77 //! Return index of current position.
78 Standard_Integer Index() const { return myIter.Index(); }
80 //! Go to the next item.
88 //! Look for the nearest item passing filters.
91 for (; myIter.More(); myIter.Next())
93 if (myIter.Value()->IsImmediate() != myToDrawImmediate)
98 switch (myLayersToProcess)
104 case OpenGl_LF_Upper:
106 if (myIter.Index() <= myDefaultLayerIndex)
112 case OpenGl_LF_Bottom:
114 if (myIter.Index() >= myDefaultLayerIndex)
120 case OpenGl_LF_Default:
122 if (myIter.Index() != myDefaultLayerIndex)
133 OpenGl_IndexedLayerIterator myIter;
134 Standard_Integer myDefaultLayerIndex;
135 OpenGl_LayerFilter myLayersToProcess;
136 Standard_Boolean myToDrawImmediate;
140 //=======================================================================
141 //function : OpenGl_LayerList
142 //purpose : Constructor
143 //=======================================================================
145 OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
146 : myBVHBuilder (new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth)),
147 myDefaultLayerIndex (0),
148 myNbPriorities (theNbPriorities),
150 myImmediateNbStructures (0),
151 myModifStateOfRaytraceable (0),
152 myRenderOpaqueFilter (new OpenGl_OpaqueFilter()),
153 myRenderTranspFilter (new OpenGl_TransparentFilter())
155 // insert default priority layers
156 myLayers.Append (new OpenGl_Layer (myNbPriorities, myBVHBuilder));
157 myLayerIds.Bind (Graphic3d_ZLayerId_BotOSD, myLayers.Upper());
159 myLayers.Append (new OpenGl_Layer (myNbPriorities, myBVHBuilder));
160 myLayerIds.Bind (Graphic3d_ZLayerId_Default, myLayers.Upper());
162 myLayers.Append (new OpenGl_Layer (myNbPriorities, myBVHBuilder));
163 myLayerIds.Bind (Graphic3d_ZLayerId_Top, myLayers.Upper());
165 myLayers.Append (new OpenGl_Layer (myNbPriorities, myBVHBuilder));
166 myLayerIds.Bind (Graphic3d_ZLayerId_Topmost, myLayers.Upper());
168 myLayers.Append (new OpenGl_Layer (myNbPriorities, myBVHBuilder));
169 myLayerIds.Bind (Graphic3d_ZLayerId_TopOSD, myLayers.Upper());
171 myDefaultLayerIndex = myLayerIds.Find (Graphic3d_ZLayerId_Default);
173 myTransparentToProcess.Allocate (myLayers.Length());
176 //=======================================================================
177 //function : ~OpenGl_LayerList
178 //purpose : Destructor
179 //=======================================================================
181 OpenGl_LayerList::~OpenGl_LayerList()
185 //=======================================================================
186 //function : SetFrustumCullingBVHBuilder
188 //=======================================================================
189 void OpenGl_LayerList::SetFrustumCullingBVHBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder)
191 myBVHBuilder = theBuilder;
192 for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next())
194 anIts.ChangeValue()->SetFrustumCullingBVHBuilder (theBuilder);
198 //=======================================================================
199 //function : AddLayer
201 //=======================================================================
203 void OpenGl_LayerList::AddLayer (const Graphic3d_ZLayerId theLayerId)
205 if (myLayerIds.IsBound (theLayerId))
211 myLayers.Append (new OpenGl_Layer (myNbPriorities, myBVHBuilder));
212 myLayerIds.Bind (theLayerId, myLayers.Length());
214 myTransparentToProcess.Allocate (myLayers.Length());
217 //=======================================================================
220 //=======================================================================
221 OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId)
223 return *myLayers.ChangeValue (myLayerIds.Find (theLayerId));
226 //=======================================================================
229 //=======================================================================
230 const OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId) const
232 return *myLayers.Value (myLayerIds.Find (theLayerId));
235 //=======================================================================
236 //function : RemoveLayer
238 //=======================================================================
240 void OpenGl_LayerList::RemoveLayer (const Graphic3d_ZLayerId theLayerId)
242 if (!myLayerIds.IsBound (theLayerId)
248 const Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
250 // move all displayed structures to first layer
252 const OpenGl_Layer& aLayerToMove = *myLayers.Value (aRemovePos);
253 myLayers.ChangeFirst()->Append (aLayerToMove);
257 myLayers.Remove (aRemovePos);
258 myLayerIds.UnBind (theLayerId);
260 // updated sequence indexes in map
261 for (OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds); aMapIt.More(); aMapIt.Next())
263 Standard_Integer& aSeqIdx = aMapIt.ChangeValue();
264 if (aSeqIdx > aRemovePos)
268 myDefaultLayerIndex = myLayerIds.Find (Graphic3d_ZLayerId_Default);
270 myTransparentToProcess.Allocate (myLayers.Length());
273 //=======================================================================
274 //function : AddStructure
276 //=======================================================================
278 void OpenGl_LayerList::AddStructure (const OpenGl_Structure* theStruct,
279 const Graphic3d_ZLayerId theLayerId,
280 const Standard_Integer thePriority,
281 Standard_Boolean isForChangePriority)
283 // add structure to associated layer,
284 // if layer doesn't exists, display structure in default layer
285 Standard_Integer aSeqPos = myLayers.Lower();
286 myLayerIds.Find (theLayerId, aSeqPos);
288 OpenGl_Layer& aLayer = *myLayers.ChangeValue (aSeqPos);
289 aLayer.Add (theStruct, thePriority, isForChangePriority);
291 if (aLayer.IsImmediate())
293 ++myImmediateNbStructures;
296 // Note: In ray-tracing mode we don't modify modification
297 // state here. It is redundant, because the possible changes
298 // will be handled in the loop for structures
301 //=======================================================================
302 //function : RemoveStructure
304 //=======================================================================
306 void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure)
308 const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
310 Standard_Integer aSeqPos = myLayers.Lower();
311 myLayerIds.Find (aLayerId, aSeqPos);
313 OpenGl_Layer& aLayer = *myLayers.ChangeValue (aSeqPos);
314 Standard_Integer aPriority = -1;
316 // remove structure from associated list
317 // if the structure is not found there,
318 // scan through layers and remove it
319 if (aLayer.Remove (theStructure, aPriority))
322 if (aLayer.IsImmediate())
324 --myImmediateNbStructures;
327 if (aLayerId == Graphic3d_ZLayerId_Default
328 && theStructure->IsRaytracable())
330 ++myModifStateOfRaytraceable;
336 // scan through layers and remove it
337 for (OpenGl_IndexedLayerIterator anIts (myLayers); anIts.More(); anIts.Next())
339 OpenGl_Layer& aLayerEx = *anIts.ChangeValue();
340 if (aSeqPos == anIts.Index())
345 if (aLayerEx.Remove (theStructure, aPriority))
348 if (aLayerEx.IsImmediate())
350 --myImmediateNbStructures;
353 if (anIts.Index() == myDefaultLayerIndex
354 && theStructure->IsRaytracable())
356 ++myModifStateOfRaytraceable;
363 //=======================================================================
364 //function : InvalidateBVHData
366 //=======================================================================
367 void OpenGl_LayerList::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
369 Standard_Integer aSeqPos = myLayers.Lower();
370 myLayerIds.Find (theLayerId, aSeqPos);
371 OpenGl_Layer& aLayer = *myLayers.ChangeValue (aSeqPos);
372 aLayer.InvalidateBVHData();
375 //=======================================================================
376 //function : ChangeLayer
378 //=======================================================================
380 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure* theStructure,
381 const Graphic3d_ZLayerId theOldLayerId,
382 const Graphic3d_ZLayerId theNewLayerId)
384 Standard_Integer aSeqPos = myLayers.Lower();
385 myLayerIds.Find (theOldLayerId, aSeqPos);
386 OpenGl_Layer& aLayer = *myLayers.ChangeValue (aSeqPos);
387 Standard_Integer aPriority = -1;
389 // take priority and remove structure from list found by <theOldLayerId>
390 // if the structure is not found there, scan through all other layers
391 if (aLayer.Remove (theStructure, aPriority, Standard_False))
393 if (theOldLayerId == Graphic3d_ZLayerId_Default
394 && theStructure->IsRaytracable())
396 ++myModifStateOfRaytraceable;
400 if (aLayer.IsImmediate())
402 --myImmediateNbStructures;
405 // isForChangePriority should be Standard_False below, because we want
406 // the BVH tree in the target layer to be updated with theStructure
407 AddStructure (theStructure, theNewLayerId, aPriority);
411 // scan through layers and remove it
412 for (OpenGl_IndexedLayerIterator anIts (myLayers); anIts.More(); anIts.Next())
414 if (aSeqPos == anIts.Index())
419 // try to remove structure and get priority value from this layer
420 OpenGl_Layer& aLayerEx = *anIts.ChangeValue();
421 if (aLayerEx.Remove (theStructure, aPriority, Standard_True))
423 if (anIts.Index() == myDefaultLayerIndex
424 && theStructure->IsRaytracable())
426 ++myModifStateOfRaytraceable;
430 if (aLayerEx.IsImmediate())
432 --myImmediateNbStructures;
435 // isForChangePriority should be Standard_False below, because we want
436 // the BVH tree in the target layer to be updated with theStructure
437 AddStructure (theStructure, theNewLayerId, aPriority);
443 //=======================================================================
444 //function : ChangePriority
446 //=======================================================================
447 void OpenGl_LayerList::ChangePriority (const OpenGl_Structure* theStructure,
448 const Graphic3d_ZLayerId theLayerId,
449 const Standard_Integer theNewPriority)
451 Standard_Integer aSeqPos = myLayers.Lower();
452 myLayerIds.Find (theLayerId, aSeqPos);
453 OpenGl_Layer& aLayer = *myLayers.ChangeValue (aSeqPos);
454 Standard_Integer anOldPriority = -1;
456 if (aLayer.Remove (theStructure, anOldPriority, Standard_True))
459 if (aLayer.IsImmediate())
461 --myImmediateNbStructures;
464 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
468 for (OpenGl_IndexedLayerIterator anIts (myLayers); anIts.More(); anIts.Next())
470 if (aSeqPos == anIts.Index())
475 OpenGl_Layer& aLayerEx = *anIts.ChangeValue();
476 if (aLayerEx.Remove (theStructure, anOldPriority, Standard_True))
479 if (aLayerEx.IsImmediate())
481 --myImmediateNbStructures;
484 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
490 //=======================================================================
491 //function : SetLayerSettings
493 //=======================================================================
494 void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId theLayerId,
495 const Graphic3d_ZLayerSettings& theSettings)
497 OpenGl_Layer& aLayer = Layer (theLayerId);
498 if (aLayer.LayerSettings().IsImmediate() != theSettings.IsImmediate())
500 if (theSettings.IsImmediate())
502 myImmediateNbStructures += aLayer.NbStructures();
506 myImmediateNbStructures -= aLayer.NbStructures();
509 aLayer.SetLayerSettings (theSettings);
512 //=======================================================================
513 //function : UpdateCulling
515 //=======================================================================
516 void OpenGl_LayerList::UpdateCulling (const Handle(OpenGl_Workspace)& theWorkspace,
517 const Standard_Boolean theToDrawImmediate)
519 const OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector();
520 for (OpenGl_IndexedLayerIterator anIts (myLayers); anIts.More(); anIts.Next())
522 OpenGl_Layer& aLayer = *anIts.ChangeValue();
523 if (aLayer.IsImmediate() != theToDrawImmediate)
528 aLayer.UpdateCulling (aSelector, theWorkspace->IsCullingEnabled());
532 //=======================================================================
535 //=======================================================================
536 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
537 const Standard_Boolean theToDrawImmediate,
538 const OpenGl_LayerFilter theLayersToProcess,
539 OpenGl_FrameBuffer* theReadDrawFbo,
540 OpenGl_FrameBuffer* theOitAccumFbo) const
542 // Remember global settings for glDepth function and write mask.
543 OpenGl_GlobalLayerSettings aPrevSettings;
545 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
546 aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC, &aPrevSettings.DepthFunc);
547 aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aPrevSettings.DepthMask);
548 OpenGl_GlobalLayerSettings aDefaultSettings = aPrevSettings;
550 // Two render filters are used to support transparency draw. Opaque filter accepts
551 // only non-transparent OpenGl elements of a layer and counts number of skipped
552 // transparent ones. If the counter has positive value the layer is added into
553 // transparency post-processing stack. At the end of drawing or once the depth
554 // buffer is to be cleared the layers in the stack should be drawn using
555 // blending and depth mask settings and another transparency filter which accepts
556 // only transparent OpenGl elements of a layer. The stack <myTransparentToProcess>
557 // was preallocated before going into this method and has enough space to keep
558 // maximum number of references to layers, therefore it will not increase memory
559 // fragmentation during regular rendering.
560 const Handle(OpenGl_RenderFilter) aPrevFilter = theWorkspace->GetRenderFilter();
561 myRenderOpaqueFilter->SetPreviousFilter (aPrevFilter);
562 myRenderTranspFilter->SetPreviousFilter (aPrevFilter);
563 theWorkspace->SetRenderFilter (myRenderOpaqueFilter);
565 myTransparentToProcess.Clear();
567 OpenGl_LayerStack::iterator aStackIter (myTransparentToProcess.Origin());
568 Standard_Integer aClearDepthLayerPrev = -1, aClearDepthLayer = -1;
569 const bool toPerformDepthPrepass = theWorkspace->View()->RenderingParams().ToEnableDepthPrepass
570 && aPrevSettings.DepthMask == GL_TRUE;
571 for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, myDefaultLayerIndex, theToDrawImmediate, theLayersToProcess); aLayerIterStart.More();)
573 bool hasSkippedDepthLayers = false;
574 for (int aPassIter = toPerformDepthPrepass ? 0 : 2; aPassIter < 3; ++aPassIter)
578 aCtx->SetColorMask (false);
579 aDefaultSettings.DepthFunc = aPrevSettings.DepthFunc;
580 aDefaultSettings.DepthMask = GL_TRUE;
582 else if (aPassIter == 1)
584 if (!hasSkippedDepthLayers)
588 aCtx->SetColorMask (true);
589 aDefaultSettings = aPrevSettings;
591 else if (aPassIter == 2)
593 aCtx->SetColorMask (true);
594 if (toPerformDepthPrepass)
596 aDefaultSettings.DepthFunc = GL_EQUAL;
597 aDefaultSettings.DepthMask = GL_FALSE;
601 OpenGl_FilteredIndexedLayerIterator aLayerIter (aLayerIterStart);
602 for (; aLayerIter.More(); aLayerIter.Next())
604 const OpenGl_Layer& aLayer = aLayerIter.Value();
606 // make sure to clear depth of previous layers even if layer has no structures
607 if (aLayer.LayerSettings().ToClearDepth())
609 aClearDepthLayer = aLayerIter.Index();
611 if (aLayer.IsCulled())
615 else if (aClearDepthLayer > aClearDepthLayerPrev)
617 // At this point the depth buffer may be set to clear by previous configuration of layers or configuration of the current layer.
618 // Additional rendering pass to handle transparent elements of recently drawn layers require use of current depth
619 // buffer so we put remaining layers for processing as one bunch before erasing the depth buffer.
622 aLayerIterStart = aLayerIter;
626 aClearDepthLayer = -1;
630 else if (aPassIter == 0
631 && !aLayer.LayerSettings().ToRenderInDepthPrepass())
633 hasSkippedDepthLayers = true;
636 else if (aPassIter == 1
637 && aLayer.LayerSettings().ToRenderInDepthPrepass())
642 // Render opaque OpenGl elements of a layer and count the number of skipped.
643 // If a layer has skipped (e.g. transparent) elements it should be added into
644 // the transparency post-processing stack.
645 myRenderOpaqueFilter->SetSkippedCounter (0);
647 aLayer.Render (theWorkspace, aDefaultSettings);
650 && myRenderOpaqueFilter->NbSkipped() > 0)
652 myTransparentToProcess.Push (&aLayer);
656 && !aLayerIter.More())
658 aLayerIterStart = aLayerIter;
662 if (!myTransparentToProcess.IsEmpty())
664 renderTransparent (theWorkspace, aStackIter, aPrevSettings, theReadDrawFbo, theOitAccumFbo);
666 if (aClearDepthLayer > aClearDepthLayerPrev)
668 aClearDepthLayerPrev = aClearDepthLayer;
669 glDepthMask (GL_TRUE);
670 glClear (GL_DEPTH_BUFFER_BIT);
674 aCtx->core11fwd->glDepthMask (aPrevSettings.DepthMask);
675 aCtx->core11fwd->glDepthFunc (aPrevSettings.DepthFunc);
677 theWorkspace->SetRenderFilter (aPrevFilter);
680 //=======================================================================
681 //function : renderTransparent
682 //purpose : Render transparent objects using blending operator.
683 //=======================================================================
684 void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)& theWorkspace,
685 OpenGl_LayerStack::iterator& theLayerIter,
686 const OpenGl_GlobalLayerSettings& theGlobalSettings,
687 OpenGl_FrameBuffer* theReadDrawFbo,
688 OpenGl_FrameBuffer* theOitAccumFbo) const
690 // Blended order-independent transparency algorithm require several preconditions
691 // to be enabled. It should be requested by user, at least two outputs from
692 // fragment shader should be supported by GPU, so is the given framebuffer
693 // should contain two additional color buffers to handle accumulated color channels,
694 // blended alpha channel and weight factors - these accumulation buffers are required
695 // to implement commuting blend operator (at least OpenGl 2.0 should be available).
696 const bool isEnabledOit = theOitAccumFbo != NULL
697 && theOitAccumFbo->NbColorBuffers() >= 2
698 && theOitAccumFbo->ColorTexture (0)->IsValid()
699 && theOitAccumFbo->ColorTexture (1)->IsValid();
701 // Check if current iterator has already reached the end of the stack.
702 // This should happen if no additional layers has been added to
703 // the processing stack after last transparency pass.
704 if (theLayerIter == myTransparentToProcess.Back())
709 const Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
710 const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
711 OpenGl_View* aView = theWorkspace->View();
712 const float aDepthFactor = aView != NULL ? aView->RenderingParams().OitDepthFactor : 0.0f;
714 theWorkspace->SetRenderFilter (myRenderTranspFilter);
716 aCtx->core11fwd->glEnable (GL_BLEND);
720 aManager->SetOitState (true, aDepthFactor);
722 theOitAccumFbo->BindBuffer (aCtx);
724 static const Standard_Integer aDrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0 + 1 };
725 aCtx->SetDrawBuffers (2, aDrawBuffers);
726 aCtx->core11fwd->glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
727 aCtx->core11fwd->glClear (GL_COLOR_BUFFER_BIT);
728 aCtx->core15fwd->glBlendFuncSeparate (GL_ONE, GL_ONE, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
732 aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
735 // During blended order-independent transparency pass the depth test
736 // should be enabled to discard fragments covered by opaque geometry
737 // and depth writing should be disabled, because transparent fragments
738 // overal each other with non unitary coverage factor.
739 OpenGl_GlobalLayerSettings aGlobalSettings = theGlobalSettings;
740 aGlobalSettings.DepthMask = GL_FALSE;
741 aCtx->core11fwd->glDepthMask (GL_FALSE);
743 for (; theLayerIter != myTransparentToProcess.Back(); ++theLayerIter)
745 (*theLayerIter)->Render (theWorkspace, aGlobalSettings);
748 // Revert state of rendering.
751 aManager->SetOitState (false, aDepthFactor);
752 theOitAccumFbo->UnbindBuffer (aCtx);
755 theReadDrawFbo->BindBuffer (aCtx);
758 static const Standard_Integer aDrawBuffers[] = { GL_COLOR_ATTACHMENT0 };
759 aCtx->SetDrawBuffers (1, aDrawBuffers);
762 theWorkspace->SetRenderFilter (myRenderOpaqueFilter);
765 const Standard_Boolean isMSAA = theReadDrawFbo && theReadDrawFbo->NbSamples() > 0;
766 OpenGl_VertexBuffer* aVerts = theWorkspace->View()->initBlitQuad (Standard_False);
767 if (aVerts->IsValid() && aManager->BindOitCompositingProgram (isMSAA))
769 aCtx->core11fwd->glDepthFunc (GL_ALWAYS);
770 aCtx->core11fwd->glDepthMask (GL_FALSE);
772 // Bind full screen quad buffer and framebuffer resources.
773 aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS);
775 const Handle(OpenGl_TextureSet) aTextureBack = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
777 theOitAccumFbo->ColorTexture (0)->Bind (aCtx, Graphic3d_TextureUnit_0);
778 theOitAccumFbo->ColorTexture (1)->Bind (aCtx, Graphic3d_TextureUnit_1);
780 // Draw full screen quad with special shader to compose the buffers.
781 aCtx->core11fwd->glBlendFunc (GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
782 aCtx->core11fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
784 // Unbind OpenGL texture objects and shader program.
785 aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS);
786 theOitAccumFbo->ColorTexture (0)->Unbind (aCtx, Graphic3d_TextureUnit_0);
787 theOitAccumFbo->ColorTexture (1)->Unbind (aCtx, Graphic3d_TextureUnit_1);
788 aCtx->BindProgram (NULL);
790 if (!aTextureBack.IsNull())
792 aCtx->BindTextures (aTextureBack);
797 aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
798 "Initialization of OIT compositing pass has failed.\n"
799 " Blended order-independent transparency will not be available.\n");
802 Standard_Boolean& aOITFlag = isMSAA ? aView->myToDisableOITMSAA : aView->myToDisableOIT;
803 aOITFlag = Standard_True;
808 aCtx->core11fwd->glDisable (GL_BLEND);
809 aCtx->core11fwd->glBlendFunc (GL_ONE, GL_ZERO);
810 aCtx->core11fwd->glDepthMask (theGlobalSettings.DepthMask);
811 aCtx->core11fwd->glDepthFunc (theGlobalSettings.DepthFunc);
814 //=======================================================================
815 //class : OpenGl_OpaqueFilter
816 //function : ShouldRender
817 //purpose : Checks whether the element should be rendered or skipped.
818 //=======================================================================
819 Standard_Boolean OpenGl_LayerList::OpenGl_OpaqueFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
820 const OpenGl_Element* theGlElement)
822 if (!myFilter.IsNull()
823 && !myFilter->ShouldRender (theWorkspace, theGlElement))
825 return Standard_False;
828 const OpenGl_PrimitiveArray* aPArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theGlElement);
830 || !aPArray->IsFillDrawMode())
832 return Standard_True;
835 if (OpenGl_Context::CheckIsTransparent (theWorkspace->AspectFace(),
836 theWorkspace->HighlightStyle()))
839 return Standard_False;
842 return Standard_True;
845 //=======================================================================
846 //class : OpenGl_TransparentFilter
847 //function : ShouldRender
848 //purpose : Checks whether the element should be rendered or skipped.
849 //=======================================================================
850 Standard_Boolean OpenGl_LayerList::OpenGl_TransparentFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
851 const OpenGl_Element* theGlElement)
853 if (!myFilter.IsNull()
854 && !myFilter->ShouldRender (theWorkspace, theGlElement))
856 return Standard_False;
859 const OpenGl_PrimitiveArray* aPArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theGlElement);
861 || !aPArray->IsFillDrawMode())
863 return dynamic_cast<const OpenGl_AspectFace*> (theGlElement) != NULL;
866 return OpenGl_Context::CheckIsTransparent (theWorkspace->AspectFace(),
867 theWorkspace->HighlightStyle());