0023634: Eliminate Polyline and Polygon usage in drawers
[occt.git] / src / OpenGl / OpenGl_Group.cxx
... / ...
CommitLineData
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
27OpenGl_Group::OpenGl_Group ()
28: myAspectLine(NULL),
29 myAspectFace(NULL),
30 myAspectMarker(NULL),
31 myAspectText(NULL),
32 myFirst(NULL), myLast(NULL)
33{
34}
35
36OpenGl_Group::~OpenGl_Group()
37{
38 Release (Handle(OpenGl_Context)());
39}
40
41/*----------------------------------------------------------------------*/
42
43void 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
62void 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
84void 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
103void 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
122void 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
135void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
136{
137 // Is rendering in ADD or IMMEDIATE mode?
138 const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
139
140 // Setup aspects
141 const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine (Standard_False);
142 const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace (Standard_False);
143 const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
144 const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText (Standard_False);
145 if (myAspectLine)
146 {
147 theWorkspace->SetAspectLine (myAspectLine);
148 }
149 if (myAspectFace)
150 {
151 theWorkspace->SetAspectFace (myAspectFace);
152 }
153 if (myAspectMarker)
154 {
155 theWorkspace->SetAspectMarker (myAspectMarker);
156 }
157 if (myAspectText)
158 {
159 theWorkspace->SetAspectText (myAspectText);
160 }
161
162 // Render group elements
163 Handle(OpenGl_Texture) aPrevTexture; // temporary disabled texture
164 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
165 {
166 switch (aNodeIter->type)
167 {
168 case TelPolyline:
169 case TelMarker:
170 case TelMarkerSet:
171 case TelText:
172 {
173 glDisable (GL_LIGHTING);
174
175 if (isImmediate)
176 {
177 glDepthMask (GL_FALSE);
178 }
179 else if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
180 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
181 theWorkspace->DegenerateModel != 0)
182 {
183 glDisable (GL_DEPTH_TEST);
184 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
185 {
186 aPrevTexture = theWorkspace->DisableTexture();
187 }
188 theWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
189 }
190
191 if (!aPrevTexture.IsNull())
192 {
193 theWorkspace->EnableTexture (aPrevTexture);
194 aPrevTexture.Nullify();
195 }
196
197 aNodeIter->elem->Render (theWorkspace);
198 break;
199 }
200
201 case TelPolygon:
202 case TelPolygonIndices:
203 case TelQuadrangle:
204 case TelTriangleMesh:
205 {
206 if (isImmediate)
207 {
208 glDepthMask(GL_FALSE);
209 }
210 else if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
211 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
212 theWorkspace->DegenerateModel < 2)
213 {
214 glEnable (GL_DEPTH_TEST);
215 theWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
216 }
217
218 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
219 {
220 theWorkspace->DisablePolygonOffset();
221 }
222
223 aNodeIter->elem->Render (theWorkspace);
224
225 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
226 {
227 theWorkspace->EnablePolygonOffset();
228 }
229 break;
230 }
231
232 default:
233 {
234 aNodeIter->elem->Render (theWorkspace);
235 break;
236 }
237 }
238 }
239
240 // Restore aspects
241 theWorkspace->SetAspectLine (aBackAspectLine);
242 theWorkspace->SetAspectFace (aBackAspectFace);
243 theWorkspace->SetAspectMarker (aBackAspectMarker);
244 theWorkspace->SetAspectText (aBackAspectText);
245}
246
247void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
248{
249 // Delete elements
250 while (myFirst != NULL)
251 {
252 OpenGl_ElementNode* aNext = myFirst->next;
253 OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
254 delete myFirst;
255 myFirst = aNext;
256 }
257 myLast = NULL;
258
259 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
260 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
261 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
262 OpenGl_Element::Destroy (theGlCtx, myAspectText);
263}