39037a70fbe25d8f88fbf7b9ca41bc183b37af57
[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, OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f) };
49 }
50
51 // =======================================================================
52 // function : Constructor
53 // purpose  :
54 // =======================================================================
55 OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
56                           const Handle(OpenGl_GraphicDriver)& theDriver,
57                           const Handle(OpenGl_Caps)& theCaps,
58                           Standard_Boolean& theDeviceLostFlag,
59                           OpenGl_StateCounter* theCounter)
60 : Graphic3d_CView  (theMgr),
61   myDriver         (theDriver.operator->()),
62   myCaps           (theCaps),
63   myDeviceLostFlag (theDeviceLostFlag),
64   myWasRedrawnGL   (Standard_False),
65   myAntiAliasing   (Standard_False),
66   myCulling        (Standard_True),
67   myShadingModel   (Graphic3d_TOSM_FACET),
68   myBackfacing     (Graphic3d_TOBM_AUTOMATIC),
69   myBgColor        (Quantity_NOC_BLACK),
70   myFog            (myDefaultFog),
71   myZClip          (myDefaultZClip),
72   myCamera         (new Graphic3d_Camera()),
73   myUseGLLight     (Standard_True),
74   myToShowTrihedron      (false),
75   myToShowGradTrihedron  (false),
76   myStateCounter         (theCounter),
77   myLastLightSourceState (0, 0),
78   myFboColorFormat       (GL_RGBA8),
79   myFboDepthFormat       (GL_DEPTH24_STENCIL8),
80   myToFlipOutput         (Standard_False),
81   myFrameCounter         (0),
82   myHasFboBlit           (Standard_True),
83   myToDisableMSAA        (Standard_False),
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 (myBgColor.GetRGB());
404 }
405
406 // =======================================================================
407 // function : SetBackground
408 // purpose  :
409 // =======================================================================
410 void OpenGl_View::SetBackground (const Aspect_Background& theBackground)
411 {
412   myBgColor.SetRGB (theBackground.Color());
413   myFog.Color = myBgColor;
414 }
415
416 // =======================================================================
417 // function : GradientBackground
418 // purpose  :
419 // =======================================================================
420 Aspect_GradientBackground OpenGl_View::GradientBackground() const
421 {
422   Quantity_Color aColor1, aColor2;
423   aColor1.SetValues (myBgGradientArray->GradientColor (0).r(),
424                      myBgGradientArray->GradientColor (0).g(),
425                      myBgGradientArray->GradientColor (0).b(), Quantity_TOC_RGB);
426   aColor2.SetValues (myBgGradientArray->GradientColor (1).r(),
427                      myBgGradientArray->GradientColor (1).g(),
428                      myBgGradientArray->GradientColor (1).b(), Quantity_TOC_RGB);
429   return Aspect_GradientBackground (aColor1, aColor2, myBgGradientArray->GradientFillMethod());
430 }
431
432 // =======================================================================
433 // function : SetGradientBackground
434 // purpose  :
435 // =======================================================================
436 void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground)
437 {
438   Quantity_Color aColor1, aColor2;
439   theBackground.Colors (aColor1, aColor2);
440   myBgGradientArray->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod());
441 }
442
443 // =======================================================================
444 // function : SetBackgroundImage
445 // purpose  :
446 // =======================================================================
447 void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath)
448 {
449   // Prepare aspect for texture storage
450   myBackgroundImagePath = theFilePath;
451   Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
452   Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
453   aTextureMap->EnableRepeat();
454   aTextureMap->DisableModulate();
455   aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
456                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
457                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
458   anAspect->SetTextureMap (aTextureMap);
459   anAspect->SetInteriorStyle (Aspect_IS_SOLID);
460   anAspect->SetSuppressBackFaces (false);
461   // Enable texture mapping
462   if (aTextureMap->IsDone())
463   {
464     anAspect->SetTextureMapOn();
465   }
466   else
467   {
468     anAspect->SetTextureMapOff();
469     return;
470   }
471
472   // Set texture parameters
473   myTextureParams->SetAspect (anAspect);
474 }
475
476 // =======================================================================
477 // function : BackgroundImageStyle
478 // purpose  :
479 // =======================================================================
480 Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const
481 {
482   return myBgTextureArray->TextureFillMethod();
483 }
484
485 // =======================================================================
486 // function : SetBackgroundImageStyle
487 // purpose  :
488 // =======================================================================
489 void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle)
490 {
491   myBgTextureArray->SetTextureFillMethod (theFillStyle);
492 }
493
494 //=======================================================================
495 //function : AddZLayer
496 //purpose  :
497 //=======================================================================
498 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
499 {
500   myZLayers.AddLayer (theLayerId);
501 }
502
503 //=======================================================================
504 //function : RemoveZLayer
505 //purpose  :
506 //=======================================================================
507 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
508 {
509   myZLayers.RemoveLayer (theLayerId);
510 }
511
512 //=======================================================================
513 //function : SetZLayerSettings
514 //purpose  :
515 //=======================================================================
516 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
517                                      const Graphic3d_ZLayerSettings& theSettings)
518 {
519   myZLayers.SetLayerSettings (theLayerId, theSettings);
520 }
521
522 //=======================================================================
523 //function : ZLayerMax
524 //purpose  :
525 //=======================================================================
526 Standard_Integer OpenGl_View::ZLayerMax() const
527 {
528   Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default;
529   for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next())
530   {
531     aLayerMax = Max (aLayerMax, aMapIt.Value());
532   }
533
534   return aLayerMax;
535 }
536
537 //=======================================================================
538 //function : InvalidateZLayerBoundingBox
539 //purpose  :
540 //=======================================================================
541 void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const
542 {
543   if (myZLayers.LayerIDs().IsBound (theLayerId))
544   {
545     myZLayers.Layer (theLayerId).InvalidateBoundingBox();
546   }
547   else
548   {
549     for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < ZLayerMax(); ++aLayerId)
550     {
551       if (myZLayers.LayerIDs().IsBound (aLayerId))
552       {
553         const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId);
554         if (aLayer.NbOfTransformPersistenceObjects() > 0)
555         {
556           aLayer.InvalidateBoundingBox();
557         }
558       }
559     }
560   }
561 }
562
563 //=======================================================================
564 //function : ZLayerBoundingBox
565 //purpose  :
566 //=======================================================================
567 Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
568                                                    const Handle(Graphic3d_Camera)& theCamera,
569                                                    const Standard_Integer          theWindowWidth,
570                                                    const Standard_Integer          theWindowHeight,
571                                                    const Standard_Boolean          theToIgnoreInfiniteFlag) const
572 {
573   if (myZLayers.LayerIDs().IsBound (theLayerId))
574   {
575     return myZLayers.Layer (theLayerId).BoundingBox (Identification(),
576                                                      theCamera,
577                                                      theWindowWidth,
578                                                      theWindowHeight,
579                                                      theToIgnoreInfiniteFlag);
580   }
581
582   return Graphic3d_BndBox4f();
583 }
584
585 //=======================================================================
586 //function : considerZoomPersistenceObjects
587 //purpose  :
588 //=======================================================================
589 Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId        theLayerId,
590                                                            const Handle(Graphic3d_Camera)& theCamera,
591                                                            const Standard_Integer          theWindowWidth,
592                                                            const Standard_Integer          theWindowHeight,
593                                                            const Standard_Boolean          theToIgnoreInfiniteFlag) const
594 {
595   if (myZLayers.LayerIDs().IsBound (theLayerId))
596   {
597     return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(),
598                                                                         theCamera,
599                                                                         theWindowWidth,
600                                                                         theWindowHeight,
601                                                                         theToIgnoreInfiniteFlag);
602   }
603
604   return 1.0;
605 }
606
607 //=======================================================================
608 //function : FBO
609 //purpose  :
610 //=======================================================================
611 Handle(Standard_Transient) OpenGl_View::FBO() const
612 {
613   return Handle(Standard_Transient)(myFBO);
614 }
615
616 //=======================================================================
617 //function : SetFBO
618 //purpose  :
619 //=======================================================================
620 void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo)
621 {
622   myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
623 }
624
625 //=======================================================================
626 //function : FBOCreate
627 //purpose  :
628 //=======================================================================
629 Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth,
630                                                    const Standard_Integer theHeight)
631 {
632   return myWorkspace->FBOCreate (theWidth, theHeight);
633 }
634
635 //=======================================================================
636 //function : FBORelease
637 //purpose  :
638 //=======================================================================
639 void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo)
640 {
641   Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
642   if (aFrameBuffer.IsNull())
643   {
644     return;
645   }
646
647   myWorkspace->FBORelease (aFrameBuffer);
648   theFbo.Nullify();
649 }
650
651 //=======================================================================
652 //function : FBOGetDimensions
653 //purpose  :
654 //=======================================================================
655 void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo,
656                                     Standard_Integer& theWidth,
657                                     Standard_Integer& theHeight,
658                                     Standard_Integer& theWidthMax,
659                                     Standard_Integer& theHeightMax)
660 {
661   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
662   if (aFrameBuffer.IsNull())
663   {
664     return;
665   }
666
667   theWidth     = aFrameBuffer->GetVPSizeX(); // current viewport size
668   theHeight    = aFrameBuffer->GetVPSizeY();
669   theWidthMax  = aFrameBuffer->GetSizeX(); // texture size
670   theHeightMax = aFrameBuffer->GetSizeY();
671 }
672
673 //=======================================================================
674 //function : FBOChangeViewport
675 //purpose  :
676 //=======================================================================
677 void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo,
678                                      const Standard_Integer theWidth,
679                                      const Standard_Integer theHeight)
680 {
681   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
682   if (aFrameBuffer.IsNull())
683   {
684     return;
685   }
686
687   aFrameBuffer->ChangeViewport (theWidth, theHeight);
688 }
689
690 // =======================================================================
691 // function : Export
692 // purpose  :
693 // =======================================================================
694 #ifdef HAVE_GL2PS
695 Standard_Boolean OpenGl_View::Export (const Standard_CString theFileName,
696                                       const Graphic3d_ExportFormat theFormat,
697                                       const Graphic3d_SortType theSortType)
698 {
699   // gl2psBeginPage() will call OpenGL functions
700   // so we should activate correct GL context before redraw scene call
701   if (!myWorkspace->Activate())
702   {
703     return Standard_False;
704   }
705
706   Standard_Integer aFormat = -1;
707   Standard_Integer aSortType = Graphic3d_ST_BSP_Tree;
708   switch (theFormat)
709   {
710     case Graphic3d_EF_PostScript:
711       aFormat = GL2PS_PS;
712       break;
713     case Graphic3d_EF_EnhPostScript:
714       aFormat = GL2PS_EPS;
715       break;
716     case Graphic3d_EF_TEX:
717       aFormat = GL2PS_TEX;
718       break;
719     case Graphic3d_EF_PDF:
720       aFormat = GL2PS_PDF;
721       break;
722     case Graphic3d_EF_SVG:
723       aFormat = GL2PS_SVG;
724       break;
725     case Graphic3d_EF_PGF:
726       aFormat = GL2PS_PGF;
727       break;
728     case Graphic3d_EF_EMF:
729       //aFormat = GL2PS_EMF;
730       aFormat = GL2PS_PGF + 1; // 6
731       break;
732     default:
733       // unsupported format
734       return Standard_False;
735   }
736
737   switch (theSortType)
738   {
739     case Graphic3d_ST_Simple:
740       aSortType = GL2PS_SIMPLE_SORT;
741       break;
742     case Graphic3d_ST_BSP_Tree:
743       aSortType = GL2PS_BSP_SORT;
744       break;
745   }
746
747   GLint aViewport[4];
748   aViewport[0] = 0;
749   aViewport[1] = 0;
750   aViewport[2] = myWindow->Width();
751   aViewport[3] = myWindow->Height();
752
753   GLint aBufferSize = 1024 * 1024;
754   GLint anErrCode = GL2PS_SUCCESS;
755
756   // gl2ps uses standard write functions and do not check locale
757   Standard_CLocaleSentry aLocaleSentry;
758
759   while (aBufferSize > 0)
760   {
761     // current patch for EMF support in gl2ps uses WinAPI functions to create file
762     FILE* aFileH = (theFormat != Graphic3d_EF_EMF) ? fopen (theFileName, "wb") : NULL;
763     anErrCode = gl2psBeginPage ("", "", aViewport, aFormat, aSortType,
764                     GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT/* | GL2PS_SIMPLE_LINE_OFFSET*/,
765                     GL_RGBA, 0, NULL,
766                     0, 0, 0, aBufferSize, aFileH, theFileName);
767     if (anErrCode != GL2PS_SUCCESS)
768     {
769       // initialization failed
770       if (aFileH != NULL)
771         fclose (aFileH);
772       break;
773     }
774     Redraw();
775
776     anErrCode = gl2psEndPage();
777     if (aFileH != NULL)
778       fclose (aFileH);
779
780     if (anErrCode == GL2PS_OVERFLOW)
781       aBufferSize *= 2;
782     else
783       break;
784   }
785   return anErrCode == GL2PS_SUCCESS;
786 }
787 #else
788 Standard_Boolean OpenGl_View::Export (const Standard_CString /*theFileName*/,
789                                       const Graphic3d_ExportFormat /*theFormat*/,
790                                       const Graphic3d_SortType /*theSortType*/)
791 {
792     return Standard_False;
793 }
794 #endif
795
796 //=======================================================================
797 //function : displayStructure
798 //purpose  :
799 //=======================================================================
800 void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure,
801                                     const Standard_Integer              thePriority)
802 {
803   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
804   const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
805   myZLayers.AddStructure (aStruct, aZLayer, thePriority);
806 }
807
808 //=======================================================================
809 //function : eraseStructure
810 //purpose  :
811 //=======================================================================
812 void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure)
813 {
814   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
815   myZLayers.RemoveStructure (aStruct);
816 }
817
818 //=======================================================================
819 //function : changeZLayer
820 //purpose  :
821 //=======================================================================
822 void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure,
823                                 const Graphic3d_ZLayerId theNewLayerId)
824 {
825   const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
826   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
827   myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
828   Update (Aspect_TOU_WAIT, anOldLayer);
829   Update (Aspect_TOU_WAIT, theNewLayerId);
830 }
831
832 //=======================================================================
833 //function : changePriority
834 //purpose  :
835 //=======================================================================
836 void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure,
837                                   const Standard_Integer theNewPriority)
838 {
839   const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
840   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
841   myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority);
842 }