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