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