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