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