0023243: Adapt OpenGL viewer for using in Cocoa applications on Mac OS X
[occt.git] / src / OpenGl / OpenGl_Group.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
SK
20#include <OpenGl_Group.hxx>
21
2166f0fa 22#include <OpenGl_PrimitiveArray.hxx>
bf75be98 23#include <OpenGl_Workspace.hxx>
2166f0fa
SK
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{
5e27df78 38 Release (Handle(OpenGl_Context)());
2166f0fa
SK
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
bf75be98 62void OpenGl_Group::SetAspectFace (const Handle(OpenGl_Context)& theCtx,
63 const CALL_DEF_CONTEXTFILLAREA& theAspect,
64 const Standard_Boolean theIsGlobal)
2166f0fa
SK
65{
66 if (theIsGlobal || myFirst == NULL)
67 {
68 if (myAspectFace == NULL)
bf75be98 69 {
2166f0fa 70 myAspectFace = new OpenGl_AspectFace();
bf75be98 71 }
72 myAspectFace->Init (theCtx, theAspect);
2166f0fa
SK
73 }
74 else
75 {
76 OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
bf75be98 77 anAspectFace->Init (theCtx, theAspect);
2166f0fa
SK
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
5e27df78 135void OpenGl_Group::RemovePrimitiveArray (const Handle(OpenGl_Context)& theGlCtx,
136 CALL_DEF_PARRAY* thePArray)
2166f0fa
SK
137{
138 OpenGl_ElementNode *prevnode = NULL, *node = myFirst;
5e27df78 139 while (node != NULL)
2166f0fa
SK
140 {
141 if (node->type == TelParray)
142 {
5e27df78 143 CALL_DEF_PARRAY* aCurPArray = ((const OpenGl_PrimitiveArray* )node->elem)->PArray();
2166f0fa
SK
144
145 // validate for correct pointer
bf75be98 146 if (aCurPArray->num_bounds == thePArray->num_bounds &&
5e27df78 147 aCurPArray->num_edges == thePArray->num_edges &&
148 aCurPArray->num_vertexs == thePArray->num_vertexs &&
149 aCurPArray->type == thePArray->type)
2166f0fa 150 {
5e27df78 151 (prevnode ? prevnode->next : myFirst) = node->next;
2166f0fa 152 if (!myFirst) myLast = NULL;
5e27df78 153 OpenGl_Element::Destroy (theGlCtx, node->elem);
2166f0fa
SK
154 delete node;
155 break;
156 }
157 }
158 prevnode = node;
159 node = node->next;
160 }
161}
162
163/*----------------------------------------------------------------------*/
164
bf75be98 165void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
2166f0fa
SK
166{
167 // Is rendering in ADD or IMMEDIATE mode?
bf75be98 168 const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
2166f0fa
SK
169
170 // Setup aspects
bf75be98 171 const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine (Standard_False);
172 const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace (Standard_False);
173 const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
174 const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText (Standard_False);
2166f0fa 175 if (myAspectLine)
bf75be98 176 {
177 theWorkspace->SetAspectLine (myAspectLine);
178 }
2166f0fa 179 if (myAspectFace)
bf75be98 180 {
181 theWorkspace->SetAspectFace (myAspectFace);
182 }
2166f0fa 183 if (myAspectMarker)
bf75be98 184 {
185 theWorkspace->SetAspectMarker (myAspectMarker);
186 }
2166f0fa 187 if (myAspectText)
bf75be98 188 {
189 theWorkspace->SetAspectText (myAspectText);
190 }
2166f0fa
SK
191
192 // Render group elements
bf75be98 193 Handle(OpenGl_Texture) aPrevTexture; // temporary disabled texture
194 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
2166f0fa 195 {
bf75be98 196 switch (aNodeIter->type)
2166f0fa
SK
197 {
198 case TelPolyline:
199 case TelMarker:
200 case TelMarkerSet:
201 case TelText:
202 {
bf75be98 203 glDisable (GL_LIGHTING);
2166f0fa
SK
204
205 if (isImmediate)
206 {
bf75be98 207 glDepthMask (GL_FALSE);
2166f0fa 208 }
bf75be98 209 else if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
210 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
211 theWorkspace->DegenerateModel != 0)
2166f0fa 212 {
bf75be98 213 glDisable (GL_DEPTH_TEST);
214 if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
215 {
216 aPrevTexture = theWorkspace->DisableTexture();
217 }
218 theWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
2166f0fa
SK
219 }
220
bf75be98 221 if (!aPrevTexture.IsNull())
222 {
223 theWorkspace->EnableTexture (aPrevTexture);
224 aPrevTexture.Nullify();
225 }
2166f0fa 226
bf75be98 227 aNodeIter->elem->Render (theWorkspace);
2166f0fa
SK
228 break;
229 }
230
231 case TelPolygon:
232 case TelPolygonIndices:
233 case TelQuadrangle:
234 case TelTriangleMesh:
235 {
236 if (isImmediate)
237 {
238 glDepthMask(GL_FALSE);
239 }
bf75be98 240 else if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
241 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
242 theWorkspace->DegenerateModel < 2)
2166f0fa 243 {
bf75be98 244 glEnable (GL_DEPTH_TEST);
245 theWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
2166f0fa
SK
246 }
247
bf75be98 248 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
249 {
250 theWorkspace->DisablePolygonOffset();
251 }
2166f0fa 252
bf75be98 253 aNodeIter->elem->Render (theWorkspace);
2166f0fa 254
bf75be98 255 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
256 {
257 theWorkspace->EnablePolygonOffset();
258 }
2166f0fa
SK
259 break;
260 }
261
262 default:
263 {
bf75be98 264 aNodeIter->elem->Render (theWorkspace);
2166f0fa
SK
265 break;
266 }
267 }
2166f0fa
SK
268 }
269
270 // Restore aspects
bf75be98 271 theWorkspace->SetAspectLine (aBackAspectLine);
272 theWorkspace->SetAspectFace (aBackAspectFace);
273 theWorkspace->SetAspectMarker (aBackAspectMarker);
274 theWorkspace->SetAspectText (aBackAspectText);
2166f0fa
SK
275}
276
5e27df78 277void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
278{
279 // Delete elements
280 while (myFirst != NULL)
281 {
282 OpenGl_ElementNode* aNext = myFirst->next;
283 OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
284 delete myFirst;
285 myFirst = aNext;
286 }
287 myLast = NULL;
288
289 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
290 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
291 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
292 OpenGl_Element::Destroy (theGlCtx, myAspectText);
293}