b80d9d6b1b851f7f876ecf70929bcda224c4673d
[occt.git] / src / OpenGl / OpenGl_LayerList.cxx
1 // Created on: 2012-02-02
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifdef HAVE_CONFIG_H
17   #include <config.h>
18 #endif
19
20 #include <OpenGl_GlCore11.hxx>
21
22 #include <OpenGl_LayerList.hxx>
23 #include <OpenGl_Structure.hxx>
24
25 #include <InterfaceGraphic_Graphic3d.hxx>
26 #include <InterfaceGraphic.hxx>
27
28 //=======================================================================
29 //function : OpenGl_LayerList
30 //purpose  : Constructor
31 //=======================================================================
32
33 OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
34  : myNbPriorities (theNbPriorities),
35    myNbStructures (0)
36 {
37   // insert default priority layer
38   myLayers.Append (OpenGl_PriorityList (myNbPriorities));
39   myLayerIds.Bind (0, myLayers.Length());
40 }
41
42 //=======================================================================
43 //function : ~OpenGl_LayerList
44 //purpose  : Destructor
45 //=======================================================================
46
47 OpenGl_LayerList::~OpenGl_LayerList ()
48 {
49 }
50
51 //=======================================================================
52 //function : defaultLayer
53 //purpose  :
54 //=======================================================================
55
56 OpenGl_PriorityList& OpenGl_LayerList::defaultLayer()
57 {
58   return myLayers.ChangeValue (1);
59 }
60
61 //=======================================================================
62 //function : NbPriorities
63 //purpose  : Method returns the number of available priorities
64 //=======================================================================
65
66 Standard_Integer OpenGl_LayerList::NbPriorities () const
67 {
68   return myNbPriorities;
69 }
70
71 //=======================================================================
72 //function : NbStructures
73 //purpose  : Method returns the number of available structures
74 //=======================================================================
75
76 Standard_Integer OpenGl_LayerList::NbStructures () const
77 {
78   return myNbStructures;
79 }
80
81 //=======================================================================
82 //function : AddLayer
83 //purpose  : 
84 //=======================================================================
85
86 void OpenGl_LayerList::AddLayer (const Standard_Integer theLayerId)
87 {
88   if (HasLayer (theLayerId))
89     return;
90
91   // add the new layer
92   myLayers.Append (OpenGl_PriorityList (myNbPriorities));
93   myLayerIds.Bind (theLayerId, myLayers.Length());
94 }
95
96 //=======================================================================
97 //function : HasLayer
98 //purpose  : 
99 //=======================================================================
100
101 Standard_Boolean OpenGl_LayerList::HasLayer 
102   (const Standard_Integer theLayerId) const
103 {
104   return myLayerIds.IsBound (theLayerId);
105 }
106
107 //=======================================================================
108 //function : RemoveLayer
109 //purpose  :
110 //=======================================================================
111
112 void OpenGl_LayerList::RemoveLayer (const Standard_Integer theLayerId)
113 {
114   if (!HasLayer (theLayerId) || theLayerId == 0)
115     return;
116
117   Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
118   
119   // move all displayed structures to first layer
120   const OpenGl_PriorityList& aList = myLayers.Value (aRemovePos);
121   defaultLayer ().Append (aList);
122
123   // remove layer
124   myLayers.Remove (aRemovePos);
125   myLayerIds.UnBind (theLayerId);
126
127   // updated sequence indexes in map
128   OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds);
129   for ( ; aMapIt.More (); aMapIt.Next ())
130   {
131     Standard_Integer& aSeqIdx = aMapIt.ChangeValue ();
132     if (aSeqIdx > aRemovePos)
133       aSeqIdx--;
134   }
135 }
136
137 //=======================================================================
138 //function : AddStructure
139 //purpose  :
140 //=======================================================================
141
142 void OpenGl_LayerList::AddStructure (const OpenGl_Structure *theStructure,
143                                      const Standard_Integer  theLayerId,
144                                      const Standard_Integer  thePriority)
145 {
146   // add structure to associated layer,
147   // if layer doesn't exists, display structure in default layer
148   OpenGl_PriorityList& aList = !HasLayer (theLayerId) ? defaultLayer () :
149     myLayers.ChangeValue (myLayerIds.Find (theLayerId));
150
151   aList.Add (theStructure, thePriority);
152   myNbStructures++;
153
154   // Note: In ray-tracing mode we don't modify modification
155   // state here. It is redundant, because the possible changes
156   // will be handled in the loop for structures
157 }
158
159 //=======================================================================
160 //function : RemoveStructure
161 //purpose  : 
162 //=======================================================================
163
164 void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure *theStructure,
165                                         const Standard_Integer  theLayerId)
166 {
167   Standard_Integer aSeqPos = !HasLayer (theLayerId) ?
168     1 : myLayerIds.Find (theLayerId);
169   
170   OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos);
171
172   // remove structure from associated list
173   // if the structure is not found there,
174   // scan through layers and remove it
175   if (aList.Remove (theStructure) >= 0)
176   {
177     myNbStructures--;
178
179 #ifdef HAVE_OPENCL
180     if (theStructure->IsRaytracable())
181     {
182       myModificationState++;
183     }
184 #endif
185
186     return;
187   }
188   
189   // scan through layers and remove it
190   Standard_Integer aSeqId = 1;
191   OpenGl_SequenceOfLayers::Iterator anIts;
192   for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
193   {
194     OpenGl_PriorityList& aScanList = anIts.ChangeValue ();
195     if (aSeqPos == aSeqId)
196       continue;
197   
198     if (aScanList.Remove (theStructure) >= 0)
199     {
200       myNbStructures--;
201
202 #ifdef HAVE_OPENCL
203       if (theStructure->IsRaytracable())
204       {
205         myModificationState++;
206       }
207 #endif
208
209       return;
210     }
211   }
212 }
213
214 //=======================================================================
215 //function : ChangeLayer
216 //purpose  :
217 //=======================================================================
218
219 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure *theStructure,
220                                     const Standard_Integer  theOldLayerId,
221                                     const Standard_Integer  theNewLayerId)
222 {
223   Standard_Integer aSeqPos = !HasLayer (theOldLayerId) ?
224     1 : myLayerIds.Find (theOldLayerId);
225   
226   OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos);
227   Standard_Integer aPriority;
228
229   // take priority and remove structure from list found by <theOldLayerId>
230   // if the structure is not found there, scan through all other layers
231   if ((aPriority = aList.Remove (theStructure)) >= 0)
232   {
233     myNbStructures--;
234     AddStructure (theStructure, theNewLayerId, aPriority);
235   }
236   else
237   {
238     // scan through layers and remove it
239     Standard_Integer aSeqId = 1;
240     OpenGl_SequenceOfLayers::Iterator anIts;
241     for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
242     {
243       if (aSeqPos == aSeqId)
244         continue;
245   
246       // try to remove structure and get priority value from this layer
247       if ((aPriority = aList.Remove (theStructure)) >= 0)
248       {
249         myNbStructures--;
250         AddStructure (theStructure, theNewLayerId, aPriority);
251         break;
252       }
253     }
254   }
255 }
256
257 //=======================================================================
258 //function : Render
259 //purpose  : Render this element
260 //=======================================================================
261
262 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
263 {
264   OpenGl_SequenceOfLayers::Iterator anIts;
265   for(anIts.Init (myLayers); anIts.More (); anIts.Next ())
266   {
267     const OpenGl_PriorityList& aList = anIts.Value ();
268     if (aList.NbStructures () > 0)
269     {
270       // separate depth buffers
271       glClear (GL_DEPTH_BUFFER_BIT);
272
273       // render priority list
274       aList.Render (theWorkspace);
275     }
276   }
277 }