0031096: Visualization, TKOpenGl - support metallic-roughness texture mapping
[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   Handle(OpenGl_Texture) aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams());
281   if (Handle(Image_PixMap) anImage = myTextureEnvData->GetImage())
282   {
283     aTextureEnv->Init (theContext, *anImage, myTextureEnvData->Type(), true);
284   }
285   myTextureEnv = new OpenGl_TextureSet (aTextureEnv);
286   myTextureEnv->ChangeTextureSetBits() = Graphic3d_TextureSetBits_BaseColor;
287 }
288
289 // =======================================================================
290 // function : SetImmediateModeDrawToFront
291 // purpose  :
292 // =======================================================================
293 Standard_Boolean OpenGl_View::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
294 {
295   const Standard_Boolean aPrevMode = myTransientDrawToFront;
296   myTransientDrawToFront = theDrawToFrontBuffer;
297   return aPrevMode;
298 }
299
300 // =======================================================================
301 // function : SetWindow
302 // purpose  :
303 // =======================================================================
304 void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow,
305                              const Aspect_RenderingContext theContext)
306 {
307   myWindow = myDriver->CreateRenderWindow (theWindow, theContext);
308   Standard_ASSERT_RAISE (!myWindow.IsNull(),
309                          "OpenGl_View::SetWindow, "
310                          "Failed to create OpenGl window.");
311
312   myWorkspace = new OpenGl_Workspace (this, myWindow);
313   myWorldViewProjState.Reset();
314   myToUpdateEnvironmentMap = Standard_True;
315   myHasFboBlit = Standard_True;
316   Invalidate();
317
318   // Environment texture resource does not support lazy initialization.
319   initTextureEnv (myWorkspace->GetGlContext());
320 }
321
322 // =======================================================================
323 // function : Resized
324 // purpose  :
325 // =======================================================================
326 void OpenGl_View::Resized()
327 {
328   if (myWindow.IsNull())
329     return;
330
331   myWindow->Resize();
332 }
333
334 // =======================================================================
335 // function : SetMinMaxValuesCallback
336 // purpose  :
337 // =======================================================================
338 static void SetMinMaxValuesCallback (Graphic3d_CView* theView)
339 {
340   OpenGl_View* aView = dynamic_cast<OpenGl_View*>(theView);
341   if (aView == NULL)
342     return;
343
344   Bnd_Box aBox = theView->MinMaxValues();
345   if (!aBox.IsVoid())
346   {
347     gp_Pnt aMin = aBox.CornerMin();
348     gp_Pnt aMax = aBox.CornerMax();
349
350     Graphic3d_Vec3 aMinVec ((Standard_ShortReal )aMin.X(), (Standard_ShortReal )aMin.Y(), (Standard_ShortReal )aMin.Z());
351     Graphic3d_Vec3 aMaxVec ((Standard_ShortReal )aMax.X(), (Standard_ShortReal )aMax.Y(), (Standard_ShortReal )aMax.Z());
352     aView->GraduatedTrihedronMinMaxValues (aMinVec, aMaxVec);
353   }
354 }
355
356 // =======================================================================
357 // function : GraduatedTrihedronDisplay
358 // purpose  :
359 // =======================================================================
360 void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData)
361 {
362   myGTrihedronData = theTrihedronData;
363   myGTrihedronData.PtrView = this;
364   myGTrihedronData.CubicAxesCallback = SetMinMaxValuesCallback;
365   myGraduatedTrihedron.SetValues (myGTrihedronData);
366   myToShowGradTrihedron = true;
367 }
368
369 // =======================================================================
370 // function : GraduatedTrihedronErase
371 // purpose  :
372 // =======================================================================
373 void OpenGl_View::GraduatedTrihedronErase()
374 {
375   myGTrihedronData.PtrView = NULL;
376   myGraduatedTrihedron.Release (myWorkspace->GetGlContext().operator->());
377   myToShowGradTrihedron = false;
378 }
379
380 // =======================================================================
381 // function : GraduatedTrihedronMinMaxValues
382 // purpose  :
383 // =======================================================================
384 void OpenGl_View::GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax)
385 {
386   myGraduatedTrihedron.SetMinMax (theMin, theMax);
387 }
388
389 // =======================================================================
390 // function : BufferDump
391 // purpose  :
392 // =======================================================================
393 Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType)
394 {
395   if (theBufferType != Graphic3d_BT_RGB_RayTraceHdrLeft)
396   {
397     return myWorkspace->BufferDump(myFBO, theImage, theBufferType);
398   }
399
400   if (!myRaytraceParameters.AdaptiveScreenSampling)
401   {
402     return myWorkspace->BufferDump(myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType);
403   }
404
405 #if defined(GL_ES_VERSION_2_0)
406   return false;
407 #else
408   if (theImage.Format() != Image_Format_RGBF)
409   {
410     return false;
411   }
412
413   const GLuint aW = myRaytraceOutputTexture[0]->SizeX();
414   const GLuint aH = myRaytraceOutputTexture[0]->SizeY();
415   if (aW / 3 != theImage.SizeX() || aH / 2 != theImage.SizeY())
416   {
417     return false;
418   }
419
420   std::vector<GLfloat> aValues;
421   try
422   {
423     aValues.resize (aW * aH);
424   }
425   catch (const std::bad_alloc&)
426   {
427     return false;
428   }
429
430   glBindTexture (GL_TEXTURE_RECTANGLE, myRaytraceOutputTexture[0]->TextureId());
431   glGetTexImage (GL_TEXTURE_RECTANGLE, 0, OpenGl_TextureFormat::Create<GLfloat, 1>().Format(), GL_FLOAT, &aValues[0]);
432   glBindTexture (GL_TEXTURE_RECTANGLE, 0);
433   for (unsigned int aRow = 0; aRow < aH; aRow += 2)
434   {
435     for (unsigned int aCol = 0; aCol < aW; aCol += 3)
436     {
437       float* anImageValue = theImage.ChangeValue<float[3]> ((aH - aRow) / 2 - 1, aCol / 3);
438       float aInvNbSamples = 1.f / aValues[aRow * aW + aCol + aW];
439       anImageValue[0] = aValues[aRow * aW + aCol] * aInvNbSamples;
440       anImageValue[1] = aValues[aRow * aW + aCol + 1] * aInvNbSamples;
441       anImageValue[2] = aValues[aRow * aW + aCol + 1 + aW] * aInvNbSamples;
442     }
443   }
444
445   return true;
446 #endif
447 }
448
449 // =======================================================================
450 // function : GradientBackground
451 // purpose  :
452 // =======================================================================
453 Aspect_GradientBackground OpenGl_View::GradientBackground() const
454 {
455   Quantity_Color aColor1, aColor2;
456   aColor1.SetValues (myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0).r(),
457                      myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0).g(),
458                      myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0).b(), Quantity_TOC_RGB);
459   aColor2.SetValues (myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1).r(),
460                      myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1).g(),
461                      myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1).b(), Quantity_TOC_RGB);
462   return Aspect_GradientBackground (aColor1, aColor2, myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientFillMethod());
463 }
464
465 // =======================================================================
466 // function : SetGradientBackground
467 // purpose  :
468 // =======================================================================
469 void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground)
470 {
471   Quantity_Color aColor1, aColor2;
472   theBackground.Colors (aColor1, aColor2);
473   myBackgrounds[Graphic3d_TOB_GRADIENT]->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod());
474
475   myBackgroundType = Graphic3d_TOB_GRADIENT;
476 }
477
478 // =======================================================================
479 // function : SetBackgroundImage
480 // purpose  :
481 // =======================================================================
482 void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath)
483 {
484   // Prepare aspect for texture storage
485   myBackgroundImagePath = theFilePath;
486   Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
487   Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
488   aTextureMap->EnableRepeat();
489   aTextureMap->DisableModulate();
490   aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
491                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
492                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
493   anAspect->SetTextureMap (aTextureMap);
494   anAspect->SetInteriorStyle (Aspect_IS_SOLID);
495   anAspect->SetSuppressBackFaces (false);
496   // Enable texture mapping
497   if (aTextureMap->IsDone())
498   {
499     anAspect->SetTextureMapOn();
500   }
501   else
502   {
503     anAspect->SetTextureMapOff();
504     return;
505   }
506
507   // Set texture parameters
508   myTextureParams->SetAspect (anAspect);
509
510   myBackgroundType = Graphic3d_TOB_TEXTURE;
511 }
512
513 // =======================================================================
514 // function : BackgroundImageStyle
515 // purpose  :
516 // =======================================================================
517 Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const
518 {
519   return myBackgrounds[Graphic3d_TOB_TEXTURE]->TextureFillMethod();
520 }
521
522 // =======================================================================
523 // function : SetBackgroundImageStyle
524 // purpose  :
525 // =======================================================================
526 void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle)
527 {
528   myBackgrounds[Graphic3d_TOB_TEXTURE]->SetTextureFillMethod (theFillStyle);
529 }
530
531 // =======================================================================
532 // function : BackgroundCubeMap
533 // purpose  :
534 // =======================================================================
535 Handle(Graphic3d_CubeMap) OpenGl_View::BackgroundCubeMap() const
536 {
537   return myBackgroundCubeMap;
538 }
539
540 // =======================================================================
541 // function : SpecIBLMapLevels
542 // purpose  :
543 // =======================================================================
544 unsigned int OpenGl_View::SpecIBLMapLevels() const
545 {
546   return myPBREnvironment.IsNull() ? 0 : myPBREnvironment->SpecMapLevelsNumber();
547 }
548  
549 // =======================================================================
550 // function : SetBackgroundCubeMap
551 // purpose  :
552 // =======================================================================
553 void OpenGl_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
554                                         Standard_Boolean theToUpdatePBREnv)
555 {
556   myBackgroundCubeMap = theCubeMap;
557   if (theCubeMap.IsNull())
558   {
559     if (theToUpdatePBREnv)
560     {
561       myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR;
562     }
563     if (myBackgroundType == Graphic3d_TOB_CUBEMAP)
564     {
565       myBackgroundType = Graphic3d_TOB_NONE;
566     }
567     return;
568   }
569
570   theCubeMap ->SetMipmapsGeneration (Standard_True);
571   Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
572   Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (myBackgroundCubeMap);
573   anAspect->SetInteriorStyle (Aspect_IS_SOLID);
574   anAspect->SetSuppressBackFaces (false);
575   anAspect->SetTextureSet (aTextureSet);
576
577   const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
578   if (!aCtx.IsNull())
579   {
580     anAspect->SetShaderProgram (aCtx->ShaderManager()->GetBgCubeMapProgram());
581   }
582   anAspect->SetTextureMapOn (theCubeMap->IsDone());
583   myCubeMapParams->SetAspect (anAspect);
584
585   if (theToUpdatePBREnv)
586   {
587     myPBREnvRequest = OpenGl_PBREnvRequest_BAKE;
588   }
589   const OpenGl_Aspects* anAspectsBackup = myWorkspace->SetAspects (myCubeMapParams);
590   myWorkspace->ApplyAspects();
591   myWorkspace->SetAspects (anAspectsBackup);
592   myWorkspace->ApplyAspects();
593
594   myBackgroundType = Graphic3d_TOB_CUBEMAP;
595 }
596
597 //=======================================================================
598 //function : InsertLayerBefore
599 //purpose  :
600 //=======================================================================
601 void OpenGl_View::InsertLayerBefore (const Graphic3d_ZLayerId theLayerId,
602   const Graphic3d_ZLayerSettings& theSettings,
603   const Graphic3d_ZLayerId theLayerAfter)
604 {
605   myZLayers.InsertLayerBefore (theLayerId, theSettings, theLayerAfter);
606 }
607
608 //=======================================================================
609 //function : InsertLayerAfter
610 //purpose  :
611 //=======================================================================
612 void OpenGl_View::InsertLayerAfter (const Graphic3d_ZLayerId theLayerId,
613   const Graphic3d_ZLayerSettings& theSettings,
614   const Graphic3d_ZLayerId theLayerBefore)
615 {
616   myZLayers.InsertLayerAfter (theLayerId, theSettings, theLayerBefore);
617 }
618
619 //=======================================================================
620 //function : RemoveZLayer
621 //purpose  :
622 //=======================================================================
623 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
624 {
625   myZLayers.RemoveLayer (theLayerId);
626 }
627
628 //=======================================================================
629 //function : SetZLayerSettings
630 //purpose  :
631 //=======================================================================
632 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
633                                      const Graphic3d_ZLayerSettings& theSettings)
634 {
635   myZLayers.SetLayerSettings (theLayerId, theSettings);
636 }
637
638 //=======================================================================
639 //function : ZLayerMax
640 //purpose  :
641 //=======================================================================
642 Standard_Integer OpenGl_View::ZLayerMax() const
643 {
644   Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default;
645   for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myZLayers.Layers()); aLayerIter.More(); aLayerIter.Next())
646   {
647     aLayerMax = Max (aLayerMax, aLayerIter.Value()->LayerId());
648   }
649   return aLayerMax;
650 }
651
652 //=======================================================================
653 //function : Layers
654 //purpose  :
655 //=======================================================================
656 const NCollection_List<Handle(Graphic3d_Layer)>& OpenGl_View::Layers() const
657 {
658   return myZLayers.Layers();
659 }
660
661 //=======================================================================
662 //function : Layer
663 //purpose  :
664 //=======================================================================
665 Handle(Graphic3d_Layer) OpenGl_View::Layer (const Graphic3d_ZLayerId theLayerId) const
666 {
667   Handle(Graphic3d_Layer) aLayer;
668   if (theLayerId != Graphic3d_ZLayerId_UNKNOWN)
669   {
670     myZLayers.LayerIDs().Find (theLayerId, aLayer);
671   }
672   return aLayer;
673 }
674
675 //=======================================================================
676 //function : MinMaxValues
677 //purpose  :
678 //=======================================================================
679 Bnd_Box OpenGl_View::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary) const
680 {
681   if (!IsDefined())
682   {
683     return Bnd_Box();
684   }
685
686   Bnd_Box aBox = base_type::MinMaxValues (theToIncludeAuxiliary);
687
688   return aBox;
689 }
690
691 //=======================================================================
692 //function : FBO
693 //purpose  :
694 //=======================================================================
695 Handle(Standard_Transient) OpenGl_View::FBO() const
696 {
697   return Handle(Standard_Transient)(myFBO);
698 }
699
700 //=======================================================================
701 //function : SetFBO
702 //purpose  :
703 //=======================================================================
704 void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo)
705 {
706   myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
707 }
708
709 //=======================================================================
710 //function : FBOCreate
711 //purpose  :
712 //=======================================================================
713 Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth,
714                                                    const Standard_Integer theHeight)
715 {
716   return myWorkspace->FBOCreate (theWidth, theHeight);
717 }
718
719 //=======================================================================
720 //function : FBORelease
721 //purpose  :
722 //=======================================================================
723 void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo)
724 {
725   Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
726   if (aFrameBuffer.IsNull())
727   {
728     return;
729   }
730
731   myWorkspace->FBORelease (aFrameBuffer);
732   theFbo.Nullify();
733 }
734
735 //=======================================================================
736 //function : FBOGetDimensions
737 //purpose  :
738 //=======================================================================
739 void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo,
740                                     Standard_Integer& theWidth,
741                                     Standard_Integer& theHeight,
742                                     Standard_Integer& theWidthMax,
743                                     Standard_Integer& theHeightMax)
744 {
745   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
746   if (aFrameBuffer.IsNull())
747   {
748     return;
749   }
750
751   theWidth     = aFrameBuffer->GetVPSizeX(); // current viewport size
752   theHeight    = aFrameBuffer->GetVPSizeY();
753   theWidthMax  = aFrameBuffer->GetSizeX(); // texture size
754   theHeightMax = aFrameBuffer->GetSizeY();
755 }
756
757 //=======================================================================
758 //function : FBOChangeViewport
759 //purpose  :
760 //=======================================================================
761 void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo,
762                                      const Standard_Integer theWidth,
763                                      const Standard_Integer theHeight)
764 {
765   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
766   if (aFrameBuffer.IsNull())
767   {
768     return;
769   }
770
771   aFrameBuffer->ChangeViewport (theWidth, theHeight);
772 }
773
774 //=======================================================================
775 //function : displayStructure
776 //purpose  :
777 //=======================================================================
778 void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure,
779                                     const Standard_Integer              thePriority)
780 {
781   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
782   const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
783   myZLayers.AddStructure (aStruct, aZLayer, thePriority);
784 }
785
786 //=======================================================================
787 //function : eraseStructure
788 //purpose  :
789 //=======================================================================
790 void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure)
791 {
792   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
793   myZLayers.RemoveStructure (aStruct);
794 }
795
796 //=======================================================================
797 //function : changeZLayer
798 //purpose  :
799 //=======================================================================
800 void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure,
801                                 const Graphic3d_ZLayerId theNewLayerId)
802 {
803   const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
804   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
805   myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
806   Update (anOldLayer);
807   Update (theNewLayerId);
808 }
809
810 //=======================================================================
811 //function : changePriority
812 //purpose  :
813 //=======================================================================
814 void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure,
815                                   const Standard_Integer theNewPriority)
816 {
817   const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
818   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
819   myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority);
820 }
821
822 //=======================================================================
823 //function : DiagnosticInformation
824 //purpose  :
825 //=======================================================================
826 void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
827                                          Graphic3d_DiagnosticInfo theFlags) const
828 {
829   Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
830   if (!myWorkspace->Activate()
831    || aCtx.IsNull())
832   {
833     return;
834   }
835
836   aCtx->DiagnosticInformation (theDict, theFlags);
837   if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
838   {
839     TCollection_AsciiString aResRatio (myRenderParams.ResolutionRatio());
840     theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio;
841   }
842 }
843
844 //=======================================================================
845 //function : StatisticInformation
846 //purpose  :
847 //=======================================================================
848 void OpenGl_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
849 {
850   if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext())
851   {
852     const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats();
853     const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams();
854     aStats->FormatStats (theDict, aRendParams.CollectedStats);
855   }
856 }
857
858 //=======================================================================
859 //function : StatisticInformation
860 //purpose  :
861 //=======================================================================
862 TCollection_AsciiString OpenGl_View::StatisticInformation() const
863 {
864   if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext())
865   {
866     const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats();
867     const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams();
868     return aStats->FormatStats (aRendParams.CollectedStats);
869   }
870   return TCollection_AsciiString();
871 }