Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-08-01 |
2 | // Created by: Sergey ZERCHANINOV | |
973c2be1 | 3 | // Copyright (c) 2011-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
2166f0fa | 15 | |
e276548b | 16 | #include <OpenGl_Group.hxx> |
b64d84be | 17 | |
18 | #include <OpenGl_GraphicDriver.hxx> | |
19 | #include <OpenGl_Flipper.hxx> | |
2166f0fa | 20 | #include <OpenGl_PrimitiveArray.hxx> |
c357e426 | 21 | #include <OpenGl_SceneGeometry.hxx> |
b64d84be | 22 | #include <OpenGl_StencilTest.hxx> |
e276548b | 23 | #include <OpenGl_Structure.hxx> |
b64d84be | 24 | #include <OpenGl_Text.hxx> |
bf75be98 | 25 | #include <OpenGl_Workspace.hxx> |
2166f0fa | 26 | |
b64d84be | 27 | #include <Graphic3d_ArrayOfPrimitives.hxx> |
b64d84be | 28 | #include <Graphic3d_GroupDefinitionError.hxx> |
29 | ||
92efcf78 | 30 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group) |
31 | ||
1b661a81 | 32 | namespace |
33 | { | |
34 | //! Render element if it passes the filtering procedure. This method should | |
35 | //! be used for elements which can be used in scope of rendering algorithms. | |
36 | //! E.g. elements of groups during recursive rendering. | |
37 | //! If render filter is null, pure rendering is performed. | |
38 | //! @param theWorkspace [in] the rendering workspace. | |
39 | //! @param theFilter [in] the rendering filter to check whether the element | |
40 | //! should be rendered or not. | |
41 | //! @return True if element passes the check and renders, | |
42 | static bool renderFiltered (const Handle(OpenGl_Workspace)& theWorkspace, | |
43 | OpenGl_Element* theElement) | |
44 | { | |
45 | if (!theWorkspace->ShouldRender (theElement)) | |
46 | { | |
47 | return false; | |
48 | } | |
49 | ||
50 | theElement->Render (theWorkspace); | |
51 | return true; | |
52 | } | |
53 | } | |
54 | ||
4269bd1b | 55 | // ======================================================================= |
56 | // function : OpenGl_Group | |
57 | // purpose : | |
58 | // ======================================================================= | |
b64d84be | 59 | OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct) |
60 | : Graphic3d_Group (theStruct), | |
bf5f0ca2 | 61 | myAspects(NULL), |
e276548b | 62 | myFirst(NULL), |
b64d84be | 63 | myLast(NULL), |
d4aaad5b | 64 | myIsRaytracable (Standard_False) |
2166f0fa | 65 | { |
b64d84be | 66 | Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure()); |
c04c30b3 | 67 | if (aStruct.IsNull()) |
b64d84be | 68 | { |
9775fa61 | 69 | throw Graphic3d_GroupDefinitionError("OpenGl_Group should be created by OpenGl_Structure!"); |
b64d84be | 70 | } |
2166f0fa SK |
71 | } |
72 | ||
4269bd1b | 73 | // ======================================================================= |
74 | // function : ~OpenGl_Group | |
75 | // purpose : | |
76 | // ======================================================================= | |
2166f0fa SK |
77 | OpenGl_Group::~OpenGl_Group() |
78 | { | |
5e27df78 | 79 | Release (Handle(OpenGl_Context)()); |
2166f0fa SK |
80 | } |
81 | ||
4269bd1b | 82 | // ======================================================================= |
b6472664 | 83 | // function : SetGroupPrimitivesAspect |
4269bd1b | 84 | // purpose : |
85 | // ======================================================================= | |
bf5f0ca2 | 86 | void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect) |
2166f0fa | 87 | { |
b6472664 | 88 | if (IsDeleted()) |
b64d84be | 89 | { |
90 | return; | |
91 | } | |
92 | ||
bf5f0ca2 | 93 | if (myAspects == NULL) |
2166f0fa | 94 | { |
bf5f0ca2 | 95 | myAspects = new OpenGl_Aspects (theAspect); |
2166f0fa SK |
96 | } |
97 | else | |
98 | { | |
bf5f0ca2 | 99 | myAspects->SetAspect (theAspect); |
b6472664 | 100 | } |
101 | ||
bf5f0ca2 | 102 | if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL) |
b6472664 | 103 | { |
bf5f0ca2 | 104 | aStruct->UpdateStateIfRaytracable (Standard_False); |
e276548b | 105 | } |
b6472664 | 106 | |
107 | Update(); | |
2166f0fa SK |
108 | } |
109 | ||
4269bd1b | 110 | // ======================================================================= |
b6472664 | 111 | // function : SetPrimitivesAspect |
4269bd1b | 112 | // purpose : |
113 | // ======================================================================= | |
bf5f0ca2 | 114 | void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect) |
2166f0fa | 115 | { |
bf5f0ca2 | 116 | if (myAspects == NULL) |
b6472664 | 117 | { |
118 | SetGroupPrimitivesAspect (theAspect); | |
119 | return; | |
120 | } | |
121 | else if (IsDeleted()) | |
b64d84be | 122 | { |
123 | return; | |
124 | } | |
125 | ||
bf5f0ca2 | 126 | OpenGl_Aspects* anAspects = new OpenGl_Aspects (theAspect); |
127 | AddElement (anAspects); | |
b6472664 | 128 | Update(); |
2166f0fa SK |
129 | } |
130 | ||
4269bd1b | 131 | // ======================================================================= |
bf5f0ca2 | 132 | // function : SynchronizeAspects |
b6472664 | 133 | // purpose : |
134 | // ======================================================================= | |
bf5f0ca2 | 135 | void OpenGl_Group::SynchronizeAspects() |
b6472664 | 136 | { |
bf5f0ca2 | 137 | if (myAspects != NULL) |
b6472664 | 138 | { |
bf5f0ca2 | 139 | myAspects->SynchronizeAspects(); |
140 | if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL) | |
141 | { | |
142 | aStruct->UpdateStateIfRaytracable (Standard_False); | |
143 | } | |
2166f0fa | 144 | } |
bf5f0ca2 | 145 | for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next) |
2166f0fa | 146 | { |
bf5f0ca2 | 147 | aNode->elem->SynchronizeAspects(); |
b6472664 | 148 | } |
b6472664 | 149 | } |
150 | ||
151 | // ======================================================================= | |
bf5f0ca2 | 152 | // function : ReplaceAspects |
b6472664 | 153 | // purpose : |
154 | // ======================================================================= | |
bf5f0ca2 | 155 | void OpenGl_Group::ReplaceAspects (const Graphic3d_MapOfAspectsToAspects& theMap) |
b6472664 | 156 | { |
bf5f0ca2 | 157 | if (theMap.IsEmpty()) |
b6472664 | 158 | { |
159 | return; | |
2166f0fa | 160 | } |
b6472664 | 161 | |
bf5f0ca2 | 162 | Handle(Graphic3d_Aspects) anAspect; |
163 | if (myAspects != NULL | |
164 | && theMap.Find (myAspects->Aspect(), anAspect)) | |
eaac0866 | 165 | { |
bf5f0ca2 | 166 | myAspects->SetAspect (anAspect); |
167 | if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL) | |
168 | { | |
169 | aStruct->UpdateStateIfRaytracable (Standard_False); | |
170 | } | |
eaac0866 | 171 | } |
172 | for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next) | |
173 | { | |
bf5f0ca2 | 174 | OpenGl_Aspects* aGlAspect = dynamic_cast<OpenGl_Aspects*> (aNode->elem); |
175 | if (aGlAspect != NULL | |
176 | && theMap.Find (aGlAspect->Aspect(), anAspect)) | |
177 | { | |
178 | aGlAspect->SetAspect (anAspect); | |
179 | } | |
eaac0866 | 180 | } |
181 | } | |
182 | ||
b64d84be | 183 | // ======================================================================= |
184 | // function : AddPrimitiveArray | |
185 | // purpose : | |
186 | // ======================================================================= | |
871fa103 | 187 | void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType, |
188 | const Handle(Graphic3d_IndexBuffer)& theIndices, | |
189 | const Handle(Graphic3d_Buffer)& theAttribs, | |
190 | const Handle(Graphic3d_BoundBuffer)& theBounds, | |
191 | const Standard_Boolean theToEvalMinMax) | |
b64d84be | 192 | { |
193 | if (IsDeleted() | |
871fa103 | 194 | || theAttribs.IsNull()) |
b64d84be | 195 | { |
196 | return; | |
197 | } | |
198 | ||
8d3f219f | 199 | OpenGl_Structure* aStruct = GlStruct(); |
200 | const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver(); | |
201 | ||
202 | OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds); | |
b64d84be | 203 | AddElement (anArray); |
204 | ||
871fa103 | 205 | Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax); |
b64d84be | 206 | } |
207 | ||
208 | // ======================================================================= | |
8ed07085 | 209 | // function : AddText |
b64d84be | 210 | // purpose : |
211 | // ======================================================================= | |
8ed07085 | 212 | void OpenGl_Group::AddText (const Handle(Graphic3d_Text)& theTextParams, |
213 | const Standard_Boolean theToEvalMinMax) | |
b64d84be | 214 | { |
215 | if (IsDeleted()) | |
216 | { | |
217 | return; | |
218 | } | |
219 | ||
8ed07085 | 220 | if (theTextParams->Height() < 2.0) |
ce01ec26 | 221 | { |
8ed07085 | 222 | // TODO - this should be handled in different way (throw exception / take default text height without modifying Graphic3d_Text / log warning, etc.) |
223 | OpenGl_Structure* aStruct = GlStruct(); | |
224 | theTextParams->SetHeight (aStruct->GlDriver()->DefaultTextHeight()); | |
ce01ec26 | 225 | } |
8ed07085 | 226 | OpenGl_Text* aText = new OpenGl_Text (theTextParams); |
ce01ec26 | 227 | |
228 | AddElement (aText); | |
8ed07085 | 229 | Graphic3d_Group::AddText (theTextParams, theToEvalMinMax); |
ce01ec26 | 230 | } |
231 | ||
b64d84be | 232 | // ======================================================================= |
233 | // function : SetFlippingOptions | |
234 | // purpose : | |
235 | // ======================================================================= | |
236 | void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled, | |
237 | const gp_Ax2& theRefPlane) | |
238 | { | |
239 | OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane); | |
240 | aFlipper->SetOptions (theIsEnabled); | |
241 | AddElement (aFlipper); | |
242 | } | |
243 | ||
244 | // ======================================================================= | |
245 | // function : SetStencilTestOptions | |
246 | // purpose : | |
247 | // ======================================================================= | |
248 | void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled) | |
249 | { | |
250 | OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest(); | |
251 | aStencilTest->SetOptions (theIsEnabled); | |
252 | AddElement (aStencilTest); | |
253 | } | |
254 | ||
4269bd1b | 255 | // ======================================================================= |
256 | // function : AddElement | |
257 | // purpose : | |
258 | // ======================================================================= | |
5322131b | 259 | void OpenGl_Group::AddElement (OpenGl_Element* theElem) |
2166f0fa | 260 | { |
e276548b | 261 | OpenGl_ElementNode *aNode = new OpenGl_ElementNode(); |
262 | ||
e276548b | 263 | aNode->elem = theElem; |
264 | aNode->next = NULL; | |
265 | (myLast? myLast->next : myFirst) = aNode; | |
266 | myLast = aNode; | |
267 | ||
e276548b | 268 | if (OpenGl_Raytrace::IsRaytracedElement (aNode)) |
269 | { | |
e276548b | 270 | myIsRaytracable = Standard_True; |
2166f0fa | 271 | |
b64d84be | 272 | OpenGl_Structure* aStruct = GlStruct(); |
273 | if (aStruct != NULL) | |
e276548b | 274 | { |
d4aaad5b | 275 | aStruct->UpdateStateIfRaytracable (Standard_False); |
e276548b | 276 | } |
277 | } | |
2166f0fa SK |
278 | } |
279 | ||
4269bd1b | 280 | // ======================================================================= |
281 | // function : Render | |
282 | // purpose : | |
283 | // ======================================================================= | |
bf75be98 | 284 | void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const |
2166f0fa | 285 | { |
2166f0fa | 286 | // Setup aspects |
25c35042 | 287 | theWorkspace->SetAllowFaceCulling (myIsClosed |
288 | && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn()); | |
bf5f0ca2 | 289 | const OpenGl_Aspects* aBackAspects = theWorkspace->Aspects(); |
290 | const bool isAspectSet = myAspects != NULL && renderFiltered (theWorkspace, myAspects); | |
2166f0fa SK |
291 | |
292 | // Render group elements | |
bf75be98 | 293 | for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next) |
2166f0fa | 294 | { |
1b661a81 | 295 | renderFiltered (theWorkspace, aNodeIter->elem); |
2166f0fa SK |
296 | } |
297 | ||
298 | // Restore aspects | |
bf5f0ca2 | 299 | if (isAspectSet) |
300 | theWorkspace->SetAspects (aBackAspects); | |
2166f0fa SK |
301 | } |
302 | ||
b64d84be | 303 | // ======================================================================= |
304 | // function : Clear | |
305 | // purpose : | |
306 | // ======================================================================= | |
307 | void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr) | |
308 | { | |
309 | if (IsDeleted()) | |
310 | { | |
311 | return; | |
312 | } | |
313 | ||
314 | OpenGl_Structure* aStruct = GlStruct(); | |
315 | const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext(); | |
316 | ||
317 | Release (aCtx); | |
318 | Graphic3d_Group::Clear (theToUpdateStructureMgr); | |
d4aaad5b | 319 | |
320 | myIsRaytracable = Standard_False; | |
b64d84be | 321 | } |
322 | ||
4269bd1b | 323 | // ======================================================================= |
324 | // function : Release | |
325 | // purpose : | |
326 | // ======================================================================= | |
5e27df78 | 327 | void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx) |
328 | { | |
329 | // Delete elements | |
330 | while (myFirst != NULL) | |
331 | { | |
332 | OpenGl_ElementNode* aNext = myFirst->next; | |
ad67e367 | 333 | OpenGl_Element::Destroy (theGlCtx.get(), myFirst->elem); |
5e27df78 | 334 | delete myFirst; |
335 | myFirst = aNext; | |
336 | } | |
337 | myLast = NULL; | |
338 | ||
ad67e367 | 339 | OpenGl_Element::Destroy (theGlCtx.get(), myAspects); |
5e27df78 | 340 | } |