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