b6f81ad0c97b36b75203b71dd6396bbccd4ed862
[occt.git] / src / OpenGl / OpenGl_Group.cxx
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
20 #include <OpenGl_Group.hxx>
21
22 #include <OpenGl_PrimitiveArray.hxx>
23 #include <OpenGl_Workspace.hxx>
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 {
38   Release (Handle(OpenGl_Context)());
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
62 void OpenGl_Group::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
63                                   const CALL_DEF_CONTEXTFILLAREA& theAspect,
64                                   const Standard_Boolean          theIsGlobal)
65 {
66   if (theIsGlobal || myFirst == NULL)
67   {
68     if (myAspectFace == NULL)
69     {
70       myAspectFace = new OpenGl_AspectFace();
71     }
72     myAspectFace->Init (theCtx, theAspect);
73   }
74   else
75   {
76     OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
77     anAspectFace->Init (theCtx, theAspect);
78     AddElement (TelNil/*TelAspectFace*/, anAspectFace);
79   }
80 }
81
82 /*----------------------------------------------------------------------*/
83
84 void OpenGl_Group::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
85                                     const CALL_DEF_CONTEXTMARKER& theAspect,
86                                     const Standard_Boolean theIsGlobal)
87 {
88   if (theIsGlobal || myFirst == NULL)
89   {
90     if (myAspectMarker == NULL)
91     {
92       myAspectMarker = new OpenGl_AspectMarker();
93     }
94     myAspectMarker->Init (theCtx, theAspect);
95   }
96   else
97   {
98     OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
99     anAspectMarker->Init (theCtx, theAspect);
100     AddElement (TelNil/*TelAspectMarker*/, anAspectMarker);
101   }
102 }
103
104 /*----------------------------------------------------------------------*/
105
106 void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theContext,
107                                   const Standard_Boolean theIsGlobal)
108 {
109   if (theIsGlobal || myFirst == NULL)
110   {
111     if (myAspectText == NULL)
112       myAspectText = new OpenGl_AspectText();
113     myAspectText->SetContext (theContext);
114   }
115   else
116   {
117     OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
118     anAspectText->SetContext (theContext);
119     AddElement ( TelNil/*TelAspectText*/, anAspectText);
120   }
121 }
122
123 /*----------------------------------------------------------------------*/
124
125 void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem )
126 {
127   OpenGl_ElementNode *node = new OpenGl_ElementNode();
128
129   node->type = AType;
130   node->elem = AElem;
131   node->next = NULL;
132   (myLast? myLast->next : myFirst) = node;
133   myLast = node;
134 }
135
136 /*----------------------------------------------------------------------*/
137
138 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
139 {
140   // Is rendering in ADD or IMMEDIATE mode?
141   const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
142
143   // Setup aspects
144   const OpenGl_AspectLine*   aBackAspectLine   = theWorkspace->AspectLine   (Standard_False);
145   const OpenGl_AspectFace*   aBackAspectFace   = theWorkspace->AspectFace   (Standard_False);
146   const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
147   const OpenGl_AspectText*   aBackAspectText   = theWorkspace->AspectText   (Standard_False);
148   if (myAspectLine)
149   {
150     theWorkspace->SetAspectLine (myAspectLine);
151   }
152   if (myAspectFace)
153   {
154     theWorkspace->SetAspectFace (myAspectFace);
155   }
156   if (myAspectMarker)
157   {
158     theWorkspace->SetAspectMarker (myAspectMarker);
159   }
160   if (myAspectText)
161   {
162     theWorkspace->SetAspectText (myAspectText);
163   }
164
165   // Render group elements
166   for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
167   {
168     switch (aNodeIter->type)
169     {
170       case TelMarker:
171       case TelMarkerSet:
172       case TelText:
173       {
174         glDisable (GL_LIGHTING);
175         if (isImmediate)
176         {
177           glDepthMask (GL_FALSE);
178         }
179
180         aNodeIter->elem->Render (theWorkspace);
181         break;
182       }
183       default:
184       {
185         aNodeIter->elem->Render (theWorkspace);
186         break;
187       }
188     }
189   }
190
191   // Restore aspects
192   theWorkspace->SetAspectLine   (aBackAspectLine);
193   theWorkspace->SetAspectFace   (aBackAspectFace);
194   theWorkspace->SetAspectMarker (aBackAspectMarker);
195   theWorkspace->SetAspectText   (aBackAspectText);
196 }
197
198 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
199 {
200   // Delete elements
201   while (myFirst != NULL)
202   {
203     OpenGl_ElementNode* aNext = myFirst->next;
204     OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
205     delete myFirst;
206     myFirst = aNext;
207   }
208   myLast = NULL;
209
210   OpenGl_Element::Destroy (theGlCtx, myAspectLine);
211   OpenGl_Element::Destroy (theGlCtx, myAspectFace);
212   OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
213   OpenGl_Element::Destroy (theGlCtx, myAspectText);
214 }