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