0022819: Redesign of OpenGl driver
[occt.git] / src / OpenGl / OpenGl_Group.cxx
CommitLineData
2166f0fa
SK
1// File: OpenGl_Group.cxx
2// Created: 1 August 2011
3// Author: Sergey ZERCHANINOV
4// Copyright: OPEN CASCADE 2011
5
6#include <OpenGl_Group.hxx>
7
8#include <OpenGl_TextureBox.hxx>
9#include <OpenGl_PrimitiveArray.hxx>
10
11/*----------------------------------------------------------------------*/
12
13OpenGl_Group::OpenGl_Group ()
14: myAspectLine(NULL),
15 myAspectFace(NULL),
16 myAspectMarker(NULL),
17 myAspectText(NULL),
18 myFirst(NULL), myLast(NULL)
19{
20}
21
22OpenGl_Group::~OpenGl_Group()
23{
24 Clear();
25}
26
27/*----------------------------------------------------------------------*/
28
29void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theContext,
30 const Standard_Boolean theIsGlobal)
31{
32 if (theIsGlobal || myFirst == NULL)
33 {
34 if (myAspectLine == NULL)
35 myAspectLine = new OpenGl_AspectLine();
36 myAspectLine->SetContext (theContext);
37 }
38 else
39 {
40 OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
41 anAspectLine->SetContext (theContext);
42 AddElement (TelNil/*TelAspectLine*/, anAspectLine);
43 }
44}
45
46/*----------------------------------------------------------------------*/
47
48void OpenGl_Group::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theContext,
49 const Standard_Boolean theIsGlobal)
50{
51 if (theIsGlobal || myFirst == NULL)
52 {
53 if (myAspectFace == NULL)
54 myAspectFace = new OpenGl_AspectFace();
55 myAspectFace->SetContext (theContext);
56 }
57 else
58 {
59 OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
60 anAspectFace->SetContext (theContext);
61 AddElement (TelNil/*TelAspectFace*/, anAspectFace);
62 }
63}
64
65/*----------------------------------------------------------------------*/
66
67void OpenGl_Group::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theContext,
68 const Standard_Boolean theIsGlobal)
69{
70 if (theIsGlobal || myFirst == NULL)
71 {
72 if (myAspectMarker == NULL)
73 myAspectMarker = new OpenGl_AspectMarker();
74 myAspectMarker->SetContext (theContext);
75 }
76 else
77 {
78 OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
79 anAspectMarker->SetContext (theContext);
80 AddElement (TelNil/*TelAspectMarker*/, anAspectMarker);
81 }
82}
83
84/*----------------------------------------------------------------------*/
85
86void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theContext,
87 const Standard_Boolean theIsGlobal)
88{
89 if (theIsGlobal || myFirst == NULL)
90 {
91 if (myAspectText == NULL)
92 myAspectText = new OpenGl_AspectText();
93 myAspectText->SetContext (theContext);
94 }
95 else
96 {
97 OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
98 anAspectText->SetContext (theContext);
99 AddElement ( TelNil/*TelAspectText*/, anAspectText);
100 }
101}
102
103/*----------------------------------------------------------------------*/
104
105void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem )
106{
107 OpenGl_ElementNode *node = new OpenGl_ElementNode();
108
109 node->type = AType;
110 node->elem = AElem;
111 node->next = NULL;
112 (myLast? myLast->next : myFirst) = node;
113 myLast = node;
114}
115
116/*----------------------------------------------------------------------*/
117
118void OpenGl_Group::Clear ()
119{
120 if (myAspectLine)
121 {
122 // Delete line context
123 delete myAspectLine;
124 myAspectLine = NULL;
125 }
126 if (myAspectFace)
127 {
128 // Delete face context
129 delete myAspectFace;
130 myAspectFace = NULL;
131 }
132 if (myAspectMarker)
133 {
134 // Delete marker context
135 delete myAspectMarker;
136 myAspectMarker = NULL;
137 }
138 if (myAspectText)
139 {
140 // Delete text context
141 delete myAspectText;
142 myAspectText = NULL;
143 }
144 // Delete elements
145 while (myFirst)
146 {
147 OpenGl_ElementNode *next = myFirst->next;
148 delete myFirst->elem;
149 delete myFirst;
150 myFirst = next;
151 }
152 myLast = NULL;
153}
154
155/*----------------------------------------------------------------------*/
156
157void OpenGl_Group::RemovePrimitiveArray (CALL_DEF_PARRAY *APArray)
158{
159 OpenGl_ElementNode *prevnode = NULL, *node = myFirst;
160 while (node)
161 {
162 if (node->type == TelParray)
163 {
164 CALL_DEF_PARRAY *aCurPArray = ((const OpenGl_PrimitiveArray *)node->elem)->PArray();
165
166 // validate for correct pointer
167 if (aCurPArray->num_bounds == APArray->num_bounds &&
168 aCurPArray->num_edges == APArray->num_edges &&
169 aCurPArray->num_vertexs == APArray->num_vertexs &&
170 aCurPArray->type == APArray->type)
171 {
172 (prevnode? prevnode->next : myFirst) = node->next;
173 if (!myFirst) myLast = NULL;
174 delete node->elem;
175 delete node;
176 break;
177 }
178 }
179 prevnode = node;
180 node = node->next;
181 }
182}
183
184/*----------------------------------------------------------------------*/
185
186void OpenGl_Group::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
187{
188 // Is rendering in ADD or IMMEDIATE mode?
189 const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
190
191 // Setup aspects
192 const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
193 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
194 const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
195 const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
196 if (myAspectLine)
197 AWorkspace->SetAspectLine(myAspectLine);
198 if (myAspectFace)
199 AWorkspace->SetAspectFace(myAspectFace);
200 if (myAspectMarker)
201 AWorkspace->SetAspectMarker(myAspectMarker);
202 if (myAspectText)
203 AWorkspace->SetAspectText(myAspectText);
204
205 // Render group elements
206 OpenGl_ElementNode *node = myFirst;
207 while (node)
208 {
209 switch (node->type)
210 {
211 case TelPolyline:
212 case TelMarker:
213 case TelMarkerSet:
214 case TelText:
215 {
216 glDisable(GL_LIGHTING);
217
218 if (isImmediate)
219 {
220 glDepthMask(GL_FALSE);
221 }
222 else if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
223 (AWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
224 AWorkspace->DegenerateModel != 0 )
225 {
226 glDisable( GL_DEPTH_TEST );
227 if ( AWorkspace->NamedStatus & OPENGL_NS_TEXTURE ) DisableTexture();
228 AWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
229 }
230
231 node->elem->Render( AWorkspace );
232
233 if ( !isImmediate && (AWorkspace->NamedStatus & OPENGL_NS_TEXTURE) != 0 ) EnableTexture();
234 break;
235 }
236
237 case TelPolygon:
238 case TelPolygonIndices:
239 case TelQuadrangle:
240 case TelTriangleMesh:
241 {
242 if (isImmediate)
243 {
244 glDepthMask(GL_FALSE);
245 }
246 else if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
247 (AWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
248 AWorkspace->DegenerateModel < 2 )
249 {
250 if ( AWorkspace->NamedStatus & OPENGL_NS_TEXTURE ) EnableTexture ();
251
252 glEnable( GL_DEPTH_TEST );
253 AWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
254 }
255
256 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
257 AWorkspace->DisablePolygonOffset();
258
259 node->elem->Render( AWorkspace );
260
261 if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
262 AWorkspace->EnablePolygonOffset();
263 break;
264 }
265
266 default:
267 {
268 node->elem->Render( AWorkspace );
269 break;
270 }
271 }
272 node = node->next;
273 }
274
275 // Restore aspects
276 AWorkspace->SetAspectLine(aspect_line);
277 AWorkspace->SetAspectFace(aspect_face);
278 AWorkspace->SetAspectMarker(aspect_marker);
279 AWorkspace->SetAspectText(aspect_text);
280}
281
282/*----------------------------------------------------------------------*/