0024732: OpenGl_Context - retrieve functions up to GL4.4
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifdef HAVE_CONFIG_H
17   #include <config.h>
18 #endif
19
20 #include <OpenGl_CappingAlgo.hxx>
21 #include <OpenGl_Context.hxx>
22 #include <OpenGl_GlCore11.hxx>
23 #include <OpenGl_GraphicDriver.hxx>
24 #include <OpenGl_ShaderManager.hxx>
25 #include <OpenGl_ShaderProgram.hxx>
26 #include <OpenGl_Structure.hxx>
27 #include <OpenGl_telem_util.hxx>
28 #include <OpenGl_Vec.hxx>
29 #include <OpenGl_View.hxx>
30 #include <OpenGl_Workspace.hxx>
31
32 #include <Graphic3d_SequenceOfHClipPlane_Handle.hxx>
33
34 IMPLEMENT_STANDARD_HANDLE (OpenGl_Structure, Graphic3d_CStructure)
35 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Structure, Graphic3d_CStructure)
36
37 //! Auxiliary class for bounding box presentation
38 class OpenGl_BndBoxPrs : public OpenGl_Element
39 {
40
41 public:
42
43   //! Main constructor
44   OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
45   {
46     const float Xm = theBndBox.Pmin.x;
47     const float Ym = theBndBox.Pmin.y;
48     const float Zm = theBndBox.Pmin.z;
49     const float XM = theBndBox.Pmax.x;
50     const float YM = theBndBox.Pmax.y;
51     const float ZM = theBndBox.Pmax.z;
52     myVerts[0]  = OpenGl_Vec3 (Xm, Ym, Zm);
53     myVerts[1]  = OpenGl_Vec3 (Xm, Ym, ZM);
54     myVerts[2]  = OpenGl_Vec3 (Xm, YM, ZM);
55     myVerts[3]  = OpenGl_Vec3 (Xm, YM, Zm);
56     myVerts[4]  = OpenGl_Vec3 (Xm, Ym, Zm);
57     myVerts[5]  = OpenGl_Vec3 (XM, Ym, Zm);
58     myVerts[6]  = OpenGl_Vec3 (XM, Ym, ZM);
59     myVerts[7]  = OpenGl_Vec3 (XM, YM, ZM);
60     myVerts[8]  = OpenGl_Vec3 (XM, YM, Zm);
61     myVerts[9]  = OpenGl_Vec3 (XM, Ym, Zm);
62     myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
63     myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
64     myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
65     myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
66     myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
67     myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
68   }
69
70   //! Render presentation
71   virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const
72   {
73     // Apply line aspect
74     const OpenGl_AspectLine*     anAspectLine = theWorkspace->AspectLine (Standard_True);
75     const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
76
77     glDisable (GL_LIGHTING);
78     if ((theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0)
79     {
80       glDepthMask (GL_FALSE);
81     }
82
83     // Use highlight colors
84     glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
85
86     glEnableClientState (GL_VERTEX_ARRAY);
87     glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
88     glDrawArrays (GL_LINE_STRIP, 0, 16);
89     glDisableClientState (GL_VERTEX_ARRAY);
90
91     // restore aspects
92     if (!aPrevTexture.IsNull())
93     {
94       theWorkspace->EnableTexture (aPrevTexture);
95     }
96   }
97
98   //! Release graphical resources
99   virtual void Release (const Handle(OpenGl_Context)& )
100   {
101     //
102   }
103
104 protected:
105
106   //! Protected destructor
107   virtual ~OpenGl_BndBoxPrs() {}
108
109 private:
110
111   OpenGl_Vec3 myVerts[16]; //!< vertices array
112
113 public:
114
115   DEFINE_STANDARD_ALLOC
116
117 };
118
119 /*----------------------------------------------------------------------*/
120
121 // =======================================================================
122 // function : call_util_transpose_mat
123 // purpose  :
124 // =======================================================================
125 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
126 {
127   int i, j;
128
129   for (i=0; i<4; i++)
130     for (j=0; j<4; j++)
131       tmat[j*4+i] = mat[i][j];
132 }
133
134 // =======================================================================
135 // function : OpenGl_Structure
136 // purpose  :
137 // =======================================================================
138 OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
139 : Graphic3d_CStructure (theManager),
140   myTransformation(NULL),
141   myTransPers(NULL),
142   myAspectLine(NULL),
143   myAspectFace(NULL),
144   myAspectMarker(NULL),
145   myAspectText(NULL),
146   myHighlightBox(NULL),
147   myHighlightColor(NULL),
148   myNamedStatus(0),
149   myZLayer(0)
150 {
151   UpdateNamedStatus();
152 #if HAVE_OPENCL
153   myIsRaytracable = Standard_False;
154   myModificationState = 0;
155 #endif
156 }
157
158 // =======================================================================
159 // function : ~OpenGl_Structure
160 // purpose  :
161 // =======================================================================
162 OpenGl_Structure::~OpenGl_Structure()
163 {
164   Release (Handle(OpenGl_Context)());
165   delete myTransformation;  myTransformation  = NULL;
166   delete myTransPers;       myTransPers       = NULL;
167 }
168
169 // =======================================================================
170 // function : UpdateAspects
171 // purpose  :
172 // =======================================================================
173 void OpenGl_Structure::UpdateAspects()
174 {
175   SetTransformPersistence (TransformPersistence);
176
177   if (ContextLine.IsDef)
178     SetAspectLine (ContextLine);
179
180   if (ContextFillArea.IsDef)
181     SetAspectFace (ContextFillArea);
182
183   if (ContextMarker.IsDef)
184     SetAspectMarker (ContextMarker);
185
186   if (ContextText.IsDef)
187     SetAspectText (ContextText);
188 }
189
190 // =======================================================================
191 // function : UpdateTransformation
192 // purpose  :
193 // =======================================================================
194 void OpenGl_Structure::UpdateTransformation()
195 {
196   if (myTransformation == NULL)
197   {
198     myTransformation = new OpenGl_Matrix();
199   }
200
201   matcpy (myTransformation->mat, &Graphic3d_CStructure::Transformation[0][0]);
202
203 #ifdef HAVE_OPENCL
204   if (myIsRaytracable)
205   {
206     UpdateStateWithAncestorStructures();
207   }
208 #endif
209 }
210
211 // =======================================================================
212 // function : SetTransformPersistence
213 // purpose  :
214 // =======================================================================
215 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
216 {
217   if (!myTransPers)
218     myTransPers = new TEL_TRANSFORM_PERSISTENCE;
219
220   myTransPers->mode = ATransPers.Flag;
221   myTransPers->pointX = ATransPers.Point.x;
222   myTransPers->pointY = ATransPers.Point.y;
223   myTransPers->pointZ = ATransPers.Point.z;
224 }
225
226 // =======================================================================
227 // function : SetAspectLine
228 // purpose  :
229 // =======================================================================
230 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &theAspect)
231 {
232   if (!myAspectLine)
233   {
234     myAspectLine = new OpenGl_AspectLine();
235   }
236   myAspectLine->SetAspect (theAspect);
237 }
238
239 // =======================================================================
240 // function : SetAspectFace
241 // purpose  :
242 // =======================================================================
243 void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect)
244 {
245   if (!myAspectFace)
246   {
247     myAspectFace = new OpenGl_AspectFace();
248   }
249   myAspectFace->SetAspect (theAspect);
250
251 #ifdef HAVE_OPENCL
252   if (myIsRaytracable)
253   {
254     UpdateStateWithAncestorStructures();
255   }
256 #endif
257 }
258
259 // =======================================================================
260 // function : SetAspectMarker
261 // purpose  :
262 // =======================================================================
263 void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect)
264 {
265   if (!myAspectMarker)
266   {
267     myAspectMarker = new OpenGl_AspectMarker();
268   }
269   myAspectMarker->SetAspect (theAspect);
270 }
271
272 // =======================================================================
273 // function : SetAspectText
274 // purpose  :
275 // =======================================================================
276 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &theAspect)
277 {
278   if (!myAspectText)
279   {
280     myAspectText = new OpenGl_AspectText();
281   }
282   myAspectText->SetAspect (theAspect);
283 }
284
285 // =======================================================================
286 // function : SetHighlightBox
287 // purpose  :
288 // =======================================================================
289 void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
290                                         const CALL_DEF_BOUNDBOX&      theBoundBox)
291 {
292   if (myHighlightBox != NULL)
293   {
294     myHighlightBox->Release (theGlCtx);
295   }
296   else
297   {
298 #ifndef HAVE_OPENCL
299     myHighlightBox = new OpenGl_Group();
300 #else
301     myHighlightBox = new OpenGl_Group (this);
302 #endif
303   }
304
305   CALL_DEF_CONTEXTLINE aContextLine;
306   aContextLine.Color    = theBoundBox.Color;
307   aContextLine.LineType = Aspect_TOL_SOLID;
308   aContextLine.Width    = 1.0f;
309   myHighlightBox->SetAspectLine (aContextLine);
310
311   OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (theBoundBox);
312   myHighlightBox->AddElement (aBndBoxPrs);
313 }
314
315 // =======================================================================
316 // function : ClearHighlightBox
317 // purpose  :
318 // =======================================================================
319 void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
320 {
321   if (myHighlightBox != NULL)
322   {
323     OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
324   }
325 }
326
327 // =======================================================================
328 // function : HighlightWithColor
329 // purpose  :
330 // =======================================================================
331 void OpenGl_Structure::HighlightWithColor (const Graphic3d_Vec3&  theColor,
332                                            const Standard_Boolean theToCreate)
333 {
334   const Handle(OpenGl_Context)& aCtx = GlDriver()->GetSharedContext();
335   if (theToCreate)
336     SetHighlightColor   (aCtx, theColor);
337   else
338     ClearHighlightColor (aCtx);
339 }
340
341 // =======================================================================
342 // function : HighlightWithBndBox
343 // purpose  :
344 // =======================================================================
345 void OpenGl_Structure::HighlightWithBndBox (const Standard_Boolean theToCreate)
346 {
347   const Handle(OpenGl_Context)& aCtx = GlDriver()->GetSharedContext();
348   if (theToCreate)
349     SetHighlightBox   (aCtx, BoundBox);
350   else
351     ClearHighlightBox (aCtx);
352 }
353
354 // =======================================================================
355 // function : SetHighlightColor
356 // purpose  :
357 // =======================================================================
358 void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
359                                           const Graphic3d_Vec3&         theColor)
360 {
361   ClearHighlightBox (theGlCtx);
362   if (myHighlightColor == NULL)
363   {
364     myHighlightColor = new TEL_COLOUR();
365   }
366
367   myHighlightColor->rgb[0] = theColor.r();
368   myHighlightColor->rgb[1] = theColor.g();
369   myHighlightColor->rgb[2] = theColor.b();
370   myHighlightColor->rgb[3] = 1.F;
371 }
372
373 // =======================================================================
374 // function : ClearHighlightColor
375 // purpose  :
376 // =======================================================================
377 void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
378 {
379   ClearHighlightBox(theGlCtx);
380   delete myHighlightColor;
381   myHighlightColor = NULL;
382 }
383
384 // =======================================================================
385 // function : UpdateNamedStatus
386 // purpose  :
387 // =======================================================================
388 void OpenGl_Structure::UpdateNamedStatus()
389 {
390   myNamedStatus = 0;
391   if (highlight) myNamedStatus |= OPENGL_NS_HIGHLIGHT;
392   if (!visible)  myNamedStatus |= OPENGL_NS_HIDE;
393
394 #ifdef HAVE_OPENCL
395   if (myIsRaytracable)
396   {
397     UpdateStateWithAncestorStructures();
398   }
399 #endif
400 }
401
402 #ifdef HAVE_OPENCL
403
404 // =======================================================================
405 // function : RegisterAncestorStructure
406 // purpose  :
407 // =======================================================================
408 void OpenGl_Structure::RegisterAncestorStructure (const OpenGl_Structure* theStructure) const
409 {
410   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
411   {
412     if (anIt.Value() == theStructure)
413     {
414       return;
415     }
416   }
417
418   myAncestorStructures.Append (theStructure);
419 }
420
421 // =======================================================================
422 // function : UnregisterAncestorStructure
423 // purpose  :
424 // =======================================================================
425 void OpenGl_Structure::UnregisterAncestorStructure (const OpenGl_Structure* theStructure) const
426 {
427   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
428   {
429     if (anIt.Value() == theStructure)
430     {
431       myAncestorStructures.Remove (anIt);
432       return;
433     }
434   }
435 }
436
437 // =======================================================================
438 // function : UnregisterFromAncestorStructure
439 // purpose  :
440 // =======================================================================
441 void OpenGl_Structure::UnregisterFromAncestorStructure() const
442 {
443   for (OpenGl_ListOfStructure::Iterator anIta (myAncestorStructures); anIta.More(); anIta.Next())
444   {
445     OpenGl_Structure* anAncestor = const_cast<OpenGl_Structure*> (anIta.ChangeValue());
446
447     for (OpenGl_ListOfStructure::Iterator anIts (anAncestor->myConnected); anIts.More(); anIts.Next())
448     {
449       if (anIts.Value() == this)
450       {
451         anAncestor->myConnected.Remove (anIts);
452         return;
453       }
454     }
455   }
456 }
457
458 // =======================================================================
459 // function : UpdateStateWithAncestorStructures
460 // purpose  :
461 // =======================================================================
462 void OpenGl_Structure::UpdateStateWithAncestorStructures() const
463 {
464   myModificationState++;
465
466   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
467   {
468     anIt.Value()->UpdateStateWithAncestorStructures();
469   }
470 }
471
472 // =======================================================================
473 // function : UpdateRaytracableWithAncestorStructures
474 // purpose  :
475 // =======================================================================
476 void OpenGl_Structure::UpdateRaytracableWithAncestorStructures() const
477 {
478   myIsRaytracable = OpenGl_Raytrace::IsRaytracedStructure (this);
479
480   if (!myIsRaytracable)
481   {
482     for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
483     {
484       anIt.Value()->UpdateRaytracableWithAncestorStructures();
485     }
486   }
487 }
488
489 // =======================================================================
490 // function : SetRaytracableWithAncestorStructures
491 // purpose  :
492 // =======================================================================
493 void OpenGl_Structure::SetRaytracableWithAncestorStructures() const
494 {
495   myIsRaytracable = Standard_True;
496
497   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
498   {
499     if (!anIt.Value()->IsRaytracable())
500     {
501       anIt.Value()->SetRaytracableWithAncestorStructures();
502     }
503   }
504 }
505
506 #endif
507
508 // =======================================================================
509 // function : Connect
510 // purpose  :
511 // =======================================================================
512 void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
513 {
514   OpenGl_Structure* aStruct = (OpenGl_Structure* )&theStructure;
515   Disconnect (theStructure);
516   myConnected.Append (aStruct);
517
518 #ifdef HAVE_OPENCL
519   if (aStruct->IsRaytracable())
520   {
521     UpdateStateWithAncestorStructures();
522     SetRaytracableWithAncestorStructures();
523   }
524
525   aStruct->RegisterAncestorStructure (this);
526 #endif
527 }
528
529 // =======================================================================
530 // function : Disconnect
531 // purpose  :
532 // =======================================================================
533 void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
534 {
535   OpenGl_Structure* aStruct = (OpenGl_Structure* )&theStructure;
536   for (OpenGl_ListOfStructure::Iterator anIter (myConnected); anIter.More(); anIter.Next())
537   {
538     // Check for the given structure
539     if (anIter.Value() == aStruct)
540     {
541       myConnected.Remove (anIter);
542
543 #ifdef HAVE_OPENCL
544       if (aStruct->IsRaytracable())
545       {
546         UpdateStateWithAncestorStructures();
547         UpdateRaytracableWithAncestorStructures();
548       }
549
550       aStruct->UnregisterAncestorStructure (this);
551 #endif
552       return;
553     }
554   }
555 }
556
557 // =======================================================================
558 // function : AddGroup
559 // purpose  :
560 // =======================================================================
561 OpenGl_Group * OpenGl_Structure::AddGroup()
562 {
563   // Create new group
564 #ifndef HAVE_OPENCL
565   OpenGl_Group *g = new OpenGl_Group();
566 #else
567   OpenGl_Group *g = new OpenGl_Group (this);
568 #endif
569
570   myGroups.Append(g);
571   return g;
572 }
573
574 // =======================================================================
575 // function : RemoveGroup
576 // purpose  :
577 // =======================================================================
578 void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
579                                     const OpenGl_Group*           theGroup)
580 {
581   for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
582   {
583     // Check for the given group
584     if (anIter.Value() == theGroup)
585     {
586       myGroups.Remove (anIter);
587
588 #ifdef HAVE_OPENCL
589       if (theGroup->IsRaytracable())
590       {
591         UpdateStateWithAncestorStructures();
592         UpdateRaytracableWithAncestorStructures();
593       }
594 #endif
595
596       // Delete object
597       OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (theGroup));
598       return;
599     }
600   }
601 }
602
603 // =======================================================================
604 // function : Clear
605 // purpose  :
606 // =======================================================================
607 void OpenGl_Structure::Clear()
608 {
609   Clear (GlDriver()->GetSharedContext());
610 }
611
612 // =======================================================================
613 // function : Clear
614 // purpose  :
615 // =======================================================================
616 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
617 {
618 #ifdef HAVE_OPENCL
619   Standard_Boolean aRaytracableGroupDeleted (Standard_False);
620 #endif
621
622   // Release groups
623   for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
624   {
625 #ifdef HAVE_OPENCL
626     aRaytracableGroupDeleted |= anIter.Value()->IsRaytracable();
627 #endif
628
629     // Delete objects
630     OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
631   }
632   myGroups.Clear();
633
634 #ifdef HAVE_OPENCL
635   if (aRaytracableGroupDeleted)
636   {
637     UpdateStateWithAncestorStructures();
638     UpdateRaytracableWithAncestorStructures();
639   }
640 #endif
641 }
642
643 // =======================================================================
644 // function : Render
645 // purpose  :
646 // =======================================================================
647 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
648 {
649   // Process the structure only if visible
650   if ( myNamedStatus & OPENGL_NS_HIDE )
651     return;
652
653   // Render named status
654   const Standard_Integer named_status = AWorkspace->NamedStatus;
655   AWorkspace->NamedStatus |= myNamedStatus;
656
657   // Is rendering in ADD or IMMEDIATE mode?
658   const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
659
660   const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
661
662   // Apply local transformation
663   GLint matrix_mode = 0;
664   const OpenGl_Matrix *local_trsf = NULL;
665   if (myTransformation)
666   {
667     if (isImmediate)
668     {
669       Tmatrix3 aModelWorld;
670       call_util_transpose_mat (*aModelWorld, myTransformation->mat);
671       glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
672
673       if (!aCtx->ShaderManager()->IsEmpty())
674       {
675         Tmatrix3 aWorldView;
676         glGetFloatv (GL_MODELVIEW_MATRIX, *aWorldView);
677
678         Tmatrix3 aProjection;
679         glGetFloatv (GL_PROJECTION_MATRIX, *aProjection);
680
681         aCtx->ShaderManager()->UpdateModelWorldStateTo (&aModelWorld);
682         aCtx->ShaderManager()->UpdateWorldViewStateTo (&aWorldView);
683         aCtx->ShaderManager()->UpdateProjectionStateTo (&aProjection);
684       }
685
686       glMatrixMode (GL_MODELVIEW);
687       glPushMatrix ();
688       glScalef (1.F, 1.F, 1.F);
689       glMultMatrixf (*aModelWorld);
690     }
691     else
692     {
693       glMatrixMode (GL_MODELVIEW);
694       glPushMatrix();
695
696       local_trsf = AWorkspace->SetStructureMatrix (myTransformation);
697     }
698   }
699
700   // Apply transform persistence
701   const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
702   if ( myTransPers && myTransPers->mode != 0 )
703   {
704     trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers);
705   }
706
707   // Apply aspects
708   const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
709   const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
710   const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
711   const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
712   if (myAspectLine)
713     AWorkspace->SetAspectLine(myAspectLine);
714   if (myAspectFace)
715     AWorkspace->SetAspectFace(myAspectFace);
716   if (myAspectMarker)
717     AWorkspace->SetAspectMarker(myAspectMarker);
718   if (myAspectText)
719     AWorkspace->SetAspectText(myAspectText);
720
721   // Apply highlight box
722   if (myHighlightBox)
723     myHighlightBox->Render( AWorkspace );
724
725   // Apply highlight color
726   const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
727   if (myHighlightColor)
728     AWorkspace->HighlightColor = myHighlightColor;
729
730   // Render connected structures
731   OpenGl_ListOfStructure::Iterator its(myConnected);
732   while (its.More())
733   {
734     its.Value()->Render(AWorkspace);
735     its.Next();
736   }
737
738   // Set up plane equations for non-structure transformed global model-view matrix
739   const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
740
741   // List of planes to be applied to context state
742   Handle(Graphic3d_SequenceOfHClipPlane) aUserPlanes;
743
744   // Collect clipping planes of structure scope
745   if (!myClipPlanes.IsEmpty())
746   {
747     Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
748     for (; aClippingIt.More(); aClippingIt.Next())
749     {
750       const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
751       if (!aClipPlane->IsOn())
752       {
753         continue;
754       }
755
756       if (aUserPlanes.IsNull())
757       {
758         aUserPlanes = new Graphic3d_SequenceOfHClipPlane();
759       }
760
761       aUserPlanes->Append (aClipPlane);
762     }
763   }
764
765   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
766   {
767     // add planes at loaded view matrix state
768     aContext->ChangeClipping().AddWorld (*aUserPlanes, AWorkspace);
769
770     // Set OCCT state uniform variables
771     if (!aContext->ShaderManager()->IsEmpty())
772     {
773       aContext->ShaderManager()->UpdateClippingState();
774     }
775   }
776
777   // Render groups
778   OpenGl_ListOfGroup::Iterator itg(myGroups);
779   while (itg.More())
780   {
781     itg.Value()->Render(AWorkspace);
782     itg.Next();
783   }
784
785   // Render capping for structure groups
786   if (!aContext->Clipping().Planes().IsEmpty())
787   {
788     OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
789   }
790
791   // Revert structure clippings
792   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
793   {
794     aContext->ChangeClipping().Remove (*aUserPlanes);
795
796     // Set OCCT state uniform variables
797     if (!aContext->ShaderManager()->IsEmpty())
798     {
799       aContext->ShaderManager()->RevertClippingState();
800     }
801   }
802
803   // Restore highlight color
804   AWorkspace->HighlightColor = highlight_color;
805
806   // Restore aspects
807   AWorkspace->SetAspectLine(aspect_line);
808   AWorkspace->SetAspectFace(aspect_face);
809   AWorkspace->SetAspectMarker(aspect_marker);
810   AWorkspace->SetAspectText(aspect_text);
811
812   // Restore transform persistence
813   if ( myTransPers && myTransPers->mode != 0 )
814   {
815     AWorkspace->ActiveView()->BeginTransformPersistence (aContext, trans_pers);
816   }
817
818   // Restore local transformation
819   if (myTransformation)
820   {
821     if (isImmediate)
822     {
823       glPopMatrix ();
824       glMatrixMode (matrix_mode);
825
826       Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
827                                     { 0.f, 1.f, 0.f, 0.f },
828                                     { 0.f, 0.f, 1.f, 0.f },
829                                     { 0.f, 0.f, 0.f, 1.f } };
830
831       aContext->ShaderManager()->RevertModelWorldStateTo (&aModelWorldState);
832     }
833     else
834     {
835       AWorkspace->SetStructureMatrix (local_trsf, true);
836
837       glMatrixMode (GL_MODELVIEW);
838       glPopMatrix();
839     }
840   }
841
842   // Restore named status
843   AWorkspace->NamedStatus = named_status;
844 }
845
846 // =======================================================================
847 // function : Release
848 // purpose  :
849 // =======================================================================
850 void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
851 {
852   // Release groups
853   Clear (theGlCtx);
854   OpenGl_Element::Destroy (theGlCtx, myAspectLine);
855   OpenGl_Element::Destroy (theGlCtx, myAspectFace);
856   OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
857   OpenGl_Element::Destroy (theGlCtx, myAspectText);
858   ClearHighlightColor (theGlCtx);
859
860 #ifdef HAVE_OPENCL
861   // Remove from connected list of ancestor
862   UnregisterFromAncestorStructure();
863 #endif
864 }
865
866 // =======================================================================
867 // function : ReleaseGlResources
868 // purpose  :
869 // =======================================================================
870 void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
871 {
872   for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
873   {
874     OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
875     if (aGroup != NULL)
876     {
877       aGroup->Release (theGlCtx);
878     }
879   }
880   if (myAspectLine != NULL)
881   {
882     myAspectLine->Release (theGlCtx);
883   }
884   if (myAspectFace != NULL)
885   {
886     myAspectFace->Release (theGlCtx);
887   }
888   if (myAspectMarker != NULL)
889   {
890     myAspectMarker->Release (theGlCtx);
891   }
892   if (myAspectText != NULL)
893   {
894     myAspectText->Release (theGlCtx);
895   }
896   if (myHighlightBox != NULL)
897   {
898     myHighlightBox->Release (theGlCtx);
899   }
900 }
901
902 //=======================================================================
903 //function : SetZLayer
904 //purpose  :
905 //=======================================================================
906 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
907 {
908   myZLayer = theLayerIndex;
909 }
910
911 //=======================================================================
912 //function : GetZLayer
913 //purpose  :
914 //=======================================================================
915 Standard_Integer OpenGl_Structure::GetZLayer () const
916 {
917   return myZLayer;
918 }