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