c054675599f96ba49e335bc1d6459be2d218c839
[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_Trihedron.hxx>
33 #include <OpenGl_Window.hxx>
34 #include <OpenGl_Workspace.hxx>
35 #include <Standard_CLocaleSentry.hxx>
36
37 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,Graphic3d_CView)
38
39 #ifdef HAVE_GL2PS
40 #include <gl2ps.h>
41 #endif
42
43 /*----------------------------------------------------------------------*/
44
45 namespace
46 {
47   static const OPENGL_ZCLIP myDefaultZClip = { { Standard_False, 0.F }, { Standard_False, 1.F } };
48   static const OPENGL_FOG   myDefaultFog   = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
49   static const TEL_COLOUR   myDefaultBg    = { { 0.F, 0.F, 0.F, 1.F } };
50 }
51
52 // =======================================================================
53 // function : Constructor
54 // purpose  :
55 // =======================================================================
56 OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
57                           const Handle(OpenGl_GraphicDriver)& theDriver,
58                           const Handle(OpenGl_Caps)& theCaps,
59                           Standard_Boolean& theDeviceLostFlag,
60                           OpenGl_StateCounter* theCounter)
61 : Graphic3d_CView  (theMgr),
62   myDriver         (theDriver.operator->()),
63   myCaps           (theCaps),
64   myDeviceLostFlag (theDeviceLostFlag),
65   myWasRedrawnGL   (Standard_False),
66   myAntiAliasing   (Standard_False),
67   myCulling        (Standard_True),
68   myShadingModel   (Graphic3d_TOSM_FACET),
69   myBackfacing     (Graphic3d_TOBM_AUTOMATIC),
70   myBgColor        (myDefaultBg),
71   myFog            (myDefaultFog),
72   myZClip          (myDefaultZClip),
73   myCamera         (new Graphic3d_Camera()),
74   myUseGLLight     (Standard_True),
75   myToShowTrihedron      (false),
76   myToShowGradTrihedron  (false),
77   myStateCounter         (theCounter),
78   myLastLightSourceState (0, 0),
79   myFboColorFormat       (GL_RGBA8),
80   myFboDepthFormat       (GL_DEPTH24_STENCIL8),
81   myToFlipOutput         (Standard_False),
82   myFrameCounter         (0),
83   myHasFboBlit           (Standard_True),
84   myToDisableMSAA        (Standard_False),
85   myTransientDrawToFront (Standard_True),
86   myBackBufferRestored   (Standard_False),
87   myIsImmediateDrawn     (Standard_False),
88   myTextureParams   (new OpenGl_AspectFace()),
89   myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
90   myBgTextureArray  (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)),
91   // ray-tracing fields initialization
92   myRaytraceInitStatus     (OpenGl_RT_NONE),
93   myIsRaytraceDataValid    (Standard_False),
94   myIsRaytraceWarnTextures (Standard_False),
95   myToUpdateEnvironmentMap (Standard_False),
96   myLayerListState (0)
97 {
98   myWorkspace = new OpenGl_Workspace (this, NULL);
99
100   // AA mode
101   const char* anAaEnv = ::getenv ("CALL_OPENGL_ANTIALIASING_MODE");
102   if (anAaEnv != NULL)
103   {
104     int v;
105     if (sscanf (anAaEnv, "%d", &v) > 0) myAntiAliasing = v;
106   }
107
108   OpenGl_Light       aLight;
109   aLight.Type        = Graphic3d_TOLS_AMBIENT;
110   aLight.IsHeadlight = Standard_False;
111   aLight.Color.r()   = 1.;
112   aLight.Color.g()   = 1.;
113   aLight.Color.b()   = 1.;
114   myNoShadingLight.Append (aLight);
115
116   myCurrLightSourceState  = myStateCounter->Increment();
117   myMainSceneFbos[0]      = new OpenGl_FrameBuffer();
118   myMainSceneFbos[1]      = new OpenGl_FrameBuffer();
119   myImmediateSceneFbos[0] = new OpenGl_FrameBuffer();
120   myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
121   myOpenGlFBO             = new OpenGl_FrameBuffer();
122   myOpenGlFBO2            = new OpenGl_FrameBuffer();
123   myRaytraceFBO1[0]       = new OpenGl_FrameBuffer();
124   myRaytraceFBO1[1]       = new OpenGl_FrameBuffer();
125   myRaytraceFBO2[0]       = new OpenGl_FrameBuffer();
126   myRaytraceFBO2[1]       = new OpenGl_FrameBuffer();
127 }
128
129 // =======================================================================
130 // function : Destructor
131 // purpose  :
132 // =======================================================================
133 OpenGl_View::~OpenGl_View()
134 {
135   ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
136   OpenGl_Element::Destroy (NULL, myBgGradientArray);
137   OpenGl_Element::Destroy (NULL, myBgTextureArray);
138   OpenGl_Element::Destroy (NULL, myTextureParams);
139 }
140
141 // =======================================================================
142 // function : ReleaseGlResources
143 // purpose  :
144 // =======================================================================
145 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
146 {
147   myTrihedron         .Release (theCtx.operator->());
148   myGraduatedTrihedron.Release (theCtx.operator->());
149
150   if (!myTextureEnv.IsNull())
151   {
152     theCtx->DelayedRelease (myTextureEnv);
153     myTextureEnv.Nullify();
154   }
155
156   if (myTextureParams != NULL)
157   {
158     myTextureParams->Release (theCtx.operator->());
159   }
160   if (myBgGradientArray != NULL)
161   {
162     myBgGradientArray->Release (theCtx.operator->());
163   }
164   if (myBgTextureArray != NULL)
165   {
166     myBgTextureArray->Release (theCtx.operator->());
167   }
168
169   myMainSceneFbos[0]     ->Release (theCtx.operator->());
170   myMainSceneFbos[1]     ->Release (theCtx.operator->());
171   myImmediateSceneFbos[0]->Release (theCtx.operator->());
172   myImmediateSceneFbos[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::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv)
203 {
204   Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
205   if (!aCtx.IsNull() && !myTextureEnv.IsNull())
206   {
207     aCtx->DelayedRelease (myTextureEnv);
208   }
209
210   myToUpdateEnvironmentMap = Standard_True;
211   myTextureEnvData = theTextureEnv;
212   myTextureEnv.Nullify();
213   initTextureEnv (aCtx);
214 }
215
216 // =======================================================================
217 // function : initTextureEnv
218 // purpose  :
219 // =======================================================================
220 void OpenGl_View::initTextureEnv (const Handle(OpenGl_Context)& theContext)
221 {
222   if (myTextureEnvData.IsNull()
223     ||  theContext.IsNull()
224     || !theContext->MakeCurrent())
225   {
226     return;
227   }
228
229   myTextureEnv = new OpenGl_Texture (myTextureEnvData->GetParams());
230   Handle(Image_PixMap) anImage = myTextureEnvData->GetImage();
231   if (!anImage.IsNull())
232   {
233     myTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type());
234   }
235 }
236
237 // =======================================================================
238 // function : SetImmediateModeDrawToFront
239 // purpose  :
240 // =======================================================================
241 Standard_Boolean OpenGl_View::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
242 {
243   const Standard_Boolean aPrevMode = myTransientDrawToFront;
244   myTransientDrawToFront = theDrawToFrontBuffer;
245   return aPrevMode;
246 }
247
248 // =======================================================================
249 // function : SetWindow
250 // purpose  :
251 // =======================================================================
252 void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow,
253                              const Aspect_RenderingContext theContext)
254 {
255   myWindow = myDriver->CreateRenderWindow (theWindow, theContext);
256   Standard_ASSERT_RAISE (!myWindow.IsNull(),
257                          "OpenGl_View::SetWindow, "
258                          "Failed to create OpenGl window.");
259
260   myWorkspace = new OpenGl_Workspace (this, myWindow);
261   myWorldViewProjState.Reset();
262   myToUpdateEnvironmentMap = Standard_True;
263   myHasFboBlit = Standard_True;
264   Invalidate();
265
266   // Environment texture resource does not support lazy initialization.
267   initTextureEnv (myWorkspace->GetGlContext());
268 }
269
270 // =======================================================================
271 // function : Resized
272 // purpose  :
273 // =======================================================================
274 void OpenGl_View::Resized()
275 {
276   if (myWindow.IsNull())
277     return;
278
279   myWindow->Resize();
280 }
281
282 // =======================================================================
283 // function : TriedronDisplay
284 // purpose  :
285 // =======================================================================
286 void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition,
287                                    const Quantity_NameOfColor          theColor,
288                                    const Standard_Real                 theScale,
289                                    const Standard_Boolean              theAsWireframe)
290 {
291   myToShowTrihedron = true;
292   myTrihedron.SetWireframe   (theAsWireframe);
293   myTrihedron.SetPosition    (thePosition);
294   myTrihedron.SetScale       (theScale);
295   myTrihedron.SetLabelsColor (theColor);
296 }
297
298 // =======================================================================
299 // function : TriedronErase
300 // purpose  :
301 // =======================================================================
302 void OpenGl_View::TriedronErase()
303 {
304   myToShowTrihedron = false;
305   myTrihedron.Release (myWorkspace->GetGlContext().operator->());
306 }
307
308 // =======================================================================
309 // function : ZBufferTriedronSetup
310 // purpose  :
311 // =======================================================================
312 void OpenGl_View::ZBufferTriedronSetup (const Quantity_NameOfColor theXColor,
313                                         const Quantity_NameOfColor theYColor,
314                                         const Quantity_NameOfColor theZColor,
315                                         const Standard_Real theSizeRatio,
316                                         const Standard_Real theAxisDiametr,
317                                         const Standard_Integer theNbFacettes)
318 {
319   myTrihedron.SetArrowsColors  (theXColor, theYColor, theZColor);
320   myTrihedron.SetSizeRatio     (theSizeRatio);
321   myTrihedron.SetNbFacets      (theNbFacettes);
322   myTrihedron.SetArrowDiameter (theAxisDiametr);
323 }
324
325 // =======================================================================
326 // function : TriedronEcho
327 // purpose  :
328 // =======================================================================
329 void OpenGl_View::TriedronEcho (const Aspect_TypeOfTriedronEcho /*theType*/)
330 {
331   // do nothing
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   return myWorkspace->BufferDump (myFBO, theImage, theBufferType);
396 }
397
398 // =======================================================================
399 // function : Background
400 // purpose  :
401 // =======================================================================
402 Aspect_Background OpenGl_View::Background() const
403 {
404   return Aspect_Background (Quantity_Color (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], Quantity_TOC_RGB));
405 }
406
407 // =======================================================================
408 // function : SetBackground
409 // purpose  :
410 // =======================================================================
411 void OpenGl_View::SetBackground (const Aspect_Background& theBackground)
412 {
413   Quantity_Color aBgColor = theBackground.Color();
414   myBgColor.rgb[0] = static_cast<float> (aBgColor.Red());
415   myBgColor.rgb[1] = static_cast<float> (aBgColor.Green());
416   myBgColor.rgb[2] = static_cast<float> (aBgColor.Blue());
417   myFog.Color      = myBgColor;
418 }
419
420 // =======================================================================
421 // function : GradientBackground
422 // purpose  :
423 // =======================================================================
424 Aspect_GradientBackground OpenGl_View::GradientBackground() const
425 {
426   Quantity_Color aColor1, aColor2;
427   aColor1.SetValues (myBgGradientArray->GradientColor (0).r(),
428                      myBgGradientArray->GradientColor (0).g(),
429                      myBgGradientArray->GradientColor (0).b(), Quantity_TOC_RGB);
430   aColor2.SetValues (myBgGradientArray->GradientColor (1).r(),
431                      myBgGradientArray->GradientColor (1).g(),
432                      myBgGradientArray->GradientColor (1).b(), Quantity_TOC_RGB);
433   return Aspect_GradientBackground (aColor1, aColor2, myBgGradientArray->GradientFillMethod());
434 }
435
436 // =======================================================================
437 // function : SetGradientBackground
438 // purpose  :
439 // =======================================================================
440 void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground)
441 {
442   Quantity_Color aColor1, aColor2;
443   theBackground.Colors (aColor1, aColor2);
444   myBgGradientArray->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod());
445 }
446
447 // =======================================================================
448 // function : SetBackgroundImage
449 // purpose  :
450 // =======================================================================
451 void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath)
452 {
453   // Prepare aspect for texture storage
454   myBackgroundImagePath = theFilePath;
455   Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
456   Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
457   aTextureMap->EnableRepeat();
458   aTextureMap->DisableModulate();
459   aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
460                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
461                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
462   anAspect->SetTextureMap (aTextureMap);
463   anAspect->SetInteriorStyle (Aspect_IS_SOLID);
464   // Enable texture mapping
465   if (aTextureMap->IsDone())
466   {
467     anAspect->SetTextureMapOn();
468   }
469   else
470   {
471     anAspect->SetTextureMapOff();
472     return;
473   }
474
475   // Set texture parameters
476   myTextureParams->SetAspect (anAspect);
477 }
478
479 // =======================================================================
480 // function : BackgroundImageStyle
481 // purpose  :
482 // =======================================================================
483 Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const
484 {
485   return myBgTextureArray->TextureFillMethod();
486 }
487
488 // =======================================================================
489 // function : SetBackgroundImageStyle
490 // purpose  :
491 // =======================================================================
492 void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle)
493 {
494   myBgTextureArray->SetTextureFillMethod (theFillStyle);
495 }
496
497 //=======================================================================
498 //function : AddZLayer
499 //purpose  :
500 //=======================================================================
501 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
502 {
503   myZLayers.AddLayer (theLayerId);
504 }
505
506 //=======================================================================
507 //function : RemoveZLayer
508 //purpose  :
509 //=======================================================================
510 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
511 {
512   myZLayers.RemoveLayer (theLayerId);
513 }
514
515 //=======================================================================
516 //function : SetZLayerSettings
517 //purpose  :
518 //=======================================================================
519 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
520                                      const Graphic3d_ZLayerSettings& theSettings)
521 {
522   myZLayers.SetLayerSettings (theLayerId, theSettings);
523 }
524
525 //=======================================================================
526 //function : ZLayerMax
527 //purpose  :
528 //=======================================================================
529 Standard_Integer OpenGl_View::ZLayerMax() const
530 {
531   Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default;
532   for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next())
533   {
534     aLayerMax = Max (aLayerMax, aMapIt.Value());
535   }
536
537   return aLayerMax;
538 }
539
540 //=======================================================================
541 //function : InvalidateZLayerBoundingBox
542 //purpose  :
543 //=======================================================================
544 void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const
545 {
546   if (myZLayers.LayerIDs().IsBound (theLayerId))
547   {
548     myZLayers.Layer (theLayerId).InvalidateBoundingBox();
549   }
550   else
551   {
552     for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < ZLayerMax(); ++aLayerId)
553     {
554       if (myZLayers.LayerIDs().IsBound (aLayerId))
555       {
556         const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId);
557         if (aLayer.NbOfTransformPersistenceObjects() > 0)
558         {
559           aLayer.InvalidateBoundingBox();
560         }
561       }
562     }
563   }
564 }
565
566 //=======================================================================
567 //function : ZLayerBoundingBox
568 //purpose  :
569 //=======================================================================
570 Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
571                                                    const Handle(Graphic3d_Camera)& theCamera,
572                                                    const Standard_Integer          theWindowWidth,
573                                                    const Standard_Integer          theWindowHeight,
574                                                    const Standard_Boolean          theToIgnoreInfiniteFlag) const
575 {
576   if (myZLayers.LayerIDs().IsBound (theLayerId))
577   {
578     return myZLayers.Layer (theLayerId).BoundingBox (Identification(),
579                                                      theCamera,
580                                                      theWindowWidth,
581                                                      theWindowHeight,
582                                                      theToIgnoreInfiniteFlag);
583   }
584
585   return Graphic3d_BndBox4f();
586 }
587
588 //=======================================================================
589 //function : considerZoomPersistenceObjects
590 //purpose  :
591 //=======================================================================
592 Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId        theLayerId,
593                                                            const Handle(Graphic3d_Camera)& theCamera,
594                                                            const Standard_Integer          theWindowWidth,
595                                                            const Standard_Integer          theWindowHeight,
596                                                            const Standard_Boolean          theToIgnoreInfiniteFlag) const
597 {
598   if (myZLayers.LayerIDs().IsBound (theLayerId) && theCamera->IsOrthographic())
599   {
600     return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(),
601                                                                         theCamera,
602                                                                         theWindowWidth,
603                                                                         theWindowHeight,
604                                                                         theToIgnoreInfiniteFlag);
605   }
606
607   return 1.0;
608 }
609
610 //=======================================================================
611 //function : FBO
612 //purpose  :
613 //=======================================================================
614 Handle(Standard_Transient) OpenGl_View::FBO() const
615 {
616   return Handle(Standard_Transient)(myFBO);
617 }
618
619 //=======================================================================
620 //function : SetFBO
621 //purpose  :
622 //=======================================================================
623 void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo)
624 {
625   myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
626 }
627
628 //=======================================================================
629 //function : FBOCreate
630 //purpose  :
631 //=======================================================================
632 Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth,
633                                                    const Standard_Integer theHeight)
634 {
635   return myWorkspace->FBOCreate (theWidth, theHeight);
636 }
637
638 //=======================================================================
639 //function : FBORelease
640 //purpose  :
641 //=======================================================================
642 void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo)
643 {
644   Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
645   if (aFrameBuffer.IsNull())
646   {
647     return;
648   }
649
650   myWorkspace->FBORelease (aFrameBuffer);
651   theFbo.Nullify();
652 }
653
654 //=======================================================================
655 //function : FBOGetDimensions
656 //purpose  :
657 //=======================================================================
658 void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo,
659                                     Standard_Integer& theWidth,
660                                     Standard_Integer& theHeight,
661                                     Standard_Integer& theWidthMax,
662                                     Standard_Integer& theHeightMax)
663 {
664   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
665   if (aFrameBuffer.IsNull())
666   {
667     return;
668   }
669
670   theWidth     = aFrameBuffer->GetVPSizeX(); // current viewport size
671   theHeight    = aFrameBuffer->GetVPSizeY();
672   theWidthMax  = aFrameBuffer->GetSizeX(); // texture size
673   theHeightMax = aFrameBuffer->GetSizeY();
674 }
675
676 //=======================================================================
677 //function : FBOChangeViewport
678 //purpose  :
679 //=======================================================================
680 void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo,
681                                      const Standard_Integer theWidth,
682                                      const Standard_Integer theHeight)
683 {
684   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
685   if (aFrameBuffer.IsNull())
686   {
687     return;
688   }
689
690   aFrameBuffer->ChangeViewport (theWidth, theHeight);
691 }
692
693 // =======================================================================
694 // function : Export
695 // purpose  :
696 // =======================================================================
697 #ifdef HAVE_GL2PS
698 Standard_Boolean OpenGl_View::Export (const Standard_CString theFileName,
699                                       const Graphic3d_ExportFormat theFormat,
700                                       const Graphic3d_SortType theSortType)
701 {
702   // gl2psBeginPage() will call OpenGL functions
703   // so we should activate correct GL context before redraw scene call
704   if (!myWorkspace->Activate())
705   {
706     return Standard_False;
707   }
708
709   Standard_Integer aFormat = -1;
710   Standard_Integer aSortType = Graphic3d_ST_BSP_Tree;
711   switch (theFormat)
712   {
713     case Graphic3d_EF_PostScript:
714       aFormat = GL2PS_PS;
715       break;
716     case Graphic3d_EF_EnhPostScript:
717       aFormat = GL2PS_EPS;
718       break;
719     case Graphic3d_EF_TEX:
720       aFormat = GL2PS_TEX;
721       break;
722     case Graphic3d_EF_PDF:
723       aFormat = GL2PS_PDF;
724       break;
725     case Graphic3d_EF_SVG:
726       aFormat = GL2PS_SVG;
727       break;
728     case Graphic3d_EF_PGF:
729       aFormat = GL2PS_PGF;
730       break;
731     case Graphic3d_EF_EMF:
732       //aFormat = GL2PS_EMF;
733       aFormat = GL2PS_PGF + 1; // 6
734       break;
735     default:
736       // unsupported format
737       return Standard_False;
738   }
739
740   switch (theSortType)
741   {
742     case Graphic3d_ST_Simple:
743       aSortType = GL2PS_SIMPLE_SORT;
744       break;
745     case Graphic3d_ST_BSP_Tree:
746       aSortType = GL2PS_BSP_SORT;
747       break;
748   }
749
750   GLint aViewport[4];
751   aViewport[0] = 0;
752   aViewport[1] = 0;
753   aViewport[2] = myWindow->Width();
754   aViewport[3] = myWindow->Height();
755
756   GLint aBufferSize = 1024 * 1024;
757   GLint anErrCode = GL2PS_SUCCESS;
758
759   // gl2ps uses standard write functions and do not check locale
760   Standard_CLocaleSentry aLocaleSentry;
761
762   while (aBufferSize > 0)
763   {
764     // current patch for EMF support in gl2ps uses WinAPI functions to create file
765     FILE* aFileH = (theFormat != Graphic3d_EF_EMF) ? fopen (theFileName, "wb") : NULL;
766     anErrCode = gl2psBeginPage ("", "", aViewport, aFormat, aSortType,
767                     GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT/* | GL2PS_SIMPLE_LINE_OFFSET*/,
768                     GL_RGBA, 0, NULL,
769                     0, 0, 0, aBufferSize, aFileH, theFileName);
770     if (anErrCode != GL2PS_SUCCESS)
771     {
772       // initialization failed
773       if (aFileH != NULL)
774         fclose (aFileH);
775       break;
776     }
777     Redraw();
778
779     anErrCode = gl2psEndPage();
780     if (aFileH != NULL)
781       fclose (aFileH);
782
783     if (anErrCode == GL2PS_OVERFLOW)
784       aBufferSize *= 2;
785     else
786       break;
787   }
788   return anErrCode == GL2PS_SUCCESS;
789 }
790 #else
791 Standard_Boolean OpenGl_View::Export (const Standard_CString /*theFileName*/,
792                                       const Graphic3d_ExportFormat /*theFormat*/,
793                                       const Graphic3d_SortType /*theSortType*/)
794 {
795     return Standard_False;
796 }
797 #endif
798
799 //=======================================================================
800 //function : displayStructure
801 //purpose  :
802 //=======================================================================
803 void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure,
804                                     const Standard_Integer              thePriority)
805 {
806   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
807   const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
808   myZLayers.AddStructure (aStruct, aZLayer, thePriority);
809 }
810
811 //=======================================================================
812 //function : eraseStructure
813 //purpose  :
814 //=======================================================================
815 void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure)
816 {
817   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
818   myZLayers.RemoveStructure (aStruct);
819 }
820
821 //=======================================================================
822 //function : changeZLayer
823 //purpose  :
824 //=======================================================================
825 void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure,
826                                 const Graphic3d_ZLayerId theNewLayerId)
827 {
828   const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
829   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
830   myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
831   Update (Aspect_TOU_WAIT, anOldLayer);
832   Update (Aspect_TOU_WAIT, theNewLayerId);
833 }
834
835 //=======================================================================
836 //function : changePriority
837 //purpose  :
838 //=======================================================================
839 void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure,
840                                   const Standard_Integer theNewPriority)
841 {
842   const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
843   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
844   myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority);
845 }