0028698: Visualization, Graphic3d_CView - mark methods MinMaxValues() and NumberOfDis...
[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
5f8b738e 16#include <OpenGl_GlCore11.hxx>
17
59f45b7c 18#include <OpenGl_LayerList.hxx>
59f45b7c 19#include <OpenGl_Structure.hxx>
550f3b8b 20#include <OpenGl_Workspace.hxx>
59f45b7c 21
c04c30b3 22#include <Graphic3d_GraphicDriver.hxx>
59f45b7c 23
24//=======================================================================
25//function : OpenGl_LayerList
26//purpose : Constructor
27//=======================================================================
28
29OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
bd6a8454 30: myDefaultLayerIndex (0),
31 myNbPriorities (theNbPriorities),
a1954302 32 myNbStructures (0),
bd6a8454 33 myImmediateNbStructures (0),
34 myModifStateOfRaytraceable (0)
59f45b7c 35{
a1954302 36 // insert default priority layers
c5751993 37 myLayers.Append (OpenGl_Layer (myNbPriorities));
af65fb19 38 myLayerIds.Bind (Graphic3d_ZLayerId_BotOSD, myLayers.Upper());
39
40 myLayers.Append (OpenGl_Layer (myNbPriorities));
a1954302 41 myLayerIds.Bind (Graphic3d_ZLayerId_Default, myLayers.Upper());
59f45b7c 42
a1954302 43 myLayers.Append (OpenGl_Layer (myNbPriorities));
44 myLayerIds.Bind (Graphic3d_ZLayerId_Top, myLayers.Upper());
59f45b7c 45
a1954302 46 myLayers.Append (OpenGl_Layer (myNbPriorities));
47 myLayerIds.Bind (Graphic3d_ZLayerId_Topmost, myLayers.Upper());
59f45b7c 48
a1954302 49 myLayers.Append (OpenGl_Layer (myNbPriorities));
50 myLayerIds.Bind (Graphic3d_ZLayerId_TopOSD, myLayers.Upper());
bd6a8454 51
52 myDefaultLayerIndex = myLayerIds.Find (Graphic3d_ZLayerId_Default);
59f45b7c 53}
54
55//=======================================================================
a1954302 56//function : ~OpenGl_LayerList
57//purpose : Destructor
59f45b7c 58//=======================================================================
59
a1954302 60OpenGl_LayerList::~OpenGl_LayerList()
59f45b7c 61{
59f45b7c 62}
63
64//=======================================================================
65//function : AddLayer
66//purpose :
67//=======================================================================
68
a1954302 69void OpenGl_LayerList::AddLayer (const Graphic3d_ZLayerId theLayerId)
59f45b7c 70{
a1954302 71 if (myLayerIds.IsBound (theLayerId))
72 {
59f45b7c 73 return;
a1954302 74 }
59f45b7c 75
76 // add the new layer
c5751993 77 myLayers.Append (OpenGl_Layer (myNbPriorities));
59f45b7c 78 myLayerIds.Bind (theLayerId, myLayers.Length());
79}
80
81//=======================================================================
c5751993 82//function : Layer
83//purpose :
84//=======================================================================
a1954302 85OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId)
c5751993 86{
87 return myLayers.ChangeValue (myLayerIds.Find (theLayerId));
88}
89
90//=======================================================================
91//function : Layer
92//purpose :
93//=======================================================================
a1954302 94const OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId) const
c5751993 95{
96 return myLayers.Value (myLayerIds.Find (theLayerId));
97}
98
99//=======================================================================
59f45b7c 100//function : RemoveLayer
101//purpose :
102//=======================================================================
103
a1954302 104void OpenGl_LayerList::RemoveLayer (const Graphic3d_ZLayerId theLayerId)
59f45b7c 105{
a1954302 106 if (!myLayerIds.IsBound (theLayerId)
107 || theLayerId <= 0)
108 {
59f45b7c 109 return;
a1954302 110 }
59f45b7c 111
a1954302 112 const Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
59f45b7c 113
114 // move all displayed structures to first layer
a1954302 115 const OpenGl_Layer& aLayerToMove = myLayers.Value (aRemovePos);
116 myLayers.ChangeFirst().Append (aLayerToMove);
59f45b7c 117
118 // remove layer
119 myLayers.Remove (aRemovePos);
120 myLayerIds.UnBind (theLayerId);
121
122 // updated sequence indexes in map
bd6a8454 123 for (OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds); aMapIt.More(); aMapIt.Next())
59f45b7c 124 {
bd6a8454 125 Standard_Integer& aSeqIdx = aMapIt.ChangeValue();
59f45b7c 126 if (aSeqIdx > aRemovePos)
127 aSeqIdx--;
128 }
bd6a8454 129
130 myDefaultLayerIndex = myLayerIds.Find (Graphic3d_ZLayerId_Default);
59f45b7c 131}
132
133//=======================================================================
134//function : AddStructure
135//purpose :
136//=======================================================================
137
a1954302 138void OpenGl_LayerList::AddStructure (const OpenGl_Structure* theStruct,
139 const Graphic3d_ZLayerId theLayerId,
140 const Standard_Integer thePriority,
141 Standard_Boolean isForChangePriority)
59f45b7c 142{
143 // add structure to associated layer,
144 // if layer doesn't exists, display structure in default layer
a1954302 145 Standard_Integer aSeqPos = myLayers.Lower();
146 myLayerIds.Find (theLayerId, aSeqPos);
59f45b7c 147
a1954302 148 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
149 aLayer.Add (theStruct, thePriority, isForChangePriority);
150 ++myNbStructures;
7c3ef2f7 151 if (aLayer.IsImmediate())
a1954302 152 {
153 ++myImmediateNbStructures;
154 }
e276548b 155
156 // Note: In ray-tracing mode we don't modify modification
157 // state here. It is redundant, because the possible changes
158 // will be handled in the loop for structures
59f45b7c 159}
160
161//=======================================================================
162//function : RemoveStructure
a1954302 163//purpose :
59f45b7c 164//=======================================================================
165
c357e426 166void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure)
59f45b7c 167{
c357e426 168 const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
a1954302 169
170 Standard_Integer aSeqPos = myLayers.Lower();
171 myLayerIds.Find (aLayerId, aSeqPos);
172
173 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
174 Standard_Integer aPriority = -1;
59f45b7c 175
176 // remove structure from associated list
177 // if the structure is not found there,
178 // scan through layers and remove it
c357e426 179 if (aLayer.Remove (theStructure, aPriority))
59f45b7c 180 {
a1954302 181 --myNbStructures;
7c3ef2f7 182 if (aLayer.IsImmediate())
a1954302 183 {
184 --myImmediateNbStructures;
185 }
e276548b 186
bd6a8454 187 if (aLayerId == Graphic3d_ZLayerId_Default
188 && theStructure->IsRaytracable())
e276548b 189 {
bd6a8454 190 ++myModifStateOfRaytraceable;
e276548b 191 }
e276548b 192
59f45b7c 193 return;
194 }
a1954302 195
59f45b7c 196 // scan through layers and remove it
197 Standard_Integer aSeqId = 1;
a1954302 198 for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
59f45b7c 199 {
a1954302 200 OpenGl_Layer& aLayerEx = anIts.ChangeValue();
59f45b7c 201 if (aSeqPos == aSeqId)
59f45b7c 202 {
a1954302 203 continue;
204 }
e276548b 205
c357e426 206 if (aLayerEx.Remove (theStructure, aPriority))
a1954302 207 {
208 --myNbStructures;
7c3ef2f7 209 if (aLayerEx.IsImmediate())
e276548b 210 {
a1954302 211 --myImmediateNbStructures;
e276548b 212 }
e276548b 213
bd6a8454 214 if (aSeqId == myDefaultLayerIndex
215 && theStructure->IsRaytracable())
a1954302 216 {
bd6a8454 217 ++myModifStateOfRaytraceable;
a1954302 218 }
59f45b7c 219 return;
220 }
221 }
222}
223
224//=======================================================================
b7cd4ba7 225//function : InvalidateBVHData
226//purpose :
227//=======================================================================
a1954302 228void OpenGl_LayerList::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
b7cd4ba7 229{
a1954302 230 Standard_Integer aSeqPos = myLayers.Lower();
231 myLayerIds.Find (theLayerId, aSeqPos);
232 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
233 aLayer.InvalidateBVHData();
b7cd4ba7 234}
235
236//=======================================================================
59f45b7c 237//function : ChangeLayer
238//purpose :
239//=======================================================================
240
a1954302 241void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure* theStructure,
242 const Graphic3d_ZLayerId theOldLayerId,
243 const Graphic3d_ZLayerId theNewLayerId)
59f45b7c 244{
a1954302 245 Standard_Integer aSeqPos = myLayers.Lower();
246 myLayerIds.Find (theOldLayerId, aSeqPos);
247 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
248 Standard_Integer aPriority = -1;
59f45b7c 249
250 // take priority and remove structure from list found by <theOldLayerId>
251 // if the structure is not found there, scan through all other layers
3fe9ce0e 252 if (aLayer.Remove (theStructure, aPriority, Standard_False))
59f45b7c 253 {
bd6a8454 254 if (theOldLayerId == Graphic3d_ZLayerId_Default
255 && theStructure->IsRaytracable())
256 {
257 ++myModifStateOfRaytraceable;
258 }
259
a1954302 260 --myNbStructures;
7c3ef2f7 261 if (aLayer.IsImmediate())
a1954302 262 {
263 --myImmediateNbStructures;
264 }
265
a0c20252 266 // isForChangePriority should be Standard_False below, because we want
267 // the BVH tree in the target layer to be updated with theStructure
268 AddStructure (theStructure, theNewLayerId, aPriority);
a1954302 269 return;
59f45b7c 270 }
a1954302 271
272 // scan through layers and remove it
273 Standard_Integer aSeqId = 1;
274 for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
59f45b7c 275 {
a1954302 276 if (aSeqPos == aSeqId)
59f45b7c 277 {
a1954302 278 continue;
279 }
59f45b7c 280
a1954302 281 // try to remove structure and get priority value from this layer
282 OpenGl_Layer& aLayerEx = anIts.ChangeValue();
283 if (aLayerEx.Remove (theStructure, aPriority, Standard_True))
284 {
bd6a8454 285 if (aSeqId == myDefaultLayerIndex
286 && theStructure->IsRaytracable())
287 {
288 ++myModifStateOfRaytraceable;
289 }
290
a1954302 291 --myNbStructures;
7c3ef2f7 292 if (aLayerEx.IsImmediate())
b7cd4ba7 293 {
a1954302 294 --myImmediateNbStructures;
b7cd4ba7 295 }
a1954302 296
297 // isForChangePriority should be Standard_False below, because we want
298 // the BVH tree in the target layer to be updated with theStructure
299 AddStructure (theStructure, theNewLayerId, aPriority);
300 return;
b7cd4ba7 301 }
302 }
303}
304
305//=======================================================================
306//function : ChangePriority
307//purpose :
308//=======================================================================
a1954302 309void OpenGl_LayerList::ChangePriority (const OpenGl_Structure* theStructure,
310 const Graphic3d_ZLayerId theLayerId,
311 const Standard_Integer theNewPriority)
b7cd4ba7 312{
a1954302 313 Standard_Integer aSeqPos = myLayers.Lower();
314 myLayerIds.Find (theLayerId, aSeqPos);
315 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
316 Standard_Integer anOldPriority = -1;
b7cd4ba7 317
a1954302 318 if (aLayer.Remove (theStructure, anOldPriority, Standard_True))
b7cd4ba7 319 {
a1954302 320 --myNbStructures;
7c3ef2f7 321 if (aLayer.IsImmediate())
a1954302 322 {
323 --myImmediateNbStructures;
324 }
325
b7cd4ba7 326 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
a1954302 327 return;
b7cd4ba7 328 }
a1954302 329
330 Standard_Integer aSeqId = 1;
331 for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
b7cd4ba7 332 {
a1954302 333 if (aSeqPos == aSeqId)
b7cd4ba7 334 {
a1954302 335 continue;
336 }
b7cd4ba7 337
a1954302 338 OpenGl_Layer& aLayerEx = anIts.ChangeValue();
339 if (aLayerEx.Remove (theStructure, anOldPriority, Standard_True))
340 {
341 --myNbStructures;
7c3ef2f7 342 if (aLayerEx.IsImmediate())
59f45b7c 343 {
a1954302 344 --myImmediateNbStructures;
59f45b7c 345 }
a1954302 346
347 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
348 return;
59f45b7c 349 }
350 }
351}
352
353//=======================================================================
a1954302 354//function : SetLayerSettings
355//purpose :
59f45b7c 356//=======================================================================
a1954302 357void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId theLayerId,
358 const Graphic3d_ZLayerSettings& theSettings)
359{
360 OpenGl_Layer& aLayer = Layer (theLayerId);
7c3ef2f7 361 if (aLayer.LayerSettings().IsImmediate() != theSettings.IsImmediate())
a1954302 362 {
7c3ef2f7 363 if (theSettings.IsImmediate())
a1954302 364 {
365 myImmediateNbStructures += aLayer.NbStructures();
366 }
367 else
368 {
369 myImmediateNbStructures -= aLayer.NbStructures();
370 }
371 }
372 aLayer.SetLayerSettings (theSettings);
373}
59f45b7c 374
a1954302 375//=======================================================================
376//function : Render
377//purpose :
378//=======================================================================
379void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
91c60b57 380 const Standard_Boolean theToDrawImmediate,
381 const OpenGl_LayerFilter theLayersToProcess) const
59f45b7c 382{
550f3b8b 383 OpenGl_GlobalLayerSettings aDefaultSettings;
c5751993 384
a1954302 385 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
386 aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC, &aDefaultSettings.DepthFunc);
387 aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aDefaultSettings.DepthMask);
388
bd6a8454 389 Standard_Integer aSeqId = myLayers.Lower();
b3eab8ef 390 bool toClearDepth = false;
a1954302 391 for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
59f45b7c 392 {
91c60b57 393 if (theLayersToProcess == OpenGl_LF_Bottom)
394 {
bd6a8454 395 if (aSeqId >= myDefaultLayerIndex) continue;
91c60b57 396 }
397 else if (theLayersToProcess == OpenGl_LF_Upper)
398 {
bd6a8454 399 if (aSeqId <= myDefaultLayerIndex) continue;
91c60b57 400 }
401 else if (theLayersToProcess == OpenGl_LF_Default)
402 {
bd6a8454 403 if (aSeqId != myDefaultLayerIndex) continue;
91c60b57 404 }
405
a1954302 406 const OpenGl_Layer& aLayer = anIts.Value();
b3eab8ef 407 if (aLayer.IsImmediate() != theToDrawImmediate)
a1954302 408 {
409 continue;
410 }
b3eab8ef 411 else if (aLayer.NbStructures() < 1)
59f45b7c 412 {
b3eab8ef 413 // make sure to clear depth of previous layers even if layer has no structures
414 toClearDepth = toClearDepth || aLayer.LayerSettings().ToClearDepth();
415 continue;
59f45b7c 416 }
b3eab8ef 417
418 // depth buffers
419 if (toClearDepth
420 || aLayer.LayerSettings().ToClearDepth())
a1954302 421 {
b3eab8ef 422 toClearDepth = false;
423 glDepthMask (GL_TRUE);
424 glClear (GL_DEPTH_BUFFER_BIT);
a1954302 425 }
426
a1954302 427 aLayer.Render (theWorkspace, aDefaultSettings);
59f45b7c 428 }
550f3b8b 429
b3eab8ef 430 if (toClearDepth)
431 {
432 glDepthMask (GL_TRUE);
433 glClear (GL_DEPTH_BUFFER_BIT);
434 }
435
a1954302 436 aCtx->core11fwd->glDepthMask (aDefaultSettings.DepthMask);
437 aCtx->core11fwd->glDepthFunc (aDefaultSettings.DepthFunc);
59f45b7c 438}