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