266d0960352aaf284447eb20d7041992f659b182
[occt.git] / src / OpenGl / OpenGl_Group.cxx
1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-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
8 // under the terms of the GNU Lesser General Public 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_Group.hxx>
21 #include <OpenGl_PrimitiveArray.hxx>
22 #include <OpenGl_Structure.hxx>
23 #include <OpenGl_Workspace.hxx>
24
25 // =======================================================================
26 // function : OpenGl_Group
27 // purpose  :
28 // =======================================================================
29 #ifndef HAVE_OPENCL
30 OpenGl_Group::OpenGl_Group()
31 #else
32 OpenGl_Group::OpenGl_Group (const OpenGl_Structure* theAncestorStructure)
33 #endif
34 : myAspectLine(NULL),
35   myAspectFace(NULL),
36   myAspectMarker(NULL),
37   myAspectText(NULL),
38   myFirst(NULL),
39   myLast(NULL)
40 {
41 #ifdef HAVE_OPENCL
42   myAncestorStructure = theAncestorStructure;
43   myIsRaytracable = Standard_False;
44   myModificationState = 0; // initial state
45 #endif
46 }
47
48 // =======================================================================
49 // function : ~OpenGl_Group
50 // purpose  :
51 // =======================================================================
52 OpenGl_Group::~OpenGl_Group()
53 {
54   Release (Handle(OpenGl_Context)());
55 }
56
57 // =======================================================================
58 // function : SetAspectLine
59 // purpose  :
60 // =======================================================================
61 void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theAspect,
62                                   const Standard_Boolean theIsGlobal)
63 {
64   if (theIsGlobal || myFirst == NULL)
65   {
66     if (myAspectLine == NULL)
67     {
68       myAspectLine = new OpenGl_AspectLine();
69     }
70     myAspectLine->SetAspect (theAspect);
71   }
72   else
73   {
74     OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
75     anAspectLine->SetAspect (theAspect);
76     AddElement (TelNil/*TelAspectLine*/, anAspectLine);
77   }
78 }
79
80 // =======================================================================
81 // function : SetAspectFace
82 // purpose  :
83 // =======================================================================
84 void OpenGl_Group::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect,
85                                   const Standard_Boolean          theIsGlobal)
86 {
87   if (theIsGlobal || myFirst == NULL)
88   {
89     if (myAspectFace == NULL)
90     {
91       myAspectFace = new OpenGl_AspectFace();
92     }
93     myAspectFace->SetAspect (theAspect);
94   }
95   else
96   {
97     OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
98     anAspectFace->SetAspect (theAspect);
99     AddElement (TelNil/*TelAspectFace*/, anAspectFace);
100   }
101
102 #ifdef HAVE_OPENCL
103   if (myIsRaytracable)
104   {
105     myModificationState++;
106
107     if (myAncestorStructure != NULL)
108     {
109       myAncestorStructure->UpdateStateWithAncestorStructures();
110     }
111   }
112 #endif
113 }
114
115 // =======================================================================
116 // function : SetAspectMarker
117 // purpose  :
118 // =======================================================================
119 void OpenGl_Group::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect,
120                                     const Standard_Boolean theIsGlobal)
121 {
122   if (theIsGlobal || myFirst == NULL)
123   {
124     if (myAspectMarker == NULL)
125     {
126       myAspectMarker = new OpenGl_AspectMarker();
127     }
128     myAspectMarker->SetAspect (theAspect);
129   }
130   else
131   {
132     OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
133     anAspectMarker->SetAspect (theAspect);
134     AddElement (TelNil/*TelAspectMarker*/, anAspectMarker);
135   }
136 }
137
138 // =======================================================================
139 // function : SetAspectText
140 // purpose  :
141 // =======================================================================
142 void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theAspect,
143                                   const Standard_Boolean theIsGlobal)
144 {
145   if (theIsGlobal || myFirst == NULL)
146   {
147     if (myAspectText == NULL)
148     {
149       myAspectText = new OpenGl_AspectText();
150     }
151     myAspectText->SetAspect (theAspect);
152   }
153   else
154   {
155     OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
156     anAspectText->SetAspect (theAspect);
157     AddElement ( TelNil/*TelAspectText*/, anAspectText);
158   }
159 }
160
161 // =======================================================================
162 // function : AddElement
163 // purpose  :
164 // =======================================================================
165 void OpenGl_Group::AddElement (const TelType theType, OpenGl_Element *theElem)
166 {
167   OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
168
169   aNode->type = theType;
170   aNode->elem = theElem;
171   aNode->next = NULL;
172   (myLast? myLast->next : myFirst) = aNode;
173   myLast = aNode;
174
175 #ifdef HAVE_OPENCL
176   if (OpenGl_Raytrace::IsRaytracedElement (aNode))
177   {
178     myModificationState++;
179     myIsRaytracable = Standard_True;
180
181     if (myAncestorStructure != NULL)
182     {
183       myAncestorStructure->UpdateStateWithAncestorStructures();
184       myAncestorStructure->SetRaytracableWithAncestorStructures();
185     }
186   }
187 #endif
188 }
189
190 // =======================================================================
191 // function : Render
192 // purpose  :
193 // =======================================================================
194 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
195 {
196   // Is rendering in ADD or IMMEDIATE mode?
197   const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
198   const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
199
200   // Setup aspects
201   const OpenGl_AspectLine*   aBackAspectLine   = theWorkspace->AspectLine   (Standard_False);
202   const OpenGl_AspectFace*   aBackAspectFace   = theWorkspace->AspectFace   (Standard_False);
203   const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
204   const OpenGl_AspectText*   aBackAspectText   = theWorkspace->AspectText   (Standard_False);
205   Standard_Boolean isLineSet   = myAspectLine   && myAspectLine->RenderFiltered (theWorkspace, aFilter);
206   Standard_Boolean isFaceSet   = myAspectFace   && myAspectFace->RenderFiltered (theWorkspace, aFilter);
207   Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
208   Standard_Boolean isTextSet   = myAspectText   && myAspectText->RenderFiltered (theWorkspace, aFilter);
209
210   // Render group elements
211   for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
212   {
213     switch (aNodeIter->type)
214     {
215       case TelMarker:
216       case TelMarkerSet:
217       case TelText:
218       {
219         glDisable (GL_LIGHTING);
220         if (isImmediate)
221         {
222           glDepthMask (GL_FALSE);
223         }
224
225         aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
226         break;
227       }
228       default:
229       {
230         aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
231         break;
232       }
233     }
234   }
235
236   // Restore aspects
237   if (isLineSet)
238     theWorkspace->SetAspectLine (aBackAspectLine);
239   if (isFaceSet)
240     theWorkspace->SetAspectFace (aBackAspectFace);
241   if (isMarkerSet)
242     theWorkspace->SetAspectMarker (aBackAspectMarker);
243   if (isTextSet)
244     theWorkspace->SetAspectText (aBackAspectText);
245 }
246
247 // =======================================================================
248 // function : Release
249 // purpose  :
250 // =======================================================================
251 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
252 {
253   // Delete elements
254   while (myFirst != NULL)
255   {
256     OpenGl_ElementNode* aNext = myFirst->next;
257     OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
258     delete myFirst;
259     myFirst = aNext;
260   }
261   myLast = NULL;
262
263   OpenGl_Element::Destroy (theGlCtx, myAspectLine);
264   OpenGl_Element::Destroy (theGlCtx, myAspectFace);
265   OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
266   OpenGl_Element::Destroy (theGlCtx, myAspectText);
267 }