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