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