1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_Group.hxx>
18 #include <OpenGl_GraphicDriver.hxx>
19 #include <OpenGl_Flipper.hxx>
20 #include <OpenGl_PrimitiveArray.hxx>
21 #include <OpenGl_StencilTest.hxx>
22 #include <OpenGl_Structure.hxx>
23 #include <OpenGl_Text.hxx>
24 #include <OpenGl_Workspace.hxx>
26 #include <Graphic3d_ArrayOfPrimitives.hxx>
27 #include <Graphic3d_CUserDraw.hxx>
28 #include <Graphic3d_GroupDefinitionError.hxx>
31 // =======================================================================
32 // function : OpenGl_Group
34 // =======================================================================
35 OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct)
36 : Graphic3d_Group (theStruct),
43 myIsRaytracable (Standard_False)
45 Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
48 Graphic3d_GroupDefinitionError::Raise ("OpenGl_Group should be created by OpenGl_Structure!");
52 // =======================================================================
53 // function : ~OpenGl_Group
55 // =======================================================================
56 OpenGl_Group::~OpenGl_Group()
58 Release (Handle(OpenGl_Context)());
61 // =======================================================================
62 // function : UpdateAspectLine
64 // =======================================================================
65 void OpenGl_Group::UpdateAspectLine (const Standard_Boolean theIsGlobal)
67 if (!ContextLine.IsDef)
72 if (theIsGlobal || myFirst == NULL)
74 if (myAspectLine == NULL)
76 myAspectLine = new OpenGl_AspectLine();
78 myAspectLine->SetAspect (ContextLine);
82 OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
83 anAspectLine->SetAspect (ContextLine);
84 AddElement (anAspectLine);
88 // =======================================================================
89 // function : UpdateAspectFace
91 // =======================================================================
92 void OpenGl_Group::UpdateAspectFace (const Standard_Boolean theIsGlobal)
94 if (!ContextFillArea.IsDef)
99 if (theIsGlobal || myFirst == NULL)
101 if (myAspectFace == NULL)
103 myAspectFace = new OpenGl_AspectFace();
105 myAspectFace->SetAspect (ContextFillArea);
109 OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
110 anAspectFace->SetAspect (ContextFillArea);
111 AddElement (anAspectFace);
116 OpenGl_Structure* aStruct = GlStruct();
119 aStruct->UpdateStateIfRaytracable (Standard_False);
124 // =======================================================================
125 // function : UpdateAspectMarker
127 // =======================================================================
128 void OpenGl_Group::UpdateAspectMarker (const Standard_Boolean theIsGlobal)
130 if (!ContextMarker.IsDef)
135 if (theIsGlobal || myFirst == NULL)
137 if (myAspectMarker == NULL)
139 myAspectMarker = new OpenGl_AspectMarker();
141 myAspectMarker->SetAspect (ContextMarker);
145 OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
146 anAspectMarker->SetAspect (ContextMarker);
147 AddElement (anAspectMarker);
151 // =======================================================================
152 // function : UpdateAspectText
154 // =======================================================================
155 void OpenGl_Group::UpdateAspectText (const Standard_Boolean theIsGlobal)
157 if (!ContextText.IsDef)
162 if (theIsGlobal || myFirst == NULL)
164 if (myAspectText == NULL)
166 myAspectText = new OpenGl_AspectText();
168 myAspectText->SetAspect (ContextText);
172 OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
173 anAspectText->SetAspect (ContextText);
174 AddElement (anAspectText);
178 // =======================================================================
179 // function : AddPrimitiveArray
181 // =======================================================================
182 void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
183 const Handle(Graphic3d_IndexBuffer)& theIndices,
184 const Handle(Graphic3d_Buffer)& theAttribs,
185 const Handle(Graphic3d_BoundBuffer)& theBounds,
186 const Standard_Boolean theToEvalMinMax)
189 || theAttribs.IsNull())
194 OpenGl_Structure* aStruct = GlStruct();
195 const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver();
197 OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds);
198 AddElement (anArray);
200 Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
203 // =======================================================================
206 // =======================================================================
207 void OpenGl_Group::Text (const Standard_CString theTextUtf,
208 const Graphic3d_Vertex& thePoint,
209 const Standard_Real theHeight,
210 const Quantity_PlaneAngle theAngle,
211 const Graphic3d_TextPath theTp,
212 const Graphic3d_HorizontalTextAlignment theHta,
213 const Graphic3d_VerticalTextAlignment theVta,
214 const Standard_Boolean theToEvalMinMax)
221 OpenGl_TextParam aParams;
222 OpenGl_Structure* aStruct = GlStruct();
223 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
224 aParams.HAlign = theHta;
225 aParams.VAlign = theVta;
226 const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
227 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, aPoint, aParams);
229 Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle,
230 theTp, theHta, theVta, theToEvalMinMax);
233 // =======================================================================
234 // function : UserDraw
236 // =======================================================================
237 void OpenGl_Group::UserDraw (const Standard_Address theObject,
238 const Standard_Boolean theToEvalMinMax,
239 const Standard_Boolean theContainsFacet)
246 OpenGl_Structure* aStruct = GlStruct();
247 if (aStruct->GlDriver()->UserDrawCallback() == NULL)
252 Graphic3d_CUserDraw aUserDraw;
253 aUserDraw.Data = theObject;
254 aUserDraw.Bounds = theToEvalMinMax ? &myBounds : NULL;
255 OpenGl_Element* aUserDrawElem = aStruct->GlDriver()->UserDrawCallback()(&aUserDraw);
256 if (aUserDrawElem != NULL)
258 AddElement (aUserDrawElem);
260 Graphic3d_Group::UserDraw (theObject, theToEvalMinMax, theContainsFacet);
263 // =======================================================================
264 // function : SetFlippingOptions
266 // =======================================================================
267 void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
268 const gp_Ax2& theRefPlane)
270 OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
271 aFlipper->SetOptions (theIsEnabled);
272 AddElement (aFlipper);
275 // =======================================================================
276 // function : SetStencilTestOptions
278 // =======================================================================
279 void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled)
281 OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest();
282 aStencilTest->SetOptions (theIsEnabled);
283 AddElement (aStencilTest);
286 // =======================================================================
287 // function : AddElement
289 // =======================================================================
290 void OpenGl_Group::AddElement (OpenGl_Element* theElem)
292 OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
294 aNode->elem = theElem;
296 (myLast? myLast->next : myFirst) = aNode;
299 if (OpenGl_Raytrace::IsRaytracedElement (aNode))
301 myIsRaytracable = Standard_True;
303 OpenGl_Structure* aStruct = GlStruct();
306 aStruct->UpdateStateIfRaytracable (Standard_False);
311 // =======================================================================
314 // =======================================================================
315 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
317 // Is rendering in ADD or IMMEDIATE mode?
318 const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
321 const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine (Standard_False);
322 const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace (Standard_False);
323 const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
324 const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText (Standard_False);
325 Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter);
326 Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter);
327 Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
328 Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter);
330 // Render group elements
331 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
333 aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
338 theWorkspace->SetAspectLine (aBackAspectLine);
340 theWorkspace->SetAspectFace (aBackAspectFace);
342 theWorkspace->SetAspectMarker (aBackAspectMarker);
344 theWorkspace->SetAspectText (aBackAspectText);
347 // =======================================================================
350 // =======================================================================
351 void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
358 OpenGl_Structure* aStruct = GlStruct();
359 const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
362 Graphic3d_Group::Clear (theToUpdateStructureMgr);
364 myIsRaytracable = Standard_False;
367 // =======================================================================
368 // function : Release
370 // =======================================================================
371 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
374 while (myFirst != NULL)
376 OpenGl_ElementNode* aNext = myFirst->next;
377 OpenGl_Element::Destroy (theGlCtx.operator->(), myFirst->elem);
383 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine);
384 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace);
385 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
386 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);