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