0030748: Visualization - Marker displayed in immediate layer ruins QT Quick view...
[occt.git] / src / OpenGl / OpenGl_View.cxx
1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <OpenGl_View.hxx>
17
18 #include <Aspect_RenderingContext.hxx>
19 #include <Aspect_Window.hxx>
20 #include <Graphic3d_AspectFillArea3d.hxx>
21 #include <Graphic3d_Texture2Dmanual.hxx>
22 #include <Graphic3d_TextureEnv.hxx>
23 #include <Graphic3d_Mat4d.hxx>
24 #include <NCollection_Mat4.hxx>
25 #include <OpenGl_Context.hxx>
26 #include <OpenGl_FrameBuffer.hxx>
27 #include <OpenGl_GlCore11.hxx>
28 #include <OpenGl_GraduatedTrihedron.hxx>
29 #include <OpenGl_GraphicDriver.hxx>
30 #include <OpenGl_ShaderManager.hxx>
31 #include <OpenGl_Texture.hxx>
32 #include <OpenGl_Window.hxx>
33 #include <OpenGl_Workspace.hxx>
34 #include <OSD_Parallel.hxx>
35 #include <Standard_CLocaleSentry.hxx>
36
37 #include "../Graphic3d/Graphic3d_Structure.pxx"
38
39 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,Graphic3d_CView)
40
41 // =======================================================================
42 // function : Constructor
43 // purpose  :
44 // =======================================================================
45 OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
46                           const Handle(OpenGl_GraphicDriver)& theDriver,
47                           const Handle(OpenGl_Caps)& theCaps,
48                           OpenGl_StateCounter* theCounter)
49 : Graphic3d_CView  (theMgr),
50   myDriver         (theDriver.operator->()),
51   myCaps           (theCaps),
52   myWasRedrawnGL   (Standard_False),
53   myBackfacing     (Graphic3d_TOBM_AUTOMATIC),
54   myToShowGradTrihedron  (false),
55   myZLayers        (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1),
56   myStateCounter         (theCounter),
57   myCurrLightSourceState (theCounter->Increment()),
58   myLightsRevision       (0),
59   myLastLightSourceState (0, 0),
60   myFboColorFormat       (GL_RGBA8),
61   myFboDepthFormat       (GL_DEPTH24_STENCIL8),
62   myToFlipOutput         (Standard_False),
63   myFrameCounter         (0),
64   myHasFboBlit           (Standard_True),
65   myToDisableOIT         (Standard_False),
66   myToDisableOITMSAA     (Standard_False),
67   myToDisableMSAA        (Standard_False),
68   myTransientDrawToFront (Standard_True),
69   myBackBufferRestored   (Standard_False),
70   myIsImmediateDrawn     (Standard_False),
71   myTextureParams   (new OpenGl_Aspects()),
72   myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
73   myBgTextureArray  (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)),
74   // ray-tracing fields initialization
75   myRaytraceInitStatus     (OpenGl_RT_NONE),
76   myIsRaytraceDataValid    (Standard_False),
77   myIsRaytraceWarnTextures (Standard_False),
78   myRaytraceBVHBuilder (new BVH_BinnedBuilder<Standard_ShortReal, 3, BVH_Constants_NbBinsBest> (BVH_Constants_LeafNodeSizeAverage,
79                                                                                                 BVH_Constants_MaxTreeDepth,
80                                                                                                 Standard_False,
81                                                                                                 OSD_Parallel::NbLogicalProcessors() + 1)),
82   myRaytraceSceneRadius  (0.0f),
83   myRaytraceSceneEpsilon (1.0e-6f),
84   myToUpdateEnvironmentMap (Standard_False),
85   myRaytraceLayerListState (0),
86   myPrevCameraApertureRadius(0.f),
87   myPrevCameraFocalPlaneDist(0.f)
88 {
89   myWorkspace = new OpenGl_Workspace (this, NULL);
90
91   Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT);
92   aLight->SetHeadlight (false);
93   aLight->SetColor (Quantity_NOC_WHITE);
94   myNoShadingLight = new Graphic3d_LightSet();
95   myNoShadingLight->Add (aLight);
96
97   myMainSceneFbos[0]         = new OpenGl_FrameBuffer();
98   myMainSceneFbos[1]         = new OpenGl_FrameBuffer();
99   myMainSceneFbosOit[0]      = new OpenGl_FrameBuffer();
100   myMainSceneFbosOit[1]      = new OpenGl_FrameBuffer();
101   myImmediateSceneFbos[0]    = new OpenGl_FrameBuffer();
102   myImmediateSceneFbos[1]    = new OpenGl_FrameBuffer();
103   myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer();
104   myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer();
105   myOpenGlFBO                = new OpenGl_FrameBuffer();
106   myOpenGlFBO2               = new OpenGl_FrameBuffer();
107   myRaytraceFBO1[0]          = new OpenGl_FrameBuffer();
108   myRaytraceFBO1[1]          = new OpenGl_FrameBuffer();
109   myRaytraceFBO2[0]          = new OpenGl_FrameBuffer();
110   myRaytraceFBO2[1]          = new OpenGl_FrameBuffer();
111 }
112
113 // =======================================================================
114 // function : Destructor
115 // purpose  :
116 // =======================================================================
117 OpenGl_View::~OpenGl_View()
118 {
119   ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
120   OpenGl_Element::Destroy (NULL, myBgGradientArray);
121   OpenGl_Element::Destroy (NULL, myBgTextureArray);
122   OpenGl_Element::Destroy (NULL, myTextureParams);
123 }
124
125 // =======================================================================
126 // function : ReleaseGlResources
127 // purpose  :
128 // =======================================================================
129 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
130 {
131   myGraduatedTrihedron.Release (theCtx.get());
132   myFrameStatsPrs.Release (theCtx.get());
133
134   if (!myTextureEnv.IsNull())
135   {
136     if (!theCtx.IsNull())
137     {
138       for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
139       {
140         theCtx->DelayedRelease (aTextureIter.ChangeValue());
141         aTextureIter.ChangeValue().Nullify();
142       }
143     }
144     myTextureEnv.Nullify();
145   }
146
147   if (myTextureParams != NULL)
148   {
149     myTextureParams->Release (theCtx.get());
150   }
151   if (myBgGradientArray != NULL)
152   {
153     myBgGradientArray->Release (theCtx.get());
154   }
155   if (myBgTextureArray != NULL)
156   {
157     myBgTextureArray->Release (theCtx.get());
158   }
159
160   myMainSceneFbos[0]        ->Release (theCtx.get());
161   myMainSceneFbos[1]        ->Release (theCtx.get());
162   myMainSceneFbosOit[0]     ->Release (theCtx.get());
163   myMainSceneFbosOit[1]     ->Release (theCtx.get());
164   myImmediateSceneFbos[0]   ->Release (theCtx.get());
165   myImmediateSceneFbos[1]   ->Release (theCtx.get());
166   myImmediateSceneFbosOit[0]->Release (theCtx.get());
167   myImmediateSceneFbosOit[1]->Release (theCtx.get());
168   myOpenGlFBO               ->Release (theCtx.get());
169   myOpenGlFBO2              ->Release (theCtx.get());
170   myFullScreenQuad           .Release (theCtx.get());
171   myFullScreenQuadFlip       .Release (theCtx.get());
172
173   releaseRaytraceResources (theCtx);
174 }
175
176 // =======================================================================
177 // function : Remove
178 // purpose  :
179 // =======================================================================
180 void OpenGl_View::Remove()
181 {
182   if (IsRemoved())
183   {
184     return;
185   }
186
187   myDriver->RemoveView (this);
188   myWindow.Nullify();
189
190   Graphic3d_CView::Remove();
191 }
192
193 // =======================================================================
194 // function : SetLocalOrigin
195 // purpose  :
196 // =======================================================================
197 void OpenGl_View::SetLocalOrigin (const gp_XYZ& theOrigin)
198 {
199   myLocalOrigin = theOrigin;
200   const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
201   if (!aCtx.IsNull())
202   {
203     aCtx->ShaderManager()->SetLocalOrigin (theOrigin);
204   }
205 }
206
207 // =======================================================================
208 // function : SetTextureEnv
209 // purpose  :
210 // =======================================================================
211 void OpenGl_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv)
212 {
213   Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
214   if (!aCtx.IsNull() && !myTextureEnv.IsNull())
215   {
216     for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
217     {
218       aCtx->DelayedRelease (aTextureIter.ChangeValue());
219       aTextureIter.ChangeValue().Nullify();
220     }
221   }
222
223   myToUpdateEnvironmentMap = Standard_True;
224   myTextureEnvData = theTextureEnv;
225   myTextureEnv.Nullify();
226   initTextureEnv (aCtx);
227 }
228
229 // =======================================================================
230 // function : initTextureEnv
231 // purpose  :
232 // =======================================================================
233 void OpenGl_View::initTextureEnv (const Handle(OpenGl_Context)& theContext)
234 {
235   if (myTextureEnvData.IsNull()
236     ||  theContext.IsNull()
237     || !theContext->MakeCurrent())
238   {
239     return;
240   }
241
242   myTextureEnv = new OpenGl_TextureSet (1);
243   Handle(OpenGl_Texture)& aTextureEnv = myTextureEnv->ChangeFirst();
244   aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams());
245   Handle(Image_PixMap) anImage = myTextureEnvData->GetImage();
246   if (!anImage.IsNull())
247   {
248     aTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type());
249   }
250 }
251
252 // =======================================================================
253 // function : SetImmediateModeDrawToFront
254 // purpose  :
255 // =======================================================================
256 Standard_Boolean OpenGl_View::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
257 {
258   const Standard_Boolean aPrevMode = myTransientDrawToFront;
259   myTransientDrawToFront = theDrawToFrontBuffer;
260   return aPrevMode;
261 }
262
263 // =======================================================================
264 // function : SetWindow
265 // purpose  :
266 // =======================================================================
267 void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow,
268                              const Aspect_RenderingContext theContext)
269 {
270   myWindow = myDriver->CreateRenderWindow (theWindow, theContext);
271   Standard_ASSERT_RAISE (!myWindow.IsNull(),
272                          "OpenGl_View::SetWindow, "
273                          "Failed to create OpenGl window.");
274
275   myWorkspace = new OpenGl_Workspace (this, myWindow);
276   myWorldViewProjState.Reset();
277   myToUpdateEnvironmentMap = Standard_True;
278   myHasFboBlit = Standard_True;
279   Invalidate();
280
281   // Environment texture resource does not support lazy initialization.
282   initTextureEnv (myWorkspace->GetGlContext());
283 }
284
285 // =======================================================================
286 // function : Resized
287 // purpose  :
288 // =======================================================================
289 void OpenGl_View::Resized()
290 {
291   if (myWindow.IsNull())
292     return;
293
294   myWindow->Resize();
295 }
296
297 // =======================================================================
298 // function : SetMinMaxValuesCallback
299 // purpose  :
300 // =======================================================================
301 static void SetMinMaxValuesCallback (Graphic3d_CView* theView)
302 {
303   OpenGl_View* aView = dynamic_cast<OpenGl_View*>(theView);
304   if (aView == NULL)
305     return;
306
307   Bnd_Box aBox = theView->MinMaxValues();
308   if (!aBox.IsVoid())
309   {
310     gp_Pnt aMin = aBox.CornerMin();
311     gp_Pnt aMax = aBox.CornerMax();
312
313     Graphic3d_Vec3 aMinVec ((Standard_ShortReal )aMin.X(), (Standard_ShortReal )aMin.Y(), (Standard_ShortReal )aMin.Z());
314     Graphic3d_Vec3 aMaxVec ((Standard_ShortReal )aMax.X(), (Standard_ShortReal )aMax.Y(), (Standard_ShortReal )aMax.Z());
315     aView->GraduatedTrihedronMinMaxValues (aMinVec, aMaxVec);
316   }
317 }
318
319 // =======================================================================
320 // function : GraduatedTrihedronDisplay
321 // purpose  :
322 // =======================================================================
323 void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData)
324 {
325   myGTrihedronData = theTrihedronData;
326   myGTrihedronData.PtrView = this;
327   myGTrihedronData.CubicAxesCallback = SetMinMaxValuesCallback;
328   myGraduatedTrihedron.SetValues (myGTrihedronData);
329   myToShowGradTrihedron = true;
330 }
331
332 // =======================================================================
333 // function : GraduatedTrihedronErase
334 // purpose  :
335 // =======================================================================
336 void OpenGl_View::GraduatedTrihedronErase()
337 {
338   myGTrihedronData.PtrView = NULL;
339   myGraduatedTrihedron.Release (myWorkspace->GetGlContext().operator->());
340   myToShowGradTrihedron = false;
341 }
342
343 // =======================================================================
344 // function : GraduatedTrihedronMinMaxValues
345 // purpose  :
346 // =======================================================================
347 void OpenGl_View::GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax)
348 {
349   myGraduatedTrihedron.SetMinMax (theMin, theMax);
350 }
351
352 // =======================================================================
353 // function : BufferDump
354 // purpose  :
355 // =======================================================================
356 Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType)
357 {
358   if (theBufferType != Graphic3d_BT_RGB_RayTraceHdrLeft)
359   {
360     return myWorkspace->BufferDump(myFBO, theImage, theBufferType);
361   }
362
363   if (!myRaytraceParameters.AdaptiveScreenSampling)
364   {
365     return myWorkspace->BufferDump(myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType);
366   }
367
368 #if defined(GL_ES_VERSION_2_0)
369   return false;
370 #else
371   if (theImage.Format() != Image_Format_RGBF)
372   {
373     return false;
374   }
375
376   const GLuint aW = myRaytraceOutputTexture[0]->SizeX();
377   const GLuint aH = myRaytraceOutputTexture[0]->SizeY();
378   if (aW / 3 != theImage.SizeX() || aH / 2 != theImage.SizeY())
379   {
380     return false;
381   }
382
383   std::vector<GLfloat> aValues;
384   try
385   {
386     aValues.resize (aW * aH);
387   }
388   catch (const std::bad_alloc&)
389   {
390     return false;
391   }
392
393   glBindTexture (GL_TEXTURE_RECTANGLE, myRaytraceOutputTexture[0]->TextureId());
394   glGetTexImage (GL_TEXTURE_RECTANGLE, 0, OpenGl_TextureFormat::Create<GLfloat, 1>().Format(), GL_FLOAT, &aValues[0]);
395   glBindTexture (GL_TEXTURE_RECTANGLE, 0);
396   for (unsigned int aRow = 0; aRow < aH; aRow += 2)
397   {
398     for (unsigned int aCol = 0; aCol < aW; aCol += 3)
399     {
400       float* anImageValue = theImage.ChangeValue<float[3]> ((aH - aRow) / 2 - 1, aCol / 3);
401       float aInvNbSamples = 1.f / aValues[aRow * aW + aCol + aW];
402       anImageValue[0] = aValues[aRow * aW + aCol] * aInvNbSamples;
403       anImageValue[1] = aValues[aRow * aW + aCol + 1] * aInvNbSamples;
404       anImageValue[2] = aValues[aRow * aW + aCol + 1 + aW] * aInvNbSamples;
405     }
406   }
407
408   return true;
409 #endif
410 }
411
412 // =======================================================================
413 // function : GradientBackground
414 // purpose  :
415 // =======================================================================
416 Aspect_GradientBackground OpenGl_View::GradientBackground() const
417 {
418   Quantity_Color aColor1, aColor2;
419   aColor1.SetValues (myBgGradientArray->GradientColor (0).r(),
420                      myBgGradientArray->GradientColor (0).g(),
421                      myBgGradientArray->GradientColor (0).b(), Quantity_TOC_RGB);
422   aColor2.SetValues (myBgGradientArray->GradientColor (1).r(),
423                      myBgGradientArray->GradientColor (1).g(),
424                      myBgGradientArray->GradientColor (1).b(), Quantity_TOC_RGB);
425   return Aspect_GradientBackground (aColor1, aColor2, myBgGradientArray->GradientFillMethod());
426 }
427
428 // =======================================================================
429 // function : SetGradientBackground
430 // purpose  :
431 // =======================================================================
432 void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground)
433 {
434   Quantity_Color aColor1, aColor2;
435   theBackground.Colors (aColor1, aColor2);
436   myBgGradientArray->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod());
437 }
438
439 // =======================================================================
440 // function : SetBackgroundImage
441 // purpose  :
442 // =======================================================================
443 void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath)
444 {
445   // Prepare aspect for texture storage
446   myBackgroundImagePath = theFilePath;
447   Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
448   Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
449   aTextureMap->EnableRepeat();
450   aTextureMap->DisableModulate();
451   aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
452                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
453                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
454   anAspect->SetTextureMap (aTextureMap);
455   anAspect->SetInteriorStyle (Aspect_IS_SOLID);
456   anAspect->SetSuppressBackFaces (false);
457   // Enable texture mapping
458   if (aTextureMap->IsDone())
459   {
460     anAspect->SetTextureMapOn();
461   }
462   else
463   {
464     anAspect->SetTextureMapOff();
465     return;
466   }
467
468   // Set texture parameters
469   myTextureParams->SetAspect (anAspect);
470 }
471
472 // =======================================================================
473 // function : BackgroundImageStyle
474 // purpose  :
475 // =======================================================================
476 Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const
477 {
478   return myBgTextureArray->TextureFillMethod();
479 }
480
481 // =======================================================================
482 // function : SetBackgroundImageStyle
483 // purpose  :
484 // =======================================================================
485 void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle)
486 {
487   myBgTextureArray->SetTextureFillMethod (theFillStyle);
488 }
489
490 //=======================================================================
491 //function : AddZLayer
492 //purpose  :
493 //=======================================================================
494 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
495 {
496   myZLayers.AddLayer (theLayerId);
497 }
498
499 //=======================================================================
500 //function : RemoveZLayer
501 //purpose  :
502 //=======================================================================
503 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
504 {
505   myZLayers.RemoveLayer (theLayerId);
506 }
507
508 //=======================================================================
509 //function : SetZLayerSettings
510 //purpose  :
511 //=======================================================================
512 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
513                                      const Graphic3d_ZLayerSettings& theSettings)
514 {
515   myZLayers.SetLayerSettings (theLayerId, theSettings);
516 }
517
518 //=======================================================================
519 //function : ZLayerMax
520 //purpose  :
521 //=======================================================================
522 Standard_Integer OpenGl_View::ZLayerMax() const
523 {
524   Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default;
525   for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next())
526   {
527     aLayerMax = Max (aLayerMax, aMapIt.Value());
528   }
529
530   return aLayerMax;
531 }
532
533 //=======================================================================
534 //function : InvalidateZLayerBoundingBox
535 //purpose  :
536 //=======================================================================
537 void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const
538 {
539   if (myZLayers.LayerIDs().IsBound (theLayerId))
540   {
541     myZLayers.Layer (theLayerId).InvalidateBoundingBox();
542   }
543   else
544   {
545     const Standard_Integer aLayerMax = ZLayerMax();
546     for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < aLayerMax; ++aLayerId)
547     {
548       if (myZLayers.LayerIDs().IsBound (aLayerId))
549       {
550         const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId);
551         if (aLayer.NbOfTransformPersistenceObjects() > 0)
552         {
553           aLayer.InvalidateBoundingBox();
554         }
555       }
556     }
557   }
558 }
559
560 //=======================================================================
561 //function : ZLayerBoundingBox
562 //purpose  :
563 //=======================================================================
564 Bnd_Box OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
565                                         const Handle(Graphic3d_Camera)& theCamera,
566                                         const Standard_Integer          theWindowWidth,
567                                         const Standard_Integer          theWindowHeight,
568                                         const Standard_Boolean          theToIncludeAuxiliary) const
569 {
570   Bnd_Box aBox;
571   if (myZLayers.LayerIDs().IsBound (theLayerId))
572   {
573     aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(),
574                                                      theCamera,
575                                                      theWindowWidth,
576                                                      theWindowHeight,
577                                                      theToIncludeAuxiliary);
578   }
579
580   // add bounding box of gradient/texture background for proper Z-fit
581   if (theToIncludeAuxiliary
582    && theLayerId == Graphic3d_ZLayerId_BotOSD
583    && (myBgTextureArray->IsDefined()
584     || myBgGradientArray->IsDefined()))
585   {
586     // Background is drawn using 2D transformation persistence
587     // (e.g. it is actually placed in 3D coordinates within active camera position).
588     // We add here full-screen plane with 2D transformation persistence
589     // for simplicity (myBgTextureArray might define a little bit different options
590     // but it is updated within ::Render())
591     const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
592     const Graphic3d_Mat4d& aWorldViewMat  = theCamera->OrientationMatrix();
593     Graphic3d_BndBox3d aBox2d (Graphic3d_Vec3d (0.0, 0.0, 0.0),
594                                Graphic3d_Vec3d (double(theWindowWidth), double(theWindowHeight), 0.0));
595
596     Graphic3d_TransformPers aTrsfPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER);
597     aTrsfPers.Apply (theCamera,
598                      aProjectionMat,
599                      aWorldViewMat,
600                      theWindowWidth,
601                      theWindowHeight,
602                      aBox2d);
603     aBox.Add (gp_Pnt (aBox2d.CornerMin().x(), aBox2d.CornerMin().y(), aBox2d.CornerMin().z()));
604     aBox.Add (gp_Pnt (aBox2d.CornerMax().x(), aBox2d.CornerMax().y(), aBox2d.CornerMax().z()));
605   }
606
607   return aBox;
608 }
609
610 //=======================================================================
611 //function : considerZoomPersistenceObjects
612 //purpose  :
613 //=======================================================================
614 Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId        theLayerId,
615                                                            const Handle(Graphic3d_Camera)& theCamera,
616                                                            const Standard_Integer          theWindowWidth,
617                                                            const Standard_Integer          theWindowHeight) const
618 {
619   if (myZLayers.LayerIDs().IsBound (theLayerId))
620   {
621     return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(),
622                                                                         theCamera,
623                                                                         theWindowWidth,
624                                                                         theWindowHeight);
625   }
626
627   return 1.0;
628 }
629
630 //=======================================================================
631 //function : FBO
632 //purpose  :
633 //=======================================================================
634 Handle(Standard_Transient) OpenGl_View::FBO() const
635 {
636   return Handle(Standard_Transient)(myFBO);
637 }
638
639 //=======================================================================
640 //function : SetFBO
641 //purpose  :
642 //=======================================================================
643 void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo)
644 {
645   myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
646 }
647
648 //=======================================================================
649 //function : FBOCreate
650 //purpose  :
651 //=======================================================================
652 Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth,
653                                                    const Standard_Integer theHeight)
654 {
655   return myWorkspace->FBOCreate (theWidth, theHeight);
656 }
657
658 //=======================================================================
659 //function : FBORelease
660 //purpose  :
661 //=======================================================================
662 void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo)
663 {
664   Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
665   if (aFrameBuffer.IsNull())
666   {
667     return;
668   }
669
670   myWorkspace->FBORelease (aFrameBuffer);
671   theFbo.Nullify();
672 }
673
674 //=======================================================================
675 //function : FBOGetDimensions
676 //purpose  :
677 //=======================================================================
678 void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo,
679                                     Standard_Integer& theWidth,
680                                     Standard_Integer& theHeight,
681                                     Standard_Integer& theWidthMax,
682                                     Standard_Integer& theHeightMax)
683 {
684   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
685   if (aFrameBuffer.IsNull())
686   {
687     return;
688   }
689
690   theWidth     = aFrameBuffer->GetVPSizeX(); // current viewport size
691   theHeight    = aFrameBuffer->GetVPSizeY();
692   theWidthMax  = aFrameBuffer->GetSizeX(); // texture size
693   theHeightMax = aFrameBuffer->GetSizeY();
694 }
695
696 //=======================================================================
697 //function : FBOChangeViewport
698 //purpose  :
699 //=======================================================================
700 void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo,
701                                      const Standard_Integer theWidth,
702                                      const Standard_Integer theHeight)
703 {
704   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
705   if (aFrameBuffer.IsNull())
706   {
707     return;
708   }
709
710   aFrameBuffer->ChangeViewport (theWidth, theHeight);
711 }
712
713 //=======================================================================
714 //function : displayStructure
715 //purpose  :
716 //=======================================================================
717 void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure,
718                                     const Standard_Integer              thePriority)
719 {
720   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
721   const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
722   myZLayers.AddStructure (aStruct, aZLayer, thePriority);
723 }
724
725 //=======================================================================
726 //function : eraseStructure
727 //purpose  :
728 //=======================================================================
729 void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure)
730 {
731   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
732   myZLayers.RemoveStructure (aStruct);
733 }
734
735 //=======================================================================
736 //function : changeZLayer
737 //purpose  :
738 //=======================================================================
739 void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure,
740                                 const Graphic3d_ZLayerId theNewLayerId)
741 {
742   const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
743   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
744   myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
745   Update (anOldLayer);
746   Update (theNewLayerId);
747 }
748
749 //=======================================================================
750 //function : changePriority
751 //purpose  :
752 //=======================================================================
753 void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure,
754                                   const Standard_Integer theNewPriority)
755 {
756   const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
757   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
758   myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority);
759 }
760
761 //=======================================================================
762 //function : DiagnosticInformation
763 //purpose  :
764 //=======================================================================
765 void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
766                                          Graphic3d_DiagnosticInfo theFlags) const
767 {
768   Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
769   if (!myWorkspace->Activate()
770    || aCtx.IsNull())
771   {
772     return;
773   }
774
775   aCtx->DiagnosticInformation (theDict, theFlags);
776   if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
777   {
778     TCollection_AsciiString aResRatio (myRenderParams.ResolutionRatio());
779     theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio;
780   }
781 }
782
783 //=======================================================================
784 //function : StatisticInformation
785 //purpose  :
786 //=======================================================================
787 void OpenGl_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
788 {
789   if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext())
790   {
791     const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats();
792     const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams();
793     aStats->FormatStats (theDict, aRendParams.CollectedStats);
794   }
795 }
796
797 //=======================================================================
798 //function : StatisticInformation
799 //purpose  :
800 //=======================================================================
801 TCollection_AsciiString OpenGl_View::StatisticInformation() const
802 {
803   if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext())
804   {
805     const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats();
806     const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams();
807     return aStats->FormatStats (aRendParams.CollectedStats);
808   }
809   return TCollection_AsciiString();
810 }