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