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