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