0024070: OpenGL capped object-level clipping planes
[occt.git] / src / OpenGl / OpenGl_Group.cxx
1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 #include <OpenGl_Group.hxx>
21
22 #include <OpenGl_PrimitiveArray.hxx>
23 #include <OpenGl_Workspace.hxx>
24
25 // =======================================================================
26 // function : OpenGl_Group
27 // purpose  :
28 // =======================================================================
29 OpenGl_Group::OpenGl_Group ()
30 : myAspectLine(NULL),
31   myAspectFace(NULL),
32   myAspectMarker(NULL),
33   myAspectText(NULL),
34   myFirst(NULL), myLast(NULL)
35 {
36 }
37
38 // =======================================================================
39 // function : ~OpenGl_Group
40 // purpose  :
41 // =======================================================================
42 OpenGl_Group::~OpenGl_Group()
43 {
44   Release (Handle(OpenGl_Context)());
45 }
46
47 // =======================================================================
48 // function : SetAspectLine
49 // purpose  :
50 // =======================================================================
51 void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theContext,
52                                   const Standard_Boolean theIsGlobal)
53 {
54   if (theIsGlobal || myFirst == NULL)
55   {
56     if (myAspectLine == NULL)
57       myAspectLine = new OpenGl_AspectLine();
58     myAspectLine->SetContext (theContext);
59   }
60   else
61   {
62     OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
63     anAspectLine->SetContext (theContext);
64     AddElement (TelNil/*TelAspectLine*/, anAspectLine);
65   }
66 }
67
68 // =======================================================================
69 // function : SetAspectFace
70 // purpose  :
71 // =======================================================================
72 void OpenGl_Group::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
73                                   const CALL_DEF_CONTEXTFILLAREA& theAspect,
74                                   const Standard_Boolean          theIsGlobal)
75 {
76   if (theIsGlobal || myFirst == NULL)
77   {
78     if (myAspectFace == NULL)
79     {
80       myAspectFace = new OpenGl_AspectFace();
81     }
82     myAspectFace->Init (theCtx, theAspect);
83   }
84   else
85   {
86     OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
87     anAspectFace->Init (theCtx, theAspect);
88     AddElement (TelNil/*TelAspectFace*/, anAspectFace);
89   }
90 }
91
92 // =======================================================================
93 // function : SetAspectMarker
94 // purpose  :
95 // =======================================================================
96 void OpenGl_Group::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
97                                     const CALL_DEF_CONTEXTMARKER& theAspect,
98                                     const Standard_Boolean theIsGlobal)
99 {
100   if (theIsGlobal || myFirst == NULL)
101   {
102     if (myAspectMarker == NULL)
103     {
104       myAspectMarker = new OpenGl_AspectMarker();
105     }
106     myAspectMarker->Init (theCtx, theAspect);
107   }
108   else
109   {
110     OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
111     anAspectMarker->Init (theCtx, theAspect);
112     AddElement (TelNil/*TelAspectMarker*/, anAspectMarker);
113   }
114 }
115
116 // =======================================================================
117 // function : SetAspectText
118 // purpose  :
119 // =======================================================================
120 void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theContext,
121                                   const Standard_Boolean theIsGlobal)
122 {
123   if (theIsGlobal || myFirst == NULL)
124   {
125     if (myAspectText == NULL)
126       myAspectText = new OpenGl_AspectText();
127     myAspectText->SetContext (theContext);
128   }
129   else
130   {
131     OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
132     anAspectText->SetContext (theContext);
133     AddElement ( TelNil/*TelAspectText*/, anAspectText);
134   }
135 }
136
137 // =======================================================================
138 // function : AddElement
139 // purpose  :
140 // =======================================================================
141 void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem )
142 {
143   OpenGl_ElementNode *node = new OpenGl_ElementNode();
144
145   node->type = AType;
146   node->elem = AElem;
147   node->next = NULL;
148   (myLast? myLast->next : myFirst) = node;
149   myLast = node;
150 }
151
152 // =======================================================================
153 // function : Render
154 // purpose  :
155 // =======================================================================
156 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
157 {
158   // Is rendering in ADD or IMMEDIATE mode?
159   const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
160   const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
161
162   // Setup aspects
163   const OpenGl_AspectLine*   aBackAspectLine   = theWorkspace->AspectLine   (Standard_False);
164   const OpenGl_AspectFace*   aBackAspectFace   = theWorkspace->AspectFace   (Standard_False);
165   const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
166   const OpenGl_AspectText*   aBackAspectText   = theWorkspace->AspectText   (Standard_False);
167   Standard_Boolean isLineSet   = myAspectLine   && myAspectLine->RenderFiltered (theWorkspace, aFilter);
168   Standard_Boolean isFaceSet   = myAspectFace   && myAspectFace->RenderFiltered (theWorkspace, aFilter);
169   Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
170   Standard_Boolean isTextSet   = myAspectText   && myAspectText->RenderFiltered (theWorkspace, aFilter);
171
172   // Render group elements
173   for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
174   {
175     switch (aNodeIter->type)
176     {
177       case TelMarker:
178       case TelMarkerSet:
179       case TelText:
180       {
181         glDisable (GL_LIGHTING);
182         if (isImmediate)
183         {
184           glDepthMask (GL_FALSE);
185         }
186
187         aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
188         break;
189       }
190       default:
191       {
192         aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
193         break;
194       }
195     }
196   }
197
198   // Restore aspects
199   if (isLineSet)
200     theWorkspace->SetAspectLine (aBackAspectLine);
201   if (isFaceSet)
202     theWorkspace->SetAspectFace (aBackAspectFace);
203   if (isMarkerSet)
204     theWorkspace->SetAspectMarker (aBackAspectMarker);
205   if (isTextSet)
206     theWorkspace->SetAspectText (aBackAspectText);
207 }
208
209 // =======================================================================
210 // function : Release
211 // purpose  :
212 // =======================================================================
213 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
214 {
215   // Delete elements
216   while (myFirst != NULL)
217   {
218     OpenGl_ElementNode* aNext = myFirst->next;
219     OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
220     delete myFirst;
221     myFirst = aNext;
222   }
223   myLast = NULL;
224
225   OpenGl_Element::Destroy (theGlCtx, myAspectLine);
226   OpenGl_Element::Destroy (theGlCtx, myAspectFace);
227   OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
228   OpenGl_Element::Destroy (theGlCtx, myAspectText);
229 }