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