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