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_DepthPeeling.hxx>
20 #include <OpenGl_FrameBuffer.hxx>
21 #include <OpenGl_LayerList.hxx>
22 #include <OpenGl_ShaderManager.hxx>
23 #include <OpenGl_ShadowMap.hxx>
24 #include <OpenGl_Structure.hxx>
25 #include <OpenGl_VertexBuffer.hxx>
26 #include <OpenGl_View.hxx>
27 #include <OpenGl_Workspace.hxx>
29 #include <Graphic3d_GraphicDriver.hxx>
33 //! Auxiliary class extending sequence iterator with index.
34 class OpenGl_IndexedLayerIterator : public NCollection_List<Handle(Graphic3d_Layer)>::Iterator
38 OpenGl_IndexedLayerIterator (const NCollection_List<Handle(Graphic3d_Layer)>& theSeq)
39 : NCollection_List<Handle(Graphic3d_Layer)>::Iterator (theSeq),
42 //! Return index of current position.
43 Standard_Integer Index() const { return myIndex; }
45 //! Move to the next position.
48 NCollection_List<Handle(Graphic3d_Layer)>::Iterator::Next();
53 Standard_Integer myIndex;
56 //! Iterator through layers with filter.
57 class OpenGl_FilteredIndexedLayerIterator
61 OpenGl_FilteredIndexedLayerIterator (const NCollection_List<Handle(Graphic3d_Layer)>& theSeq,
62 Standard_Boolean theToDrawImmediate,
63 OpenGl_LayerFilter theLayersToProcess)
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 const Handle(Graphic3d_Layer)& aLayer = myIter.Value();
94 if (aLayer->IsImmediate() != myToDrawImmediate)
99 switch (myLayersToProcess)
105 case OpenGl_LF_Upper:
107 if (aLayer->LayerId() != Graphic3d_ZLayerId_BotOSD
108 && (!aLayer->LayerSettings().IsRaytracable()
109 || aLayer->IsImmediate()))
115 case OpenGl_LF_Bottom:
117 if (aLayer->LayerId() == Graphic3d_ZLayerId_BotOSD
118 && !aLayer->LayerSettings().IsRaytracable())
124 case OpenGl_LF_RayTracable:
126 if (aLayer->LayerSettings().IsRaytracable()
127 && !aLayer->IsImmediate())
137 OpenGl_IndexedLayerIterator myIter;
138 OpenGl_LayerFilter myLayersToProcess;
139 Standard_Boolean myToDrawImmediate;
142 static const Standard_Integer THE_DRAW_BUFFERS0[] = { GL_COLOR_ATTACHMENT0 };
143 static const Standard_Integer THE_DRAW_BUFFERS01[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0 + 1 };
144 static const Standard_Integer THE_DRAW_BUFFERS012[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0 + 1, GL_COLOR_ATTACHMENT0 + 2 };
145 static const float THE_DEPTH_CLEAR_VALUE = -1e15f;
148 struct OpenGl_GlobalLayerSettings
154 //=======================================================================
155 //function : OpenGl_LayerList
156 //purpose : Constructor
157 //=======================================================================
159 OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
160 : myBVHBuilder (new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth)),
161 myNbPriorities (theNbPriorities),
163 myImmediateNbStructures (0),
164 myModifStateOfRaytraceable (0)
169 //=======================================================================
170 //function : ~OpenGl_LayerList
171 //purpose : Destructor
172 //=======================================================================
174 OpenGl_LayerList::~OpenGl_LayerList()
178 //=======================================================================
179 //function : SetFrustumCullingBVHBuilder
181 //=======================================================================
182 void OpenGl_LayerList::SetFrustumCullingBVHBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder)
184 myBVHBuilder = theBuilder;
185 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
187 aLayerIter.ChangeValue()->SetFrustumCullingBVHBuilder (theBuilder);
191 //=======================================================================
192 //function : InsertLayerBefore
194 //=======================================================================
195 void OpenGl_LayerList::InsertLayerBefore (const Graphic3d_ZLayerId theNewLayerId,
196 const Graphic3d_ZLayerSettings& theSettings,
197 const Graphic3d_ZLayerId theLayerAfter)
199 if (myLayerIds.IsBound (theNewLayerId))
204 Handle(Graphic3d_Layer) aNewLayer = new Graphic3d_Layer (theNewLayerId, myNbPriorities, myBVHBuilder);
205 aNewLayer->SetLayerSettings (theSettings);
207 Handle(Graphic3d_Layer) anOtherLayer;
208 if (theLayerAfter != Graphic3d_ZLayerId_UNKNOWN
209 && myLayerIds.Find (theLayerAfter, anOtherLayer))
211 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
213 if (aLayerIter.Value() == anOtherLayer)
215 myLayers.InsertBefore (aNewLayer, aLayerIter);
222 myLayers.Prepend (aNewLayer);
225 myLayerIds.Bind (theNewLayerId, aNewLayer);
226 myTransparentToProcess.Allocate (myLayers.Size());
229 //=======================================================================
230 //function : InsertLayerAfter
232 //=======================================================================
233 void OpenGl_LayerList::InsertLayerAfter (const Graphic3d_ZLayerId theNewLayerId,
234 const Graphic3d_ZLayerSettings& theSettings,
235 const Graphic3d_ZLayerId theLayerBefore)
237 if (myLayerIds.IsBound (theNewLayerId))
242 Handle(Graphic3d_Layer) aNewLayer = new Graphic3d_Layer (theNewLayerId, myNbPriorities, myBVHBuilder);
243 aNewLayer->SetLayerSettings (theSettings);
245 Handle(Graphic3d_Layer) anOtherLayer;
246 if (theLayerBefore != Graphic3d_ZLayerId_UNKNOWN
247 && myLayerIds.Find (theLayerBefore, anOtherLayer))
249 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
251 if (aLayerIter.Value() == anOtherLayer)
253 myLayers.InsertAfter (aNewLayer, aLayerIter);
260 myLayers.Append (aNewLayer);
263 myLayerIds.Bind (theNewLayerId, aNewLayer);
264 myTransparentToProcess.Allocate (myLayers.Size());
267 //=======================================================================
268 //function : RemoveLayer
270 //=======================================================================
271 void OpenGl_LayerList::RemoveLayer (const Graphic3d_ZLayerId theLayerId)
273 Handle(Graphic3d_Layer) aLayerToRemove;
275 || !myLayerIds.Find (theLayerId, aLayerToRemove))
280 // move all displayed structures to first layer
281 myLayerIds.Find (Graphic3d_ZLayerId_Default)->Append (*aLayerToRemove);
284 myLayers.Remove (aLayerToRemove);
285 myLayerIds.UnBind (theLayerId);
287 myTransparentToProcess.Allocate (myLayers.Size());
290 //=======================================================================
291 //function : AddStructure
293 //=======================================================================
295 void OpenGl_LayerList::AddStructure (const OpenGl_Structure* theStruct,
296 const Graphic3d_ZLayerId theLayerId,
297 const Standard_Integer thePriority,
298 Standard_Boolean isForChangePriority)
300 // add structure to associated layer,
301 // if layer doesn't exists, display structure in default layer
302 const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (theLayerId);
303 const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default);
304 aLayer->Add (theStruct, thePriority, isForChangePriority);
306 if (aLayer->IsImmediate())
308 ++myImmediateNbStructures;
311 // Note: In ray-tracing mode we don't modify modification
312 // state here. It is redundant, because the possible changes
313 // will be handled in the loop for structures
316 //=======================================================================
317 //function : RemoveStructure
319 //=======================================================================
321 void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure)
323 const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
324 const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (aLayerId);
325 const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default);
327 Standard_Integer aPriority = -1;
329 // remove structure from associated list
330 // if the structure is not found there,
331 // scan through layers and remove it
332 if (aLayer->Remove (theStructure, aPriority))
335 if (aLayer->IsImmediate())
337 --myImmediateNbStructures;
340 if (aLayer->LayerSettings().IsRaytracable()
341 && theStructure->IsRaytracable())
343 ++myModifStateOfRaytraceable;
349 // scan through layers and remove it
350 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
352 const Handle(Graphic3d_Layer)& aLayerEx = aLayerIter.ChangeValue();
353 if (aLayerEx == aLayer)
358 if (aLayerEx->Remove (theStructure, aPriority))
361 if (aLayerEx->IsImmediate())
363 --myImmediateNbStructures;
366 if (aLayerEx->LayerSettings().IsRaytracable()
367 && theStructure->IsRaytracable())
369 ++myModifStateOfRaytraceable;
376 //=======================================================================
377 //function : InvalidateBVHData
379 //=======================================================================
380 void OpenGl_LayerList::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
382 const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (theLayerId);
383 const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default);
384 aLayer->InvalidateBVHData();
387 //=======================================================================
388 //function : ChangeLayer
390 //=======================================================================
392 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure* theStructure,
393 const Graphic3d_ZLayerId theOldLayerId,
394 const Graphic3d_ZLayerId theNewLayerId)
396 const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (theOldLayerId);
397 const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default);
399 Standard_Integer aPriority = -1;
401 // take priority and remove structure from list found by <theOldLayerId>
402 // if the structure is not found there, scan through all other layers
403 if (aLayer->Remove (theStructure, aPriority, Standard_False))
405 if (aLayer->LayerSettings().IsRaytracable()
406 && !aLayer->LayerSettings().IsImmediate()
407 && theStructure->IsRaytracable())
409 ++myModifStateOfRaytraceable;
413 if (aLayer->IsImmediate())
415 --myImmediateNbStructures;
418 // isForChangePriority should be Standard_False below, because we want
419 // the BVH tree in the target layer to be updated with theStructure
420 AddStructure (theStructure, theNewLayerId, aPriority);
424 // scan through layers and remove it
425 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
427 const Handle(OpenGl_Layer)& aLayerEx = aLayerIter.ChangeValue();
428 if (aLayerEx == aLayer)
433 // try to remove structure and get priority value from this layer
434 if (aLayerEx->Remove (theStructure, aPriority, Standard_True))
436 if (aLayerEx->LayerSettings().IsRaytracable()
437 && !aLayerEx->LayerSettings().IsImmediate()
438 && theStructure->IsRaytracable())
440 ++myModifStateOfRaytraceable;
444 if (aLayerEx->IsImmediate())
446 --myImmediateNbStructures;
449 // isForChangePriority should be Standard_False below, because we want
450 // the BVH tree in the target layer to be updated with theStructure
451 AddStructure (theStructure, theNewLayerId, aPriority);
457 //=======================================================================
458 //function : ChangePriority
460 //=======================================================================
461 void OpenGl_LayerList::ChangePriority (const OpenGl_Structure* theStructure,
462 const Graphic3d_ZLayerId theLayerId,
463 const Standard_Integer theNewPriority)
465 const Handle(Graphic3d_Layer)* aLayerPtr = myLayerIds.Seek (theLayerId);
466 const Handle(Graphic3d_Layer)& aLayer = aLayerPtr != NULL ? *aLayerPtr : myLayerIds.Find (Graphic3d_ZLayerId_Default);
468 Standard_Integer anOldPriority = -1;
470 if (aLayer->Remove (theStructure, anOldPriority, Standard_True))
473 if (aLayer->IsImmediate())
475 --myImmediateNbStructures;
478 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
482 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
484 const Handle(OpenGl_Layer)& aLayerEx = aLayerIter.ChangeValue();
485 if (aLayerEx == aLayer)
490 if (aLayerEx->Remove (theStructure, anOldPriority, Standard_True))
493 if (aLayerEx->IsImmediate())
495 --myImmediateNbStructures;
498 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
504 //=======================================================================
505 //function : SetLayerSettings
507 //=======================================================================
508 void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId theLayerId,
509 const Graphic3d_ZLayerSettings& theSettings)
511 Graphic3d_Layer& aLayer = Layer (theLayerId);
512 if (aLayer.LayerSettings().IsRaytracable() != theSettings.IsRaytracable()
513 && aLayer.NbStructures() != 0)
515 ++myModifStateOfRaytraceable;
517 if (aLayer.LayerSettings().IsImmediate() != theSettings.IsImmediate())
519 if (theSettings.IsImmediate())
521 myImmediateNbStructures += aLayer.NbStructures();
525 myImmediateNbStructures -= aLayer.NbStructures();
528 aLayer.SetLayerSettings (theSettings);
531 //=======================================================================
532 //function : UpdateCulling
534 //=======================================================================
535 void OpenGl_LayerList::UpdateCulling (const Handle(OpenGl_Workspace)& theWorkspace,
536 const Standard_Boolean theToDrawImmediate)
538 const Handle(OpenGl_FrameStats)& aStats = theWorkspace->GetGlContext()->FrameStats();
539 OSD_Timer& aTimer = aStats->ActiveDataFrame().ChangeTimer (Graphic3d_FrameStatsTimer_CpuCulling);
542 const Standard_Integer aViewId = theWorkspace->View()->Identification();
543 const Graphic3d_CullingTool& aSelector = theWorkspace->View()->BVHTreeSelector();
544 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
546 const Handle(Graphic3d_Layer)& aLayer = aLayerIter.ChangeValue();
547 if (aLayer->IsImmediate() != theToDrawImmediate)
552 aLayer->UpdateCulling (aViewId, aSelector, theWorkspace->View()->RenderingParams().FrustumCullingState);
556 aStats->ActiveDataFrame()[Graphic3d_FrameStatsTimer_CpuCulling] = aTimer.UserTimeCPU();
559 //=======================================================================
560 //function : renderLayer
562 //=======================================================================
563 void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace,
564 const OpenGl_GlobalLayerSettings& theDefaultSettings,
565 const Graphic3d_Layer& theLayer) const
567 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
569 const Graphic3d_ZLayerSettings& aLayerSettings = theLayer.LayerSettings();
570 // aLayerSettings.ToClearDepth() is handled outside
573 if (aLayerSettings.ToEnableDepthTest())
575 // assuming depth test is enabled by default
576 glDepthFunc (theDefaultSettings.DepthFunc);
580 glDepthFunc (GL_ALWAYS);
583 // save environment texture
584 Handle(OpenGl_TextureSet) anEnvironmentTexture = theWorkspace->EnvironmentTexture();
585 if (!aLayerSettings.UseEnvironmentTexture())
587 theWorkspace->SetEnvironmentTexture (Handle(OpenGl_TextureSet)());
590 // handle depth offset
591 const Graphic3d_PolygonOffset anAppliedOffsetParams = theWorkspace->SetDefaultPolygonOffset (aLayerSettings.PolygonOffset());
593 // handle depth write
594 theWorkspace->UseDepthWrite() = aLayerSettings.ToEnableDepthWrite() && theDefaultSettings.DepthMask == GL_TRUE;
595 glDepthMask (theWorkspace->UseDepthWrite() ? GL_TRUE : GL_FALSE);
597 const Standard_Boolean hasLocalCS = !aLayerSettings.OriginTransformation().IsNull();
598 const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
599 Handle(Graphic3d_LightSet) aLightsBack = aManager->LightSourceState().LightSources();
600 Handle(OpenGl_ShadowMapArray) aShadowMaps = aManager->LightSourceState().ShadowMaps();
601 const bool hasOwnLights = aCtx->ColorMask() && !aLayerSettings.Lights().IsNull() && aLayerSettings.Lights() != aLightsBack;
604 aLayerSettings.Lights()->UpdateRevision();
605 aManager->UpdateLightSourceStateTo (aLayerSettings.Lights(), theWorkspace->View()->SpecIBLMapLevels(), Handle(OpenGl_ShadowMapArray)());
608 const Handle(Graphic3d_Camera)& aWorldCamera = aCtx->Camera();
611 // Apply local camera transformation.
612 // The vertex position is computed by the following formula in GLSL program:
613 // gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;
615 // occProjectionMatrix - matrix defining orthographic/perspective/stereographic projection
616 // occWorldViewMatrix - world-view matrix defining Camera position and orientation
617 // occModelWorldMatrix - model-world matrix defining Object transformation from local coordinate system to the world coordinate system
618 // occVertex - input vertex position
620 // Since double precision is quite expensive on modern GPUs, and not available on old hardware,
621 // all these values are passed with single float precision to the shader.
622 // As result, single precision become insufficient for handling objects far from the world origin.
624 // Several approaches can be used to solve precision issues:
625 // - [Broute force] migrate to double precision for all matrices and vertex position.
626 // This is too expensive for most hardware.
627 // - Store only translation part with double precision and pass it to GLSL program.
628 // This requires modified GLSL programs for computing transformation
629 // and extra packing mechanism for hardware not supporting double precision natively.
630 // This solution is less expensive then previous one.
631 // - Move translation part of occModelWorldMatrix into occWorldViewMatrix.
632 // The main idea here is that while moving Camera towards the object,
633 // Camera translation part and Object translation part will compensate each other
634 // to fit into single float precision.
635 // But this operation should be performed with double precision - this is why we are moving
636 // translation part of occModelWorldMatrix to occWorldViewMatrix.
638 // All approaches might be useful in different scenarios, but for the moment we consider the last one as main scenario.
639 // Here we do the trick:
640 // - OpenGl_Layer defines the Local Origin, which is expected to be the center of objects stored within it.
641 // This Local Origin is included into occWorldViewMatrix during rendering.
642 // - OpenGl_Structure defines Object local transformation occModelWorldMatrix with subtracted Local Origin of the Layer.
643 // This means that Object itself should be defined within either Local Transformation equal or near to Local Origin of the Layer.
644 theWorkspace->View()->SetLocalOrigin (aLayerSettings.Origin());
646 NCollection_Mat4<Standard_Real> aWorldView = aWorldCamera->OrientationMatrix();
647 Graphic3d_TransformUtils::Translate (aWorldView, aLayerSettings.Origin().X(), aLayerSettings.Origin().Y(), aLayerSettings.Origin().Z());
649 if (!aManager->LightSourceState().ShadowMaps().IsNull())
651 // shift shadowmap matrix
652 for (OpenGl_ShadowMapArray::Iterator aShadowIter (*aManager->LightSourceState().ShadowMaps()); aShadowIter.More(); aShadowIter.Next())
654 aShadowIter.Value()->UpdateCamera (*theWorkspace->View(), &aLayerSettings.Origin());
658 NCollection_Mat4<Standard_ShortReal> aWorldViewF;
659 aWorldViewF.ConvertFrom (aWorldView);
660 aCtx->WorldViewState.SetCurrent (aWorldViewF);
661 aCtx->ShaderManager()->UpdateClippingState();
662 aCtx->ShaderManager()->UpdateLightSourceState();
665 // render priority list
666 const Standard_Integer aViewId = theWorkspace->View()->Identification();
667 for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (theLayer.ArrayOfStructures()); aMapIter.More(); aMapIter.Next())
669 const Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.Value();
670 for (OpenGl_Structure::StructIterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
672 const OpenGl_Structure* aStruct = aStructIter.Value();
673 if (aStruct->IsCulled()
674 || !aStruct->IsVisible (aViewId))
679 aStruct->Render (theWorkspace);
685 aManager->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels(), aShadowMaps);
689 if (!aManager->LightSourceState().ShadowMaps().IsNull())
691 // restore shadowmap matrix
692 for (OpenGl_ShadowMapArray::Iterator aShadowIter (*aManager->LightSourceState().ShadowMaps()); aShadowIter.More(); aShadowIter.Next())
694 aShadowIter.Value()->UpdateCamera (*theWorkspace->View(), &gp::Origin().XYZ());
698 aCtx->ShaderManager()->RevertClippingState();
699 aCtx->ShaderManager()->UpdateLightSourceState();
701 aCtx->WorldViewState.SetCurrent (aWorldCamera->OrientationMatrixF());
702 theWorkspace->View() ->SetLocalOrigin (gp_XYZ (0.0, 0.0, 0.0));
705 // always restore polygon offset between layers rendering
706 theWorkspace->SetDefaultPolygonOffset (anAppliedOffsetParams);
708 // restore environment texture
709 if (!aLayerSettings.UseEnvironmentTexture())
711 theWorkspace->SetEnvironmentTexture (anEnvironmentTexture);
715 //=======================================================================
718 //=======================================================================
719 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
720 const Standard_Boolean theToDrawImmediate,
721 const OpenGl_LayerFilter theLayersToProcess,
722 OpenGl_FrameBuffer* theReadDrawFbo,
723 OpenGl_FrameBuffer* theOitAccumFbo) const
725 // Remember global settings for glDepth function and write mask.
726 OpenGl_GlobalLayerSettings aPrevSettings;
728 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
729 aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC, &aPrevSettings.DepthFunc);
730 aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aPrevSettings.DepthMask);
731 OpenGl_GlobalLayerSettings aDefaultSettings = aPrevSettings;
732 const bool isShadowMapPass = theReadDrawFbo != NULL
733 && !theReadDrawFbo->HasColor();
735 // Two render filters are used to support transparency draw. Opaque filter accepts
736 // only non-transparent OpenGl elements of a layer and counts number of skipped
737 // transparent ones. If the counter has positive value the layer is added into
738 // transparency post-processing stack. At the end of drawing or once the depth
739 // buffer is to be cleared the layers in the stack should be drawn using
740 // blending and depth mask settings and another transparency filter which accepts
741 // only transparent OpenGl elements of a layer. The stack <myTransparentToProcess>
742 // was preallocated before going into this method and has enough space to keep
743 // maximum number of references to layers, therefore it will not increase memory
744 // fragmentation during regular rendering.
745 const Standard_Integer aPrevFilter = theWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly);
746 theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_OpaqueOnly);
748 myTransparentToProcess.Clear();
750 OpenGl_LayerStack::iterator aStackIter (myTransparentToProcess.Origin());
751 Standard_Integer aClearDepthLayerPrev = -1, aClearDepthLayer = -1;
752 const bool toPerformDepthPrepass = theWorkspace->View()->RenderingParams().ToEnableDepthPrepass
753 && aPrevSettings.DepthMask == GL_TRUE
755 const Handle(Graphic3d_LightSet) aLightsBack = aCtx->ShaderManager()->LightSourceState().LightSources();
756 const Handle(OpenGl_ShadowMapArray) aShadowMaps = aCtx->ShaderManager()->LightSourceState().ShadowMaps();
757 for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, theToDrawImmediate, theLayersToProcess); aLayerIterStart.More();)
759 bool hasSkippedDepthLayers = false;
760 for (int aPassIter = toPerformDepthPrepass ? 0 : 2; aPassIter < 3; ++aPassIter)
764 aCtx->SetColorMask (false);
765 aCtx->ShaderManager()->UpdateLightSourceStateTo (Handle(Graphic3d_LightSet)(), theWorkspace->View()->SpecIBLMapLevels(), Handle(OpenGl_ShadowMapArray)());
766 aDefaultSettings.DepthFunc = aPrevSettings.DepthFunc;
767 aDefaultSettings.DepthMask = GL_TRUE;
769 else if (aPassIter == 1)
771 if (!hasSkippedDepthLayers)
775 aCtx->SetColorMask (true);
776 aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels(), aShadowMaps);
777 aDefaultSettings = aPrevSettings;
779 else if (aPassIter == 2)
783 aCtx->SetColorMask (false);
784 aCtx->ShaderManager()->UpdateLightSourceStateTo (Handle(Graphic3d_LightSet)(), theWorkspace->View()->SpecIBLMapLevels(), Handle(OpenGl_ShadowMapArray)());
788 aCtx->SetColorMask (true);
789 aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels(), aShadowMaps);
791 if (toPerformDepthPrepass)
793 aDefaultSettings.DepthFunc = GL_EQUAL;
794 aDefaultSettings.DepthMask = GL_FALSE;
798 OpenGl_FilteredIndexedLayerIterator aLayerIter (aLayerIterStart);
799 for (; aLayerIter.More(); aLayerIter.Next())
801 const OpenGl_Layer& aLayer = aLayerIter.Value();
803 // make sure to clear depth of previous layers even if layer has no structures
804 if (aLayer.LayerSettings().ToClearDepth())
806 aClearDepthLayer = aLayerIter.Index();
808 if (aLayer.IsCulled())
812 else if (aClearDepthLayer > aClearDepthLayerPrev)
814 // At this point the depth buffer may be set to clear by previous configuration of layers or configuration of the current layer.
815 // Additional rendering pass to handle transparent elements of recently drawn layers require use of current depth
816 // buffer so we put remaining layers for processing as one bunch before erasing the depth buffer.
819 aLayerIterStart = aLayerIter;
823 aClearDepthLayer = -1;
827 else if (aPassIter == 0
828 && !aLayer.LayerSettings().ToRenderInDepthPrepass())
830 hasSkippedDepthLayers = true;
833 else if (aPassIter == 1
834 && aLayer.LayerSettings().ToRenderInDepthPrepass())
839 // Render opaque OpenGl elements of a layer and count the number of skipped.
840 // If a layer has skipped (e.g. transparent) elements it should be added into
841 // the transparency post-processing stack.
842 theWorkspace->ResetSkippedCounter();
844 renderLayer (theWorkspace, aDefaultSettings, aLayer);
847 && theWorkspace->NbSkippedTransparentElements() > 0)
849 myTransparentToProcess.Push (&aLayer);
853 && !aLayerIter.More())
855 aLayerIterStart = aLayerIter;
859 if (!myTransparentToProcess.IsEmpty())
861 renderTransparent (theWorkspace, aStackIter, aPrevSettings, theReadDrawFbo, theOitAccumFbo);
863 if (aClearDepthLayer > aClearDepthLayerPrev)
865 aClearDepthLayerPrev = aClearDepthLayer;
866 glDepthMask (GL_TRUE);
867 glClear (GL_DEPTH_BUFFER_BIT);
871 aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack, theWorkspace->View()->SpecIBLMapLevels(), aShadowMaps);
872 aCtx->core11fwd->glDepthMask (aPrevSettings.DepthMask);
873 aCtx->core11fwd->glDepthFunc (aPrevSettings.DepthFunc);
875 theWorkspace->SetRenderFilter (aPrevFilter);
878 //=======================================================================
879 //function : renderTransparent
880 //purpose : Render transparent objects using blending operator.
881 //=======================================================================
882 void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)& theWorkspace,
883 OpenGl_LayerStack::iterator& theLayerIter,
884 const OpenGl_GlobalLayerSettings& theGlobalSettings,
885 OpenGl_FrameBuffer* theReadDrawFbo,
886 OpenGl_FrameBuffer* theOitAccumFbo) const
888 // Check if current iterator has already reached the end of the stack.
889 // This should happen if no additional layers has been added to
890 // the processing stack after last transparency pass.
891 if (theLayerIter == myTransparentToProcess.Back())
896 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
897 const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
898 const OpenGl_LayerStack::iterator aLayerFrom = theLayerIter;
899 OpenGl_View* aView = theWorkspace->View();
901 Graphic3d_RenderTransparentMethod anOitMode = aView != NULL
902 ? aView->RenderingParams().TransparencyMethod
903 : Graphic3d_RTM_BLEND_UNORDERED;
905 const Standard_Integer aPrevFilter = theWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly);
906 theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_TransparentOnly);
907 aCtx->core11fwd->glEnable (GL_BLEND);
909 const Handle(OpenGl_FrameBuffer)* aGlDepthPeelFBOs = aView->DepthPeelingFbos()->DepthPeelFbosOit();
910 const Handle(OpenGl_FrameBuffer)* aGlFrontBackColorFBOs = aView->DepthPeelingFbos()->FrontBackColorFbosOit();
911 const Handle(OpenGl_FrameBuffer)& aGlBlendBackFBO = aView->DepthPeelingFbos()->BlendBackFboOit();
913 // Blended order-independent transparency algorithm require several preconditions to be enabled.
914 // It should be requested by user, at least two outputs from fragment shader should be supported by GPU,
915 // so is the given framebuffer should contain two additional color buffers to handle accumulated color channels,
916 // blended alpha channel and weight factors - these accumulation buffers are required
917 // to implement commuting blend operator (at least OpenGl 2.0 should be available).
918 if (anOitMode == Graphic3d_RTM_BLEND_OIT)
920 if (theOitAccumFbo == NULL
921 || theOitAccumFbo->NbColorBuffers() < 2
922 || !theOitAccumFbo->ColorTexture (0)->IsValid()
923 || !theOitAccumFbo->ColorTexture (1)->IsValid())
925 anOitMode = Graphic3d_RTM_BLEND_UNORDERED;
928 else if (anOitMode == Graphic3d_RTM_DEPTH_PEELING_OIT)
930 if (!aGlBlendBackFBO->IsValid())
932 anOitMode = Graphic3d_RTM_BLEND_UNORDERED;
935 const bool isMSAA = theReadDrawFbo && theReadDrawFbo->NbSamples() > 0;
936 int aDepthPeelingDrawId = -1;
940 case Graphic3d_RTM_BLEND_UNORDERED:
942 aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
945 case Graphic3d_RTM_BLEND_OIT:
947 const float aDepthFactor = aView->RenderingParams().OitDepthFactor;
948 aManager->SetWeighedOitState (aDepthFactor);
950 theOitAccumFbo->BindBuffer (aCtx);
952 aCtx->SetDrawBuffers (2, THE_DRAW_BUFFERS01);
953 aCtx->SetColorMaskRGBA (NCollection_Vec4<bool> (true)); // force writes into all components, including alpha
954 aCtx->core11fwd->glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
955 aCtx->core11fwd->glClear (GL_COLOR_BUFFER_BIT);
956 aCtx->core15fwd->glBlendFuncSeparate (GL_ONE, GL_ONE, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
959 case Graphic3d_RTM_DEPTH_PEELING_OIT:
961 static const float THE_MIN_DEPTH = 0.0f;
962 static const float THE_MAX_DEPTH = 1.0f;
964 aView->DepthPeelingFbos()->AttachDepthTexture (aCtx, theReadDrawFbo->DepthStencilTexture());
966 // initialize min/max depth buffer
967 aGlBlendBackFBO->BindDrawBuffer (aCtx);
968 aCtx->SetDrawBuffers (1, THE_DRAW_BUFFERS0);
969 aCtx->SetColorMaskRGBA (NCollection_Vec4<bool> (true)); // force writes into all components, including alpha
970 aCtx->core20fwd->glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
971 aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT);
973 aGlDepthPeelFBOs[1]->BindDrawBuffer (aCtx);
974 aCtx->SetDrawBuffers (1, THE_DRAW_BUFFERS0);
975 aCtx->core20fwd->glClearColor(-THE_MIN_DEPTH, THE_MAX_DEPTH, 0.0f, 0.0f);
976 aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT);
978 aGlFrontBackColorFBOs[0]->BindDrawBuffer (aCtx);
979 aCtx->SetDrawBuffers (2, THE_DRAW_BUFFERS01);
980 aCtx->core20fwd->glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
981 aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT);
983 aGlFrontBackColorFBOs[1]->BindDrawBuffer (aCtx);
984 aCtx->SetDrawBuffers (2, THE_DRAW_BUFFERS01);
985 aCtx->core20fwd->glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
986 aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT);
988 // draw depth for first pass to peel
989 aGlDepthPeelFBOs[0]->BindBuffer (aCtx);
991 aCtx->SetDrawBuffers (1, THE_DRAW_BUFFERS0);
992 aCtx->core20fwd->glClearColor (THE_DEPTH_CLEAR_VALUE, THE_DEPTH_CLEAR_VALUE, 0.0f, 0.0f);
993 aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT);
994 aCtx->core20fwd->glBlendEquation (GL_MAX);
996 aManager->SetOitState (Graphic3d_RTM_DEPTH_PEELING_OIT);
998 aGlDepthPeelFBOs[1]->ColorTexture (0)->Bind (aCtx, aCtx->DepthPeelingDepthTexUnit());
999 aGlDepthPeelFBOs[1]->ColorTexture (1)->Bind (aCtx, aCtx->DepthPeelingFrontColorTexUnit());
1004 // During blended order-independent transparency pass the depth test
1005 // should be enabled to discard fragments covered by opaque geometry
1006 // and depth writing should be disabled, because transparent fragments
1007 // overall each other with non unitary coverage factor.
1008 OpenGl_GlobalLayerSettings aGlobalSettings = theGlobalSettings;
1009 aGlobalSettings.DepthMask = GL_FALSE;
1010 aCtx->core11fwd->glDepthMask (GL_FALSE);
1012 for (theLayerIter = aLayerFrom; theLayerIter != myTransparentToProcess.Back(); ++theLayerIter)
1014 renderLayer (theWorkspace, aGlobalSettings, *(*theLayerIter));
1019 case Graphic3d_RTM_BLEND_UNORDERED:
1023 case Graphic3d_RTM_BLEND_OIT:
1025 // revert state of rendering
1026 aManager->ResetOitState();
1027 theOitAccumFbo->UnbindBuffer (aCtx);
1030 theReadDrawFbo->BindBuffer (aCtx);
1033 aCtx->SetDrawBuffers (1, THE_DRAW_BUFFERS0);
1034 aCtx->SetColorMask (true); // update writes into alpha component
1037 case Graphic3d_RTM_DEPTH_PEELING_OIT:
1039 // Dual Depth Peeling Ping-Pong
1040 const int aNbPasses = aView->RenderingParams().NbOitDepthPeelingLayers;
1041 OpenGl_VertexBuffer* aQuadVerts = aView->initBlitQuad (false);
1043 aGlDepthPeelFBOs[1]->ColorTexture (1)->Unbind (aCtx, aCtx->DepthPeelingFrontColorTexUnit());
1044 aGlDepthPeelFBOs[1]->ColorTexture (0)->Unbind (aCtx, aCtx->DepthPeelingDepthTexUnit());
1046 for (int aPass = 0; aPass < aNbPasses; ++aPass)
1048 const int aReadId = aPass % 2;
1049 aDepthPeelingDrawId = 1 - aReadId;
1051 aGlDepthPeelFBOs[aDepthPeelingDrawId]->BindDrawBuffer (aCtx);
1052 aCtx->SetDrawBuffers (1, THE_DRAW_BUFFERS0);
1053 aCtx->core20fwd->glClearColor (THE_DEPTH_CLEAR_VALUE, THE_DEPTH_CLEAR_VALUE, 0.0f, 0.0f);
1054 aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT);
1056 aGlFrontBackColorFBOs[aDepthPeelingDrawId]->BindDrawBuffer (aCtx);
1057 aCtx->SetDrawBuffers (2, THE_DRAW_BUFFERS01);
1058 aCtx->core20fwd->glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
1059 aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT);
1061 ///aGlDepthPeelFBOs[aDepthPeelingDrawId]->BindDrawBuffer (aCtx);
1062 aGlDepthPeelFBOs[aDepthPeelingDrawId]->BindBuffer (aCtx);
1063 aCtx->SetDrawBuffers (3, THE_DRAW_BUFFERS012);
1064 aCtx->core20fwd->glBlendEquation (GL_MAX);
1066 aGlDepthPeelFBOs[aReadId]->ColorTexture (0)->Bind (aCtx, aCtx->DepthPeelingDepthTexUnit());
1067 aGlDepthPeelFBOs[aReadId]->ColorTexture (1)->Bind (aCtx, aCtx->DepthPeelingFrontColorTexUnit());
1070 for (theLayerIter = aLayerFrom; theLayerIter != myTransparentToProcess.Back(); ++theLayerIter)
1072 renderLayer (theWorkspace, aGlobalSettings, *(*theLayerIter));
1075 aGlDepthPeelFBOs[aReadId]->ColorTexture (1)->Unbind (aCtx, aCtx->DepthPeelingFrontColorTexUnit());
1076 aGlDepthPeelFBOs[aReadId]->ColorTexture (0)->Unbind (aCtx, aCtx->DepthPeelingDepthTexUnit());
1079 aGlBlendBackFBO->BindDrawBuffer (aCtx);
1080 aCtx->SetDrawBuffers (1, THE_DRAW_BUFFERS0);
1081 if (aQuadVerts->IsValid()
1082 && aManager->BindOitDepthPeelingBlendProgram (isMSAA))
1084 aCtx->core20fwd->glBlendEquation (GL_FUNC_ADD);
1085 aCtx->core20fwd->glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1086 aCtx->core20fwd->glDepthFunc (GL_ALWAYS);
1088 aQuadVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS);
1090 const Handle(OpenGl_TextureSet) aTextureBack = aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
1091 aGlDepthPeelFBOs[aDepthPeelingDrawId]->ColorTexture (2)->Bind (aCtx, Graphic3d_TextureUnit_0);
1093 aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
1095 aQuadVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS);
1096 aGlDepthPeelFBOs[aDepthPeelingDrawId]->ColorTexture (2)->Unbind (aCtx, Graphic3d_TextureUnit_0);
1097 aCtx->BindProgram (NULL);
1099 if (!aTextureBack.IsNull())
1101 aCtx->BindTextures (aTextureBack, Handle(OpenGl_ShaderProgram)());
1104 aCtx->core11fwd->glDepthFunc (theGlobalSettings.DepthFunc);
1108 aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
1109 "Initialization of OIT compositing pass has failed.\n"
1110 " Depth Peeling order-independent transparency will not be available.\n");
1113 Standard_Boolean& aOITFlag = isMSAA ? aView->myToDisableOITMSAA : aView->myToDisableOIT;
1114 aOITFlag = Standard_True;
1119 aManager->ResetOitState();
1120 aGlBlendBackFBO->UnbindBuffer (aCtx);
1123 theReadDrawFbo->BindBuffer (aCtx);
1125 aCtx->SetDrawBuffers (1, THE_DRAW_BUFFERS0);
1126 aCtx->SetColorMask (true); // update writes into alpha component
1131 theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_OpaqueOnly);
1134 case Graphic3d_RTM_BLEND_UNORDERED:
1138 case Graphic3d_RTM_BLEND_OIT:
1140 // draw full screen quad with special shader to compose the buffers
1141 OpenGl_VertexBuffer* aVerts = aView->initBlitQuad (Standard_False);
1142 if (aVerts->IsValid()
1143 && aManager->BindOitCompositingProgram (isMSAA))
1145 aCtx->core11fwd->glDepthFunc (GL_ALWAYS);
1146 aCtx->core11fwd->glDepthMask (GL_FALSE);
1148 aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS);
1150 const Handle(OpenGl_TextureSet) aTextureBack = aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
1151 theOitAccumFbo->ColorTexture (0)->Bind (aCtx, Graphic3d_TextureUnit_0);
1152 theOitAccumFbo->ColorTexture (1)->Bind (aCtx, Graphic3d_TextureUnit_1);
1154 aCtx->core11fwd->glBlendFunc (GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
1155 aCtx->core11fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
1157 aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS);
1158 theOitAccumFbo->ColorTexture (1)->Unbind (aCtx, Graphic3d_TextureUnit_1);
1159 theOitAccumFbo->ColorTexture (0)->Unbind (aCtx, Graphic3d_TextureUnit_0);
1160 aCtx->BindProgram (NULL);
1162 if (!aTextureBack.IsNull())
1164 aCtx->BindTextures (aTextureBack, Handle(OpenGl_ShaderProgram)());
1169 aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
1170 "Initialization of OIT compositing pass has failed.\n"
1171 " Blended order-independent transparency will not be available.\n");
1174 Standard_Boolean& aOITFlag = isMSAA ? aView->myToDisableOITMSAA : aView->myToDisableOIT;
1175 aOITFlag = Standard_True;
1180 case Graphic3d_RTM_DEPTH_PEELING_OIT:
1182 // compose depth peeling results into destination FBO
1183 OpenGl_VertexBuffer* aVerts = aView->initBlitQuad (Standard_False);
1184 if (aVerts->IsValid()
1185 && aManager->BindOitDepthPeelingFlushProgram (isMSAA))
1187 aCtx->core20fwd->glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1188 aCtx->core20fwd->glDepthFunc (GL_ALWAYS);
1190 aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS);
1192 const Handle(OpenGl_TextureSet) aTextureBack = aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
1193 aGlDepthPeelFBOs[aDepthPeelingDrawId]->ColorTexture (1)->Bind (aCtx, Graphic3d_TextureUnit_0);
1194 aGlBlendBackFBO->ColorTexture (0)->Bind (aCtx, Graphic3d_TextureUnit_1);
1196 aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
1198 aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS);
1199 aGlBlendBackFBO->ColorTexture (0)->Unbind (aCtx, Graphic3d_TextureUnit_1);
1200 aGlDepthPeelFBOs[aDepthPeelingDrawId]->ColorTexture (1)->Unbind (aCtx, Graphic3d_TextureUnit_0);
1201 aCtx->BindProgram (NULL);
1203 if (!aTextureBack.IsNull())
1205 aCtx->BindTextures (aTextureBack, Handle(OpenGl_ShaderProgram)());
1208 aCtx->core11fwd->glDepthFunc (theGlobalSettings.DepthFunc);
1212 aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
1213 "Initialization of OIT compositing pass has failed.\n"
1214 " Depth Peeling order-independent transparency will not be available.\n");
1217 Standard_Boolean& aOITFlag = isMSAA ? aView->myToDisableOITMSAA : aView->myToDisableOIT;
1221 aView->DepthPeelingFbos()->DetachDepthTexture (aCtx);
1226 aCtx->core11fwd->glDisable (GL_BLEND);
1227 aCtx->core11fwd->glBlendFunc (GL_ONE, GL_ZERO);
1228 aCtx->core11fwd->glDepthMask (theGlobalSettings.DepthMask);
1229 aCtx->core11fwd->glDepthFunc (theGlobalSettings.DepthFunc);
1232 // =======================================================================
1233 // function : DumpJson
1235 // =======================================================================
1236 void OpenGl_LayerList::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
1238 OCCT_DUMP_CLASS_BEGIN (theOStream, OpenGl_LayerList)
1240 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayersIt (myLayers); aLayersIt.More(); aLayersIt.Next())
1242 const Handle(Graphic3d_Layer)& aLayerId = aLayersIt.Value();
1243 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, aLayerId.get())
1246 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myNbPriorities)
1247 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myNbStructures)
1248 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myImmediateNbStructures)
1249 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myModifStateOfRaytraceable)