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_GlCore11.hxx>
18 #include <OpenGl_LayerList.hxx>
19 #include <OpenGl_Structure.hxx>
20 #include <OpenGl_Workspace.hxx>
22 #include <Graphic3d_GraphicDriver.hxx>
24 //=======================================================================
25 //function : OpenGl_LayerList
26 //purpose : Constructor
27 //=======================================================================
29 OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
30 : myDefaultLayerIndex (0),
31 myNbPriorities (theNbPriorities),
33 myImmediateNbStructures (0),
34 myModifStateOfRaytraceable (0)
36 // insert default priority layers
37 myLayers.Append (OpenGl_Layer (myNbPriorities));
38 myLayerIds.Bind (Graphic3d_ZLayerId_BotOSD, myLayers.Upper());
40 myLayers.Append (OpenGl_Layer (myNbPriorities));
41 myLayerIds.Bind (Graphic3d_ZLayerId_Default, myLayers.Upper());
43 myLayers.Append (OpenGl_Layer (myNbPriorities));
44 myLayerIds.Bind (Graphic3d_ZLayerId_Top, myLayers.Upper());
46 myLayers.Append (OpenGl_Layer (myNbPriorities));
47 myLayerIds.Bind (Graphic3d_ZLayerId_Topmost, myLayers.Upper());
49 myLayers.Append (OpenGl_Layer (myNbPriorities));
50 myLayerIds.Bind (Graphic3d_ZLayerId_TopOSD, myLayers.Upper());
52 myDefaultLayerIndex = myLayerIds.Find (Graphic3d_ZLayerId_Default);
55 //=======================================================================
56 //function : ~OpenGl_LayerList
57 //purpose : Destructor
58 //=======================================================================
60 OpenGl_LayerList::~OpenGl_LayerList()
64 //=======================================================================
67 //=======================================================================
69 void OpenGl_LayerList::AddLayer (const Graphic3d_ZLayerId theLayerId)
71 if (myLayerIds.IsBound (theLayerId))
77 myLayers.Append (OpenGl_Layer (myNbPriorities));
78 myLayerIds.Bind (theLayerId, myLayers.Length());
81 //=======================================================================
84 //=======================================================================
85 OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId)
87 return myLayers.ChangeValue (myLayerIds.Find (theLayerId));
90 //=======================================================================
93 //=======================================================================
94 const OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId) const
96 return myLayers.Value (myLayerIds.Find (theLayerId));
99 //=======================================================================
100 //function : RemoveLayer
102 //=======================================================================
104 void OpenGl_LayerList::RemoveLayer (const Graphic3d_ZLayerId theLayerId)
106 if (!myLayerIds.IsBound (theLayerId)
112 const Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
114 // move all displayed structures to first layer
115 const OpenGl_Layer& aLayerToMove = myLayers.Value (aRemovePos);
116 myLayers.ChangeFirst().Append (aLayerToMove);
119 myLayers.Remove (aRemovePos);
120 myLayerIds.UnBind (theLayerId);
122 // updated sequence indexes in map
123 for (OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds); aMapIt.More(); aMapIt.Next())
125 Standard_Integer& aSeqIdx = aMapIt.ChangeValue();
126 if (aSeqIdx > aRemovePos)
130 myDefaultLayerIndex = myLayerIds.Find (Graphic3d_ZLayerId_Default);
133 //=======================================================================
134 //function : AddStructure
136 //=======================================================================
138 void OpenGl_LayerList::AddStructure (const OpenGl_Structure* theStruct,
139 const Graphic3d_ZLayerId theLayerId,
140 const Standard_Integer thePriority,
141 Standard_Boolean isForChangePriority)
143 // add structure to associated layer,
144 // if layer doesn't exists, display structure in default layer
145 Standard_Integer aSeqPos = myLayers.Lower();
146 myLayerIds.Find (theLayerId, aSeqPos);
148 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
149 aLayer.Add (theStruct, thePriority, isForChangePriority);
151 if (aLayer.LayerSettings().IsImmediate)
153 ++myImmediateNbStructures;
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
161 //=======================================================================
162 //function : RemoveStructure
164 //=======================================================================
166 void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure)
168 const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
170 Standard_Integer aSeqPos = myLayers.Lower();
171 myLayerIds.Find (aLayerId, aSeqPos);
173 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
174 Standard_Integer aPriority = -1;
176 // remove structure from associated list
177 // if the structure is not found there,
178 // scan through layers and remove it
179 if (aLayer.Remove (theStructure, aPriority))
182 if (aLayer.LayerSettings().IsImmediate)
184 --myImmediateNbStructures;
187 if (aLayerId == Graphic3d_ZLayerId_Default
188 && theStructure->IsRaytracable())
190 ++myModifStateOfRaytraceable;
196 // scan through layers and remove it
197 Standard_Integer aSeqId = 1;
198 for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
200 OpenGl_Layer& aLayerEx = anIts.ChangeValue();
201 if (aSeqPos == aSeqId)
206 if (aLayerEx.Remove (theStructure, aPriority))
209 if (aLayerEx.LayerSettings().IsImmediate)
211 --myImmediateNbStructures;
214 if (aSeqId == myDefaultLayerIndex
215 && theStructure->IsRaytracable())
217 ++myModifStateOfRaytraceable;
224 //=======================================================================
225 //function : InvalidateBVHData
227 //=======================================================================
228 void OpenGl_LayerList::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
230 Standard_Integer aSeqPos = myLayers.Lower();
231 myLayerIds.Find (theLayerId, aSeqPos);
232 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
233 aLayer.InvalidateBVHData();
236 //=======================================================================
237 //function : ChangeLayer
239 //=======================================================================
241 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure* theStructure,
242 const Graphic3d_ZLayerId theOldLayerId,
243 const Graphic3d_ZLayerId theNewLayerId)
245 Standard_Integer aSeqPos = myLayers.Lower();
246 myLayerIds.Find (theOldLayerId, aSeqPos);
247 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
248 Standard_Integer aPriority = -1;
250 // take priority and remove structure from list found by <theOldLayerId>
251 // if the structure is not found there, scan through all other layers
252 if (aLayer.Remove (theStructure, aPriority, Standard_False))
254 if (theOldLayerId == Graphic3d_ZLayerId_Default
255 && theStructure->IsRaytracable())
257 ++myModifStateOfRaytraceable;
261 if (aLayer.LayerSettings().IsImmediate)
263 --myImmediateNbStructures;
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);
272 // scan through layers and remove it
273 Standard_Integer aSeqId = 1;
274 for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
276 if (aSeqPos == aSeqId)
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))
285 if (aSeqId == myDefaultLayerIndex
286 && theStructure->IsRaytracable())
288 ++myModifStateOfRaytraceable;
292 if (aLayerEx.LayerSettings().IsImmediate)
294 --myImmediateNbStructures;
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);
305 //=======================================================================
306 //function : ChangePriority
308 //=======================================================================
309 void OpenGl_LayerList::ChangePriority (const OpenGl_Structure* theStructure,
310 const Graphic3d_ZLayerId theLayerId,
311 const Standard_Integer theNewPriority)
313 Standard_Integer aSeqPos = myLayers.Lower();
314 myLayerIds.Find (theLayerId, aSeqPos);
315 OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
316 Standard_Integer anOldPriority = -1;
318 if (aLayer.Remove (theStructure, anOldPriority, Standard_True))
321 if (aLayer.LayerSettings().IsImmediate)
323 --myImmediateNbStructures;
326 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
330 Standard_Integer aSeqId = 1;
331 for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
333 if (aSeqPos == aSeqId)
338 OpenGl_Layer& aLayerEx = anIts.ChangeValue();
339 if (aLayerEx.Remove (theStructure, anOldPriority, Standard_True))
342 if (aLayerEx.LayerSettings().IsImmediate)
344 --myImmediateNbStructures;
347 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
353 //=======================================================================
354 //function : SetLayerSettings
356 //=======================================================================
357 void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId theLayerId,
358 const Graphic3d_ZLayerSettings& theSettings)
360 OpenGl_Layer& aLayer = Layer (theLayerId);
361 if (aLayer.LayerSettings().IsImmediate != theSettings.IsImmediate)
363 if (theSettings.IsImmediate)
365 myImmediateNbStructures += aLayer.NbStructures();
369 myImmediateNbStructures -= aLayer.NbStructures();
372 aLayer.SetLayerSettings (theSettings);
375 //=======================================================================
378 //=======================================================================
379 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
380 const Standard_Boolean theToDrawImmediate,
381 const OpenGl_LayerFilter theLayersToProcess) const
383 OpenGl_GlobalLayerSettings aDefaultSettings;
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);
389 Standard_Integer aSeqId = myLayers.Lower();
390 for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
392 if (theLayersToProcess == OpenGl_LF_Bottom)
394 if (aSeqId >= myDefaultLayerIndex) continue;
396 else if (theLayersToProcess == OpenGl_LF_Upper)
398 if (aSeqId <= myDefaultLayerIndex) continue;
400 else if (theLayersToProcess == OpenGl_LF_Default)
402 if (aSeqId != myDefaultLayerIndex) continue;
405 const OpenGl_Layer& aLayer = anIts.Value();
406 if (aLayer.NbStructures() < 1)
410 else if (theToDrawImmediate)
412 if (!aLayer.LayerSettings().IsImmediate)
419 if (aLayer.LayerSettings().IsImmediate)
426 aLayer.Render (theWorkspace, aDefaultSettings);
429 aCtx->core11fwd->glDepthMask (aDefaultSettings.DepthMask);
430 aCtx->core11fwd->glDepthFunc (aDefaultSettings.DepthFunc);