0026641: Visualization, TKOpenGl - handle correctly transformation persistence within...
[occt.git] / src / OpenGl / OpenGl_Layer.cxx
CommitLineData
c5751993 1// Created on: 2014-03-31
2// Created by: Danila ULYANOV
3// Copyright (c) 2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
0a36ca0a 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
c5751993 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.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <OpenGl_Layer.hxx>
a1954302 17
18#include <OpenGl_BVHTreeSelector.hxx>
19#include <OpenGl_Structure.hxx>
20#include <OpenGl_View.hxx>
550f3b8b 21#include <OpenGl_Workspace.hxx>
c04c30b3 22#include <Graphic3d_GraphicDriver.hxx>
c5751993 23
a1954302 24// =======================================================================
825aa485 25// function : OpenGl_Layer
a1954302 26// purpose :
27// =======================================================================
c5751993 28OpenGl_Layer::OpenGl_Layer (const Standard_Integer theNbPriorities)
50d06d8f 29: myArray (0, theNbPriorities - 1),
30 myNbStructures (0),
a1954302 31 myBVHIsLeftChildQueuedFirst (Standard_True),
32 myIsBVHPrimitivesNeedsReset (Standard_False)
c5751993 33{
50d06d8f 34 myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true;
c5751993 35}
36
a1954302 37// =======================================================================
38// function : ~OpenGl_Layer
39// purpose :
40// =======================================================================
41OpenGl_Layer::~OpenGl_Layer()
42{
43 //
44}
45
46// =======================================================================
47// function : Add
48// purpose :
49// =======================================================================
50void OpenGl_Layer::Add (const OpenGl_Structure* theStruct,
51 const Standard_Integer thePriority,
52 Standard_Boolean isForChangePriority)
53{
54 const Standard_Integer anIndex = Min (Max (thePriority, 0), myArray.Length() - 1);
55 if (theStruct == NULL)
56 {
57 return;
58 }
59
9f112210 60 myArray (anIndex).Add (theStruct);
a1954302 61 if (theStruct->IsAlwaysRendered())
62 {
63 theStruct->MarkAsNotCulled();
64 }
65 else if (!isForChangePriority)
66 {
97f937cc 67 if (theStruct->TransformPersistence.Flags == Graphic3d_TMF_None)
825aa485 68 {
69 myBVHPrimitives.Add (theStruct);
70 }
71 else
72 {
73 myBVHPrimitivesTrsfPers.Add (theStruct);
74 }
a1954302 75 }
76 ++myNbStructures;
77}
78
79// =======================================================================
80// function : Remove
81// purpose :
82// =======================================================================
83bool OpenGl_Layer::Remove (const OpenGl_Structure* theStruct,
84 Standard_Integer& thePriority,
85 Standard_Boolean isForChangePriority)
86{
87 if (theStruct == NULL)
88 {
89 thePriority = -1;
90 return false;
91 }
92
93 const Standard_Integer aNbPriorities = myArray.Length();
94 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
95 {
9f112210 96 OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
97
98 const Standard_Integer anIndex = aStructures.FindIndex (theStruct);
99 if (anIndex != 0)
a1954302 100 {
9f112210 101 aStructures.Swap (anIndex, aStructures.Size());
102 aStructures.RemoveLast();
103
104 if (!theStruct->IsAlwaysRendered()
105 && !isForChangePriority)
a1954302 106 {
825aa485 107 if (!myBVHPrimitives.Remove (theStruct))
108 {
109 myBVHPrimitivesTrsfPers.Remove (theStruct);
110 }
a1954302 111 }
9f112210 112 --myNbStructures;
113 thePriority = aPriorityIter;
114 return true;
a1954302 115 }
116 }
117
118 thePriority = -1;
119 return false;
120}
121
122// =======================================================================
123// function : InvalidateBVHData
124// purpose :
125// =======================================================================
50d06d8f 126void OpenGl_Layer::InvalidateBVHData() const
a1954302 127{
128 myIsBVHPrimitivesNeedsReset = Standard_True;
129}
130
131// =======================================================================
50d06d8f 132// function : BoundingBox
133// purpose :
134// =======================================================================
135const Graphic3d_BndBox4f& OpenGl_Layer::BoundingBox (const Standard_Integer theViewId,
136 const Handle(Graphic3d_Camera)& theCamera,
137 const Standard_Integer theWindowWidth,
138 const Standard_Integer theWindowHeight,
139 const Standard_Boolean theToIgnoreInfiniteFlag) const
140{
141 const Standard_Integer aBoxId = theToIgnoreInfiniteFlag == 0 ? 0 : 1;
142
143 if (myIsBoundingBoxNeedsReset[aBoxId])
144 {
145 // Recompute layer bounding box
146 myBoundingBox[aBoxId].Clear();
147
148 const Standard_Integer aNbPriorities = myArray.Length();
149 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
150 {
151 const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
152 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
153 {
154 const OpenGl_Structure* aStructure = aStructures.FindKey (aStructIdx);
155 if (!aStructure->IsVisible())
156 {
157 continue;
158 }
159 else if (!aStructure->ViewAffinity.IsNull()
160 && !aStructure->ViewAffinity->IsVisible (theViewId))
161 {
162 continue;
163 }
164
165 // "FitAll" operation ignores object with transform persistence parameter
166 // but adds transform persistence point in a bounding box of layer (only zoom pers. objects).
167 if (aStructure->TransformPersistence.Flags != Graphic3d_TMF_None)
168 {
169 if (!theToIgnoreInfiniteFlag && (aStructure->TransformPersistence.Flags & Graphic3d_TMF_ZoomPers))
170 {
50d06d8f 171 BVH_Vec4f aTPPoint (static_cast<float> (aStructure->TransformPersistence.Point.x()),
172 static_cast<float> (aStructure->TransformPersistence.Point.y()),
173 static_cast<float> (aStructure->TransformPersistence.Point.z()),
174 1.0f);
175
176 myBoundingBox[aBoxId].Combine (aTPPoint);
177 continue;
178 }
179 // Panning and 2d persistence apply changes to projection or/and its translation components.
180 // It makes them incompatible with z-fitting algorithm. Ignored by now.
181 else if (!theToIgnoreInfiniteFlag
182 || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_2d)
183 || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_PanPers)
184 || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_TriedronPers))
185 {
186 continue;
187 }
188 }
189
190 Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
191
192 if (aStructure->IsInfinite
193 && !theToIgnoreInfiniteFlag)
194 {
195 const Graphic3d_Vec4 aDiagVec = aBox.CornerMax() - aBox.CornerMin();
196 if (aDiagVec.xyz().SquareModulus() >= 500000.0f * 500000.0f)
197 {
198 // bounding borders of infinite line has been calculated as own point in center of this line
199 aBox = Graphic3d_BndBox4f ((aBox.CornerMin() + aBox.CornerMax()) * 0.5f);
200 }
201 else
202 {
203 aBox = Graphic3d_BndBox4f (Graphic3d_Vec4 (ShortRealFirst(), ShortRealFirst(), ShortRealFirst(), 1.0f),
204 Graphic3d_Vec4 (ShortRealLast(), ShortRealLast(), ShortRealLast(), 1.0f));
205 }
206 }
207
208 if (aStructure->TransformPersistence.Flags != Graphic3d_TMF_None)
209 {
210 const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
211 const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
212
213 aStructure->TransformPersistence.Apply (aProjectionMat,
214 aWorldViewMat,
215 theWindowWidth,
216 theWindowHeight,
217 aBox);
218 }
219
220 // To prevent float overflow at camera parameters calculation and further
221 // rendering, bounding boxes with at least one vertex coordinate out of
222 // float range are skipped by view fit algorithms
223 if (Abs (aBox.CornerMax().x()) >= ShortRealLast()
224 || Abs (aBox.CornerMax().y()) >= ShortRealLast()
225 || Abs (aBox.CornerMax().z()) >= ShortRealLast()
226 || Abs (aBox.CornerMin().x()) >= ShortRealLast()
227 || Abs (aBox.CornerMin().y()) >= ShortRealLast()
228 || Abs (aBox.CornerMin().z()) >= ShortRealLast())
229 {
230 continue;
231 }
232
233 myBoundingBox[aBoxId].Combine (aBox);
234 }
235 }
236
237 myIsBoundingBoxNeedsReset[aBoxId] = false;
238 }
239
240 return myBoundingBox[aBoxId];
241}
242
243// =======================================================================
244// function : considerZoomPersistenceObjects
245// purpose :
246// =======================================================================
247Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integer theViewId,
248 const Handle(Graphic3d_Camera)& theCamera,
249 Standard_Integer theWindowWidth,
250 Standard_Integer theWindowHeight,
251 Standard_Boolean /*theToIgnoreInfiniteFlag*/) const
252{
253 if (NbOfTransformPersistenceObjects() == 0)
254 {
255 return 1.0;
256 }
257
258 const Standard_Integer aNbPriorities = myArray.Length();
259 const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
260 const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
261 Standard_Real aMaxCoef = -std::numeric_limits<double>::max();
262
263 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
264 {
265 const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
266 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
267 {
268 OpenGl_Structure* aStructure = const_cast<OpenGl_Structure*> (aStructures.FindKey (aStructIdx));
269 if (!aStructure->IsVisible())
270 {
271 continue;
272 }
273 else if (!aStructure->ViewAffinity.IsNull()
274 && !aStructure->ViewAffinity->IsVisible (theViewId))
275 {
276 continue;
277 }
278
279 if (!(aStructure->TransformPersistence.Flags & Graphic3d_TMF_ZoomPers))
280 {
281 continue;
282 }
283
284 Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
285 aStructure->TransformPersistence.Apply (aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
286
287 const BVH_Vec4f& aCornerMin = aBox.CornerMin();
288 const BVH_Vec4f& aCornerMax = aBox.CornerMax();
289 const Standard_Integer aNbOfPoints = 8;
290 const gp_Pnt aPoints[aNbOfPoints] = { gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMin.z()),
291 gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMax.z()),
292 gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMin.z()),
293 gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMax.z()),
294 gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMin.z()),
295 gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMax.z()),
296 gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMin.z()),
297 gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMax.z()) };
298 gp_Pnt aConvertedPoints[aNbOfPoints];
299 Standard_Real aConvertedMinX = std::numeric_limits<double>::max();
300 Standard_Real aConvertedMaxX = -std::numeric_limits<double>::max();
301 Standard_Real aConvertedMinY = std::numeric_limits<double>::max();
302 Standard_Real aConvertedMaxY = -std::numeric_limits<double>::max();
303 for (Standard_Integer anIdx = 0; anIdx < aNbOfPoints; ++anIdx)
304 {
305 aConvertedPoints[anIdx] = theCamera->Project (aPoints[anIdx]);
306
307 aConvertedMinX = Min (aConvertedMinX, aConvertedPoints[anIdx].X());
308 aConvertedMaxX = Max (aConvertedMaxX, aConvertedPoints[anIdx].X());
309
310 aConvertedMinY = Min (aConvertedMinY, aConvertedPoints[anIdx].Y());
311 aConvertedMaxY = Max (aConvertedMaxY, aConvertedPoints[anIdx].Y());
312 }
313
314 const Standard_Boolean isBigObject = (Abs (aConvertedMaxX - aConvertedMinX) > 2.0) // width of zoom pers. object greater than width of window
315 || (Abs (aConvertedMaxY - aConvertedMinY) > 2.0); // height of zoom pers. object greater than height of window
316 const Standard_Boolean isAlreadyInScreen = (aConvertedMinX > -1.0 && aConvertedMinX < 1.0)
317 && (aConvertedMaxX > -1.0 && aConvertedMaxX < 1.0)
318 && (aConvertedMinY > -1.0 && aConvertedMinY < 1.0)
319 && (aConvertedMaxY > -1.0 && aConvertedMaxY < 1.0);
320 if (isBigObject || isAlreadyInScreen)
321 {
322 continue;
323 }
324
325 const gp_Pnt aTPPoint (aStructure->TransformPersistence.Point.x(),
326 aStructure->TransformPersistence.Point.y(),
327 aStructure->TransformPersistence.Point.z());
328 gp_Pnt aConvertedTPPoint = theCamera->Project (aTPPoint);
329 aConvertedTPPoint.SetZ (0.0);
330
331 if (aConvertedTPPoint.Coord().Modulus() < Precision::Confusion())
332 {
333 continue;
334 }
335
336 Standard_Real aShiftX = 0.0;
337 if (aConvertedMinX < -1.0)
338 {
339 aShiftX = ((aConvertedMaxX < -1.0) ? (-(1.0 + aConvertedMaxX) + (aConvertedMaxX - aConvertedMinX)) : -(1.0 + aConvertedMinX));
340 }
341 else if (aConvertedMaxX > 1.0)
342 {
343 aShiftX = ((aConvertedMinX > 1.0) ? ((aConvertedMinX - 1.0) + (aConvertedMaxX - aConvertedMinX)) : (aConvertedMaxX - 1.0));
344 }
345
346 Standard_Real aShiftY = 0.0;
347 if (aConvertedMinY < -1.0)
348 {
349 aShiftY = ((aConvertedMaxY < -1.0) ? (-(1.0 + aConvertedMaxY) + (aConvertedMaxY - aConvertedMinY)) : -(1.0 + aConvertedMinY));
350 }
351 else if (aConvertedMaxY > 1.0)
352 {
353 aShiftY = ((aConvertedMinY > 1.0) ? ((aConvertedMinY - 1.0) + (aConvertedMaxY - aConvertedMinY)) : (aConvertedMaxY - 1.0));
354 }
355
356 const Standard_Real aDifX = Abs (aConvertedTPPoint.X()) - aShiftX;
357 const Standard_Real aDifY = Abs (aConvertedTPPoint.Y()) - aShiftY;
358 if (aDifX > Precision::Confusion())
359 {
360 aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.X()) / aDifX);
361 }
362 if (aDifY > Precision::Confusion())
363 {
364 aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.Y()) / aDifY);
365 }
366 }
367 }
368
369 return (aMaxCoef > 0.0) ? aMaxCoef : 1.0;
370}
371
372// =======================================================================
a1954302 373// function : renderAll
374// purpose :
375// =======================================================================
376void OpenGl_Layer::renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const
377{
378 const Standard_Integer aNbPriorities = myArray.Length();
c357e426 379 const Standard_Integer aViewId = theWorkspace->View()->Identification();
a1954302 380 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
381 {
9f112210 382 const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
383 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
a1954302 384 {
9f112210 385 const OpenGl_Structure* aStruct = aStructures.FindKey (aStructIdx);
a1954302 386 if (!aStruct->IsVisible())
387 {
388 continue;
389 }
a272ed94 390 else if (!aStruct->ViewAffinity.IsNull()
391 && !aStruct->ViewAffinity->IsVisible (aViewId))
392 {
393 continue;
394 }
a1954302 395
396 aStruct->Render (theWorkspace);
397 }
398 }
399}
400
401// =======================================================================
402// function : renderTraverse
403// purpose :
404// =======================================================================
405void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const
406{
407 if (myIsBVHPrimitivesNeedsReset)
408 {
825aa485 409 myBVHPrimitives.Clear();
410 myBVHPrimitivesTrsfPers.Clear();
a1954302 411 myIsBVHPrimitivesNeedsReset = Standard_False;
825aa485 412 for (Standard_Integer aPriorityIdx = 0, aNbPriorities = myArray.Length(); aPriorityIdx < aNbPriorities; ++aPriorityIdx)
413 {
414 for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (myArray (aPriorityIdx)); aStructIter.More(); aStructIter.Next())
415 {
416 const OpenGl_Structure* aStruct = aStructIter.Value();
417
418 if (aStruct->IsAlwaysRendered())
419 continue;
420
97f937cc 421 if (aStruct->TransformPersistence.Flags == Graphic3d_TMF_None)
825aa485 422 {
423 myBVHPrimitives.Add (aStruct);
424 }
425 else
426 {
427 myBVHPrimitivesTrsfPers.Add (aStruct);
428 }
429 }
430 }
a1954302 431 }
432
c357e426 433 OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector();
a1954302 434 traverse (aSelector);
435
436 const Standard_Integer aNbPriorities = myArray.Length();
c357e426 437 const Standard_Integer aViewId = theWorkspace->View()->Identification();
a1954302 438 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
439 {
9f112210 440 const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
441 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
a1954302 442 {
9f112210 443 const OpenGl_Structure* aStruct = aStructures.FindKey (aStructIdx);
a1954302 444 if (!aStruct->IsVisible()
445 || aStruct->IsCulled())
446 {
447 continue;
448 }
a272ed94 449 else if (!aStruct->ViewAffinity.IsNull()
450 && !aStruct->ViewAffinity->IsVisible (aViewId))
451 {
452 continue;
453 }
a1954302 454
455 aStruct->Render (theWorkspace);
456 aStruct->ResetCullingStatus();
457 }
458 }
459}
460
461// =======================================================================
462// function : traverse
463// purpose :
464// =======================================================================
465void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
466{
467 // handle a case when all objects are infinite
97f937cc 468 if (myBVHPrimitives .Size() == 0
469 && myBVHPrimitivesTrsfPers.Size() == 0)
a1954302 470 return;
471
a1954302 472 theSelector.CacheClipPtsProjections();
a1954302 473
825aa485 474 NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> > aBVHTree;
475
476 for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
a1954302 477 {
825aa485 478 const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1;
479 if (isTrsfPers)
a1954302 480 {
825aa485 481 if (myBVHPrimitivesTrsfPers.Size() == 0)
825aa485 482 continue;
97f937cc 483
484 const OpenGl_Mat4& aProjection = theSelector.ProjectionMatrix();
485 const OpenGl_Mat4& aWorldView = theSelector.WorldViewMatrix();
825aa485 486 const Graphic3d_WorldViewProjState& aWVPState = theSelector.WorldViewProjState();
91d96372 487 const Standard_Integer aViewportWidth = theSelector.ViewportWidth();
488 const Standard_Integer aViewportHeight = theSelector.ViewportHeight();
489
490 aBVHTree = myBVHPrimitivesTrsfPers.BVH (aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
825aa485 491 }
492 else
493 {
494 if (myBVHPrimitives.Size() == 0)
825aa485 495 continue;
97f937cc 496
825aa485 497 aBVHTree = myBVHPrimitives.BVH();
498 }
499
500 Standard_Integer aNode = 0; // a root node
501
502 if (!theSelector.Intersect (aBVHTree->MinPoint (0),
503 aBVHTree->MaxPoint (0)))
504 {
505 continue;
506 }
507
508 Standard_Integer aStack[32];
509 Standard_Integer aHead = -1;
510 for (;;)
511 {
512 if (!aBVHTree->IsOuter (aNode))
a1954302 513 {
f2474958 514 const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
515 const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
825aa485 516 const Standard_Boolean isLeftChildIn = theSelector.Intersect (aBVHTree->MinPoint (aLeftChildIdx),
517 aBVHTree->MaxPoint (aLeftChildIdx));
518 const Standard_Boolean isRightChildIn = theSelector.Intersect (aBVHTree->MinPoint (aRightChildIdx),
519 aBVHTree->MaxPoint (aRightChildIdx));
520 if (isLeftChildIn
521 && isRightChildIn)
522 {
523 aNode = myBVHIsLeftChildQueuedFirst ? aLeftChildIdx : aRightChildIdx;
524 aStack[++aHead] = myBVHIsLeftChildQueuedFirst ? aRightChildIdx : aLeftChildIdx;
525 myBVHIsLeftChildQueuedFirst = !myBVHIsLeftChildQueuedFirst;
526 }
527 else if (isLeftChildIn
528 || isRightChildIn)
529 {
530 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
531 }
532 else
533 {
534 if (aHead < 0)
535 {
536 break;
537 }
538
539 aNode = aStack[aHead--];
540 }
a1954302 541 }
542 else
543 {
825aa485 544 Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode);
545 const OpenGl_Structure* aStruct =
546 isTrsfPers ? myBVHPrimitivesTrsfPers.GetStructureById (aIdx)
547 : myBVHPrimitives.GetStructureById (aIdx);
548 aStruct->MarkAsNotCulled();
a1954302 549 if (aHead < 0)
550 {
825aa485 551 break;
a1954302 552 }
553
14a35e5d 554 aNode = aStack[aHead--];
a1954302 555 }
556 }
a1954302 557 }
558}
559
560// =======================================================================
561// function : Append
562// purpose :
563// =======================================================================
564Standard_Boolean OpenGl_Layer::Append (const OpenGl_Layer& theOther)
565{
566 // the source priority list shouldn't have more priorities
567 const Standard_Integer aNbPriorities = theOther.NbPriorities();
568 if (aNbPriorities > NbPriorities())
569 {
570 return Standard_False;
571 }
572
573 // add all structures to destination priority list
574 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
575 {
9f112210 576 const OpenGl_IndexedMapOfStructure& aStructures = theOther.myArray (aPriorityIter);
577 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
a1954302 578 {
9f112210 579 Add (aStructures.FindKey (aStructIdx), aPriorityIter);
a1954302 580 }
581 }
582
583 return Standard_True;
584}
585
c5751993 586//=======================================================================
587//function : Render
a1954302 588//purpose :
c5751993 589//=======================================================================
a1954302 590void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace,
591 const OpenGl_GlobalLayerSettings& theDefaultSettings) const
c5751993 592{
550f3b8b 593 TEL_POFFSET_PARAM anAppliedOffsetParams = theWorkspace->AppliedPolygonOffset();
594
c5751993 595 // separate depth buffers
596 if (IsSettingEnabled (Graphic3d_ZLayerDepthClear))
597 {
598 glClear (GL_DEPTH_BUFFER_BIT);
599 }
eae454e3 600
c5751993 601 // handle depth test
602 if (IsSettingEnabled (Graphic3d_ZLayerDepthTest))
603 {
550f3b8b 604 // assuming depth test is enabled by default
605 glDepthFunc (theDefaultSettings.DepthFunc);
c5751993 606 }
607 else
608 {
609 glDepthFunc (GL_ALWAYS);
610 }
eae454e3 611
83da37b1 612 // save environment texture
613 Handle(OpenGl_Texture) anEnvironmentTexture = theWorkspace->EnvironmentTexture();
614 if (!myLayerSettings.UseEnvironmentTexture)
615 {
616 theWorkspace->SetEnvironmentTexture (Handle(OpenGl_Texture)());
617 }
618
c5751993 619 // handle depth offset
620 if (IsSettingEnabled (Graphic3d_ZLayerDepthOffset))
621 {
550f3b8b 622 theWorkspace->SetPolygonOffset (Aspect_POM_Fill,
623 myLayerSettings.DepthOffsetFactor,
624 myLayerSettings.DepthOffsetUnits);
c5751993 625 }
626 else
627 {
550f3b8b 628 theWorkspace->SetPolygonOffset (anAppliedOffsetParams.mode,
629 anAppliedOffsetParams.factor,
630 anAppliedOffsetParams.units);
c5751993 631 }
632
633 // handle depth write
eae454e3 634 theWorkspace->UseDepthWrite() = IsSettingEnabled (Graphic3d_ZLayerDepthWrite);
635 glDepthMask (theWorkspace->UseDepthWrite() ? GL_TRUE : GL_FALSE);
c5751993 636
637 // render priority list
a1954302 638 theWorkspace->IsCullingEnabled() ? renderTraverse (theWorkspace) : renderAll (theWorkspace);
550f3b8b 639
640 // always restore polygon offset between layers rendering
641 theWorkspace->SetPolygonOffset (anAppliedOffsetParams.mode,
642 anAppliedOffsetParams.factor,
643 anAppliedOffsetParams.units);
83da37b1 644
645 // restore environment texture
646 if (!myLayerSettings.UseEnvironmentTexture)
647 {
648 theWorkspace->SetEnvironmentTexture (anEnvironmentTexture);
649 }
c5751993 650}