0023500: MFC texture example is crashed when view closed
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
CommitLineData
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 20
5f8b738e 21#include <OpenGl_GlCore11.hxx>
22
2166f0fa
SK
23#include <OpenGl_Structure.hxx>
24
25#include <OpenGl_Polyline.hxx>
26#include <OpenGl_Workspace.hxx>
27#include <OpenGl_View.hxx>
28
2166f0fa
SK
29#include <OpenGl_telem_util.hxx>
30
31
32/*----------------------------------------------------------------------*/
33
34static void call_util_transpose_mat (float tmat[16], float mat[4][4])
35{
36 int i, j;
37
38 for (i=0; i<4; i++)
39 for (j=0; j<4; j++)
40 tmat[j*4+i] = mat[i][j];
41}
42
43/*----------------------------------------------------------------------*/
44
45OpenGl_Structure::OpenGl_Structure ()
46: myTransformation(NULL),
47 myTransPers(NULL),
48 myDegenerateModel(NULL),
49 myAspectLine(NULL),
50 myAspectFace(NULL),
51 myAspectMarker(NULL),
52 myAspectText(NULL),
53 myHighlightBox(NULL),
54 myHighlightColor(NULL),
59f45b7c 55 myNamedStatus(0),
56 myZLayer(0)
2166f0fa
SK
57{
58}
59
60/*----------------------------------------------------------------------*/
61
5e27df78 62OpenGl_Structure::~OpenGl_Structure()
2166f0fa 63{
5e27df78 64 Release (Handle(OpenGl_Context)());
65 delete myTransformation; myTransformation = NULL;
66 delete myTransPers; myTransPers = NULL;
67 delete myDegenerateModel; myDegenerateModel = NULL;
2166f0fa
SK
68}
69
70/*----------------------------------------------------------------------*/
71
72void OpenGl_Structure::SetTransformation(const float *AMatrix)
73{
74 if (!myTransformation)
5e27df78 75 myTransformation = new OpenGl_Matrix();
2166f0fa
SK
76
77 matcpy( myTransformation->mat, AMatrix );
78}
79
80/*----------------------------------------------------------------------*/
81
82void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
83{
84 if (!myTransPers)
85 myTransPers = new TEL_TRANSFORM_PERSISTENCE;
86
87 myTransPers->mode = ATransPers.Flag;
88 myTransPers->pointX = ATransPers.Point.x;
89 myTransPers->pointY = ATransPers.Point.y;
90 myTransPers->pointZ = ATransPers.Point.z;
91}
92
93/*----------------------------------------------------------------------*/
94
95void OpenGl_Structure::SetDegenerateModel (const Standard_Integer AMode, const float ASkipRatio)
96{
97 if (!myDegenerateModel)
98 myDegenerateModel = new DEGENERATION;
99
100 myDegenerateModel->mode = AMode;
101 myDegenerateModel->skipRatio = ASkipRatio;
102}
103
104/*----------------------------------------------------------------------*/
105
106void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
107{
108 if (!myAspectLine)
5e27df78 109 myAspectLine = new OpenGl_AspectLine();
2166f0fa
SK
110 myAspectLine->SetContext( AContext );
111}
112
113/*----------------------------------------------------------------------*/
114
115void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA &AContext)
116{
117 if (!myAspectFace)
5e27df78 118 myAspectFace = new OpenGl_AspectFace();
2166f0fa
SK
119 myAspectFace->SetContext( AContext );
120}
121
122/*----------------------------------------------------------------------*/
123
124void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER &AContext)
125{
126 if (!myAspectMarker)
5e27df78 127 myAspectMarker = new OpenGl_AspectMarker();
2166f0fa
SK
128 myAspectMarker->SetContext( AContext );
129}
130
131/*----------------------------------------------------------------------*/
132
133void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
134{
135 if (!myAspectText)
5e27df78 136 myAspectText = new OpenGl_AspectText();
2166f0fa
SK
137 myAspectText->SetContext( AContext );
138}
139
140/*----------------------------------------------------------------------*/
141
5e27df78 142void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
143 const CALL_DEF_BOUNDBOX& theBoundBox)
2166f0fa 144{
5e27df78 145 if (myHighlightBox != NULL)
146 {
147 myHighlightBox->Release (theGlCtx);
148 }
2166f0fa 149 else
5e27df78 150 {
151 myHighlightBox = new OpenGl_Group();
152 }
2166f0fa 153
5e27df78 154 CALL_DEF_CONTEXTLINE aContextLine;
155 aContextLine.Color = theBoundBox.Color;
156 aContextLine.LineType = Aspect_TOL_SOLID;
157 aContextLine.Width = 1.0f;
158 myHighlightBox->SetAspectLine (aContextLine);
2166f0fa
SK
159
160#define CALL_MAX_BOUNDBOXSIZE 16
161
5e27df78 162 Graphic3d_Array1OfVertex aPoints (1, CALL_MAX_BOUNDBOXSIZE);
163 const float Xm = theBoundBox.Pmin.x;
164 const float Ym = theBoundBox.Pmin.y;
165 const float Zm = theBoundBox.Pmin.z;
166 const float XM = theBoundBox.Pmax.x;
167 const float YM = theBoundBox.Pmax.y;
168 const float ZM = theBoundBox.Pmax.z;
169 aPoints( 1).SetCoord (Xm, Ym, Zm);
170 aPoints( 2).SetCoord (Xm, Ym, ZM);
171 aPoints( 3).SetCoord (Xm, YM, ZM);
172 aPoints( 4).SetCoord (Xm, YM, Zm);
173 aPoints( 5).SetCoord (Xm, Ym, Zm);
174 aPoints( 6).SetCoord (XM, Ym, Zm);
175 aPoints( 7).SetCoord (XM, Ym, ZM);
176 aPoints( 8).SetCoord (XM, YM, ZM);
177 aPoints( 9).SetCoord (XM, YM, Zm);
178 aPoints(10).SetCoord (XM, Ym, Zm);
179 aPoints(11).SetCoord (XM, YM, Zm);
180 aPoints(12).SetCoord (Xm, YM, Zm);
181 aPoints(13).SetCoord (Xm, YM, ZM);
182 aPoints(14).SetCoord (XM, YM, ZM);
183 aPoints(15).SetCoord (XM, Ym, ZM);
184 aPoints(16).SetCoord (Xm, Ym, ZM);
185
186 OpenGl_Polyline* aPolyline = new OpenGl_Polyline (aPoints);
187 myHighlightBox->AddElement (TelPolyline, aPolyline);
2166f0fa
SK
188}
189
190/*----------------------------------------------------------------------*/
191
5e27df78 192void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 193{
5e27df78 194 if (myHighlightBox != NULL)
2166f0fa 195 {
5e27df78 196 OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
2166f0fa
SK
197 }
198}
199
200/*----------------------------------------------------------------------*/
201
5e27df78 202void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
203 const Standard_ShortReal R,
204 const Standard_ShortReal G,
205 const Standard_ShortReal B)
2166f0fa 206{
5e27df78 207 ClearHighlightBox (theGlCtx);
208 if (myHighlightColor == NULL)
209 {
210 myHighlightColor = new TEL_COLOUR();
211 }
2166f0fa
SK
212
213 myHighlightColor->rgb[0] = R;
214 myHighlightColor->rgb[1] = G;
215 myHighlightColor->rgb[2] = B;
216 myHighlightColor->rgb[3] = 1.F;
217}
218
219/*----------------------------------------------------------------------*/
220
5e27df78 221void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 222{
5e27df78 223 ClearHighlightBox(theGlCtx);
224 delete myHighlightColor;
225 myHighlightColor = NULL;
2166f0fa
SK
226}
227
228/*----------------------------------------------------------------------*/
229
230void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
231{
232 Disconnect (AStructure);
233 myConnected.Append(AStructure);
234}
235
236/*----------------------------------------------------------------------*/
237
238void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
239{
240 OpenGl_ListOfStructure::Iterator its(myConnected);
241 while (its.More())
242 {
243 // Check for the given structure
244 if (its.Value() == AStructure)
245 {
246 myConnected.Remove(its);
247 return;
248 }
249 its.Next();
250 }
251}
252
253/*----------------------------------------------------------------------*/
254
255OpenGl_Group * OpenGl_Structure::AddGroup ()
256{
257 // Create new group
258 OpenGl_Group *g = new OpenGl_Group;
259 myGroups.Append(g);
260 return g;
261}
262
263/*----------------------------------------------------------------------*/
264
5e27df78 265void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
266 const OpenGl_Group* theGroup)
2166f0fa 267{
5e27df78 268 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
2166f0fa
SK
269 {
270 // Check for the given group
5e27df78 271 if (anIter.Value() == theGroup)
2166f0fa
SK
272 {
273 // Delete object
5e27df78 274 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
275 myGroups.Remove (anIter);
2166f0fa
SK
276 return;
277 }
2166f0fa
SK
278 }
279}
280
281/*----------------------------------------------------------------------*/
282
5e27df78 283void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 284{
5e27df78 285 // Release groups
286 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
2166f0fa
SK
287 {
288 // Delete objects
5e27df78 289 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
2166f0fa
SK
290 }
291 myGroups.Clear();
292}
293
294/*----------------------------------------------------------------------*/
295
296void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
297{
298 // Process the structure only if visible
299 if ( myNamedStatus & OPENGL_NS_HIDE )
300 return;
301
302 // Render named status
303 const Standard_Integer named_status = AWorkspace->NamedStatus;
304 AWorkspace->NamedStatus |= myNamedStatus;
305
306 // Is rendering in ADD or IMMEDIATE mode?
307 const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
308
309 // Apply local transformation
310 GLint matrix_mode = 0;
311 const OpenGl_Matrix *local_trsf = NULL;
312 if (myTransformation)
313 {
314 if (isImmediate)
315 {
316 float mat16[16];
317 call_util_transpose_mat (mat16, myTransformation->mat);
318 glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
319 glMatrixMode (GL_MODELVIEW);
320 glPushMatrix ();
321 glScalef (1.F, 1.F, 1.F);
322 glMultMatrixf (mat16);
323 }
324 else
325 {
326 glMatrixMode (GL_MODELVIEW);
327 glPushMatrix();
328
329 local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
330 }
331 }
332
333 // Apply transform persistence
334 const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
335 if ( myTransPers && myTransPers->mode != 0 )
336 {
337 trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
338 }
339
340 // Apply degeneration
341 if (myDegenerateModel)
342 {
343 if ( AWorkspace->NamedStatus & OPENGL_NS_DEGENERATION )
344 {
345 AWorkspace->DegenerateModel = myDegenerateModel->mode;
346 switch ( AWorkspace->DegenerateModel )
347 {
348 case 0: break;
349
350 default:
351 glLineWidth ( 1.0 );
352 glDisable ( GL_LINE_STIPPLE );
353
354 case 1:
355 AWorkspace->SkipRatio = myDegenerateModel->skipRatio;
356 }
357 }
358 }
359
360 // Apply aspects
361 const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
362 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
363 const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
364 const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
365 if (myAspectLine)
366 AWorkspace->SetAspectLine(myAspectLine);
367 if (myAspectFace)
368 AWorkspace->SetAspectFace(myAspectFace);
369 if (myAspectMarker)
370 AWorkspace->SetAspectMarker(myAspectMarker);
371 if (myAspectText)
372 AWorkspace->SetAspectText(myAspectText);
373
374 // Apply highlight box
375 if (myHighlightBox)
376 myHighlightBox->Render( AWorkspace );
377
378 // Apply highlight color
379 const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
380 if (myHighlightColor)
381 AWorkspace->HighlightColor = myHighlightColor;
382
383 // Render connected structures
384 OpenGl_ListOfStructure::Iterator its(myConnected);
385 while (its.More())
386 {
387 its.Value()->Render(AWorkspace);
388 its.Next();
389 }
390
391 // Render groups
392 OpenGl_ListOfGroup::Iterator itg(myGroups);
393 while (itg.More())
394 {
395 itg.Value()->Render(AWorkspace);
396 itg.Next();
397 }
398
399 // Restore highlight color
400 AWorkspace->HighlightColor = highlight_color;
401
402 // Restore aspects
403 AWorkspace->SetAspectLine(aspect_line);
404 AWorkspace->SetAspectFace(aspect_face);
405 AWorkspace->SetAspectMarker(aspect_marker);
406 AWorkspace->SetAspectText(aspect_text);
407
408 // Restore transform persistence
409 if ( myTransPers && myTransPers->mode != 0 )
410 {
411 AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
412 }
413
414 // Restore local transformation
415 if (myTransformation)
416 {
417 if (isImmediate)
418 {
419 glPopMatrix ();
420 glMatrixMode (matrix_mode);
421 }
422 else
423 {
424 AWorkspace->SetStructureMatrix(local_trsf);
425
426 glMatrixMode (GL_MODELVIEW);
427 glPopMatrix();
428 }
429 }
430
431 // Restore named status
432 AWorkspace->NamedStatus = named_status;
433}
434
5e27df78 435// =======================================================================
436// function : Release
437// purpose :
438// =======================================================================
439void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
440{
441 // Release groups
442 Clear (theGlCtx);
443 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
444 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
445 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
446 OpenGl_Element::Destroy (theGlCtx, myAspectText);
447 ClearHighlightColor (theGlCtx);
448}
449
dd8a4ce9 450// =======================================================================
451// function : ReleaseGlResources
452// purpose :
453// =======================================================================
454void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
455{
456 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
457 {
458 OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
459 if (aGroup != NULL)
460 {
461 aGroup->Release (theGlCtx);
462 }
463 }
464 if (myAspectLine != NULL)
465 {
466 myAspectLine->Release (theGlCtx);
467 }
468 if (myAspectFace != NULL)
469 {
470 myAspectFace->Release (theGlCtx);
471 }
472 if (myAspectMarker != NULL)
473 {
474 myAspectMarker->Release (theGlCtx);
475 }
476 if (myAspectText != NULL)
477 {
478 myAspectText->Release (theGlCtx);
479 }
480 if (myHighlightBox != NULL)
481 {
482 myHighlightBox->Release (theGlCtx);
483 }
484}
485
59f45b7c 486//=======================================================================
487//function : SetZLayer
488//purpose :
489//=======================================================================
490
491void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
492{
493 myZLayer = theLayerIndex;
494}
495
496//=======================================================================
497//function : GetZLayer
498//purpose :
499//=======================================================================
500
501Standard_Integer OpenGl_Structure::GetZLayer () const
502{
503 return myZLayer;
504}