98730438089074f142e52081ab1674b0cc624c93
[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 // function : Constructor
45 // purpose  :
46 // =======================================================================
47 OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
48                           const Handle(OpenGl_GraphicDriver)& theDriver,
49                           const Handle(OpenGl_Caps)& theCaps,
50                           Standard_Boolean& theDeviceLostFlag,
51                           OpenGl_StateCounter* theCounter)
52 : Graphic3d_CView  (theMgr),
53   myDriver         (theDriver.operator->()),
54   myCaps           (theCaps),
55   myDeviceLostFlag (theDeviceLostFlag),
56   myWasRedrawnGL   (Standard_False),
57   myCulling        (Standard_True),
58   myShadingModel   (Graphic3d_TOSM_FACET),
59   myBackfacing     (Graphic3d_TOBM_AUTOMATIC),
60   myBgColor        (Quantity_NOC_BLACK),
61   myCamera         (new Graphic3d_Camera()),
62   myUseGLLight     (Standard_True),
63   myToShowTrihedron      (false),
64   myToShowGradTrihedron  (false),
65   myStateCounter         (theCounter),
66   myLastLightSourceState (0, 0),
67   myFboColorFormat       (GL_RGBA8),
68   myFboDepthFormat       (GL_DEPTH24_STENCIL8),
69   myToFlipOutput         (Standard_False),
70   myFrameCounter         (0),
71   myHasFboBlit           (Standard_True),
72   myToDisableMSAA        (Standard_False),
73   myTransientDrawToFront (Standard_True),
74   myBackBufferRestored   (Standard_False),
75   myIsImmediateDrawn     (Standard_False),
76   myTextureParams   (new OpenGl_AspectFace()),
77   myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
78   myBgTextureArray  (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)),
79   // ray-tracing fields initialization
80   myRaytraceInitStatus     (OpenGl_RT_NONE),
81   myIsRaytraceDataValid    (Standard_False),
82   myIsRaytraceWarnTextures (Standard_False),
83   myToUpdateEnvironmentMap (Standard_False),
84   myLayerListState (0)
85 {
86   myWorkspace = new OpenGl_Workspace (this, NULL);
87
88   OpenGl_Light       aLight;
89   aLight.Type        = Graphic3d_TOLS_AMBIENT;
90   aLight.IsHeadlight = Standard_False;
91   aLight.Color.r()   = 1.;
92   aLight.Color.g()   = 1.;
93   aLight.Color.b()   = 1.;
94   myNoShadingLight.Append (aLight);
95
96   myCurrLightSourceState  = myStateCounter->Increment();
97   myMainSceneFbos[0]      = new OpenGl_FrameBuffer();
98   myMainSceneFbos[1]      = new OpenGl_FrameBuffer();
99   myImmediateSceneFbos[0] = new OpenGl_FrameBuffer();
100   myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
101   myOpenGlFBO             = new OpenGl_FrameBuffer();
102   myOpenGlFBO2            = new OpenGl_FrameBuffer();
103   myRaytraceFBO1[0]       = new OpenGl_FrameBuffer();
104   myRaytraceFBO1[1]       = new OpenGl_FrameBuffer();
105   myRaytraceFBO2[0]       = new OpenGl_FrameBuffer();
106   myRaytraceFBO2[1]       = new OpenGl_FrameBuffer();
107 }
108
109 // =======================================================================
110 // function : Destructor
111 // purpose  :
112 // =======================================================================
113 OpenGl_View::~OpenGl_View()
114 {
115   ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
116   OpenGl_Element::Destroy (NULL, myBgGradientArray);
117   OpenGl_Element::Destroy (NULL, myBgTextureArray);
118   OpenGl_Element::Destroy (NULL, myTextureParams);
119 }
120
121 // =======================================================================
122 // function : ReleaseGlResources
123 // purpose  :
124 // =======================================================================
125 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
126 {
127   myTrihedron         .Release (theCtx.operator->());
128   myGraduatedTrihedron.Release (theCtx.operator->());
129
130   if (!myTextureEnv.IsNull())
131   {
132     theCtx->DelayedRelease (myTextureEnv);
133     myTextureEnv.Nullify();
134   }
135
136   if (myTextureParams != NULL)
137   {
138     myTextureParams->Release (theCtx.operator->());
139   }
140   if (myBgGradientArray != NULL)
141   {
142     myBgGradientArray->Release (theCtx.operator->());
143   }
144   if (myBgTextureArray != NULL)
145   {
146     myBgTextureArray->Release (theCtx.operator->());
147   }
148
149   myMainSceneFbos[0]     ->Release (theCtx.operator->());
150   myMainSceneFbos[1]     ->Release (theCtx.operator->());
151   myImmediateSceneFbos[0]->Release (theCtx.operator->());
152   myImmediateSceneFbos[1]->Release (theCtx.operator->());
153   myOpenGlFBO            ->Release (theCtx.operator->());
154   myOpenGlFBO2           ->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 (myBgColor.GetRGB());
385 }
386
387 // =======================================================================
388 // function : SetBackground
389 // purpose  :
390 // =======================================================================
391 void OpenGl_View::SetBackground (const Aspect_Background& theBackground)
392 {
393   myBgColor.SetRGB (theBackground.Color());
394 }
395
396 // =======================================================================
397 // function : GradientBackground
398 // purpose  :
399 // =======================================================================
400 Aspect_GradientBackground OpenGl_View::GradientBackground() const
401 {
402   Quantity_Color aColor1, aColor2;
403   aColor1.SetValues (myBgGradientArray->GradientColor (0).r(),
404                      myBgGradientArray->GradientColor (0).g(),
405                      myBgGradientArray->GradientColor (0).b(), Quantity_TOC_RGB);
406   aColor2.SetValues (myBgGradientArray->GradientColor (1).r(),
407                      myBgGradientArray->GradientColor (1).g(),
408                      myBgGradientArray->GradientColor (1).b(), Quantity_TOC_RGB);
409   return Aspect_GradientBackground (aColor1, aColor2, myBgGradientArray->GradientFillMethod());
410 }
411
412 // =======================================================================
413 // function : SetGradientBackground
414 // purpose  :
415 // =======================================================================
416 void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground)
417 {
418   Quantity_Color aColor1, aColor2;
419   theBackground.Colors (aColor1, aColor2);
420   myBgGradientArray->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod());
421 }
422
423 // =======================================================================
424 // function : SetBackgroundImage
425 // purpose  :
426 // =======================================================================
427 void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath)
428 {
429   // Prepare aspect for texture storage
430   myBackgroundImagePath = theFilePath;
431   Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
432   Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
433   aTextureMap->EnableRepeat();
434   aTextureMap->DisableModulate();
435   aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
436                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
437                                         Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
438   anAspect->SetTextureMap (aTextureMap);
439   anAspect->SetInteriorStyle (Aspect_IS_SOLID);
440   anAspect->SetSuppressBackFaces (false);
441   // Enable texture mapping
442   if (aTextureMap->IsDone())
443   {
444     anAspect->SetTextureMapOn();
445   }
446   else
447   {
448     anAspect->SetTextureMapOff();
449     return;
450   }
451
452   // Set texture parameters
453   myTextureParams->SetAspect (anAspect);
454 }
455
456 // =======================================================================
457 // function : BackgroundImageStyle
458 // purpose  :
459 // =======================================================================
460 Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const
461 {
462   return myBgTextureArray->TextureFillMethod();
463 }
464
465 // =======================================================================
466 // function : SetBackgroundImageStyle
467 // purpose  :
468 // =======================================================================
469 void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle)
470 {
471   myBgTextureArray->SetTextureFillMethod (theFillStyle);
472 }
473
474 //=======================================================================
475 //function : AddZLayer
476 //purpose  :
477 //=======================================================================
478 void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
479 {
480   myZLayers.AddLayer (theLayerId);
481 }
482
483 //=======================================================================
484 //function : RemoveZLayer
485 //purpose  :
486 //=======================================================================
487 void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
488 {
489   myZLayers.RemoveLayer (theLayerId);
490 }
491
492 //=======================================================================
493 //function : SetZLayerSettings
494 //purpose  :
495 //=======================================================================
496 void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
497                                      const Graphic3d_ZLayerSettings& theSettings)
498 {
499   myZLayers.SetLayerSettings (theLayerId, theSettings);
500 }
501
502 //=======================================================================
503 //function : ZLayerMax
504 //purpose  :
505 //=======================================================================
506 Standard_Integer OpenGl_View::ZLayerMax() const
507 {
508   Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default;
509   for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next())
510   {
511     aLayerMax = Max (aLayerMax, aMapIt.Value());
512   }
513
514   return aLayerMax;
515 }
516
517 //=======================================================================
518 //function : InvalidateZLayerBoundingBox
519 //purpose  :
520 //=======================================================================
521 void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const
522 {
523   if (myZLayers.LayerIDs().IsBound (theLayerId))
524   {
525     myZLayers.Layer (theLayerId).InvalidateBoundingBox();
526   }
527   else
528   {
529     for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < ZLayerMax(); ++aLayerId)
530     {
531       if (myZLayers.LayerIDs().IsBound (aLayerId))
532       {
533         const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId);
534         if (aLayer.NbOfTransformPersistenceObjects() > 0)
535         {
536           aLayer.InvalidateBoundingBox();
537         }
538       }
539     }
540   }
541 }
542
543 //=======================================================================
544 //function : ZLayerBoundingBox
545 //purpose  :
546 //=======================================================================
547 Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
548                                                    const Handle(Graphic3d_Camera)& theCamera,
549                                                    const Standard_Integer          theWindowWidth,
550                                                    const Standard_Integer          theWindowHeight,
551                                                    const Standard_Boolean          theToIncludeAuxiliary) const
552 {
553   Graphic3d_BndBox4f aBox;
554   if (myZLayers.LayerIDs().IsBound (theLayerId))
555   {
556     aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(),
557                                                      theCamera,
558                                                      theWindowWidth,
559                                                      theWindowHeight,
560                                                      theToIncludeAuxiliary);
561   }
562
563   // add bounding box of gradient/texture background for proper Z-fit
564   if (theToIncludeAuxiliary
565    && theLayerId == Graphic3d_ZLayerId_BotOSD
566    && (myBgTextureArray->IsDefined()
567     || myBgGradientArray->IsDefined()))
568   {
569     // Background is drawn using 2D transformation persistence
570     // (e.g. it is actually placed in 3D coordinates within active camera position).
571     // We add here full-screen plane with 2D transformation persistence
572     // for simplicity (myBgTextureArray might define a little bit different options
573     // but it is updated within ::Render())
574     const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
575     const Graphic3d_Mat4& aWorldViewMat  = theCamera->OrientationMatrixF();
576     Graphic3d_BndBox4f aBox2d (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
577                                Graphic3d_Vec4 (float(theWindowWidth), float(theWindowHeight), 0.0f, 0.0f));
578
579     Graphic3d_TransformPers aTrsfPers;
580     aTrsfPers.Flags = Graphic3d_TMF_2d;
581     aTrsfPers.Point = Graphic3d_Vec3d(-1.0, -1.0, 0.0);
582     aTrsfPers.Apply (theCamera,
583                      aProjectionMat,
584                      aWorldViewMat,
585                      theWindowWidth,
586                      theWindowHeight,
587                      aBox2d);
588     aBox.Combine (aBox2d);
589   }
590
591   return aBox;
592 }
593
594 //=======================================================================
595 //function : considerZoomPersistenceObjects
596 //purpose  :
597 //=======================================================================
598 Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId        theLayerId,
599                                                            const Handle(Graphic3d_Camera)& theCamera,
600                                                            const Standard_Integer          theWindowWidth,
601                                                            const Standard_Integer          theWindowHeight) const
602 {
603   if (myZLayers.LayerIDs().IsBound (theLayerId))
604   {
605     return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(),
606                                                                         theCamera,
607                                                                         theWindowWidth,
608                                                                         theWindowHeight);
609   }
610
611   return 1.0;
612 }
613
614 //=======================================================================
615 //function : FBO
616 //purpose  :
617 //=======================================================================
618 Handle(Standard_Transient) OpenGl_View::FBO() const
619 {
620   return Handle(Standard_Transient)(myFBO);
621 }
622
623 //=======================================================================
624 //function : SetFBO
625 //purpose  :
626 //=======================================================================
627 void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo)
628 {
629   myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
630 }
631
632 //=======================================================================
633 //function : FBOCreate
634 //purpose  :
635 //=======================================================================
636 Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth,
637                                                    const Standard_Integer theHeight)
638 {
639   return myWorkspace->FBOCreate (theWidth, theHeight);
640 }
641
642 //=======================================================================
643 //function : FBORelease
644 //purpose  :
645 //=======================================================================
646 void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo)
647 {
648   Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
649   if (aFrameBuffer.IsNull())
650   {
651     return;
652   }
653
654   myWorkspace->FBORelease (aFrameBuffer);
655   theFbo.Nullify();
656 }
657
658 //=======================================================================
659 //function : FBOGetDimensions
660 //purpose  :
661 //=======================================================================
662 void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo,
663                                     Standard_Integer& theWidth,
664                                     Standard_Integer& theHeight,
665                                     Standard_Integer& theWidthMax,
666                                     Standard_Integer& theHeightMax)
667 {
668   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
669   if (aFrameBuffer.IsNull())
670   {
671     return;
672   }
673
674   theWidth     = aFrameBuffer->GetVPSizeX(); // current viewport size
675   theHeight    = aFrameBuffer->GetVPSizeY();
676   theWidthMax  = aFrameBuffer->GetSizeX(); // texture size
677   theHeightMax = aFrameBuffer->GetSizeY();
678 }
679
680 //=======================================================================
681 //function : FBOChangeViewport
682 //purpose  :
683 //=======================================================================
684 void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo,
685                                      const Standard_Integer theWidth,
686                                      const Standard_Integer theHeight)
687 {
688   const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
689   if (aFrameBuffer.IsNull())
690   {
691     return;
692   }
693
694   aFrameBuffer->ChangeViewport (theWidth, theHeight);
695 }
696
697 // =======================================================================
698 // function : Export
699 // purpose  :
700 // =======================================================================
701 #ifdef HAVE_GL2PS
702 Standard_Boolean OpenGl_View::Export (const Standard_CString theFileName,
703                                       const Graphic3d_ExportFormat theFormat,
704                                       const Graphic3d_SortType theSortType)
705 {
706   // gl2psBeginPage() will call OpenGL functions
707   // so we should activate correct GL context before redraw scene call
708   if (!myWorkspace->Activate())
709   {
710     return Standard_False;
711   }
712
713   Standard_Integer aFormat = -1;
714   Standard_Integer aSortType = Graphic3d_ST_BSP_Tree;
715   switch (theFormat)
716   {
717     case Graphic3d_EF_PostScript:
718       aFormat = GL2PS_PS;
719       break;
720     case Graphic3d_EF_EnhPostScript:
721       aFormat = GL2PS_EPS;
722       break;
723     case Graphic3d_EF_TEX:
724       aFormat = GL2PS_TEX;
725       break;
726     case Graphic3d_EF_PDF:
727       aFormat = GL2PS_PDF;
728       break;
729     case Graphic3d_EF_SVG:
730       aFormat = GL2PS_SVG;
731       break;
732     case Graphic3d_EF_PGF:
733       aFormat = GL2PS_PGF;
734       break;
735     case Graphic3d_EF_EMF:
736       //aFormat = GL2PS_EMF;
737       aFormat = GL2PS_PGF + 1; // 6
738       break;
739     default:
740       // unsupported format
741       return Standard_False;
742   }
743
744   switch (theSortType)
745   {
746     case Graphic3d_ST_Simple:
747       aSortType = GL2PS_SIMPLE_SORT;
748       break;
749     case Graphic3d_ST_BSP_Tree:
750       aSortType = GL2PS_BSP_SORT;
751       break;
752   }
753
754   GLint aViewport[4];
755   aViewport[0] = 0;
756   aViewport[1] = 0;
757   aViewport[2] = myWindow->Width();
758   aViewport[3] = myWindow->Height();
759
760   GLint aBufferSize = 1024 * 1024;
761   GLint anErrCode = GL2PS_SUCCESS;
762
763   // gl2ps uses standard write functions and do not check locale
764   Standard_CLocaleSentry aLocaleSentry;
765
766   while (aBufferSize > 0)
767   {
768     // current patch for EMF support in gl2ps uses WinAPI functions to create file
769     FILE* aFileH = (theFormat != Graphic3d_EF_EMF) ? fopen (theFileName, "wb") : NULL;
770     anErrCode = gl2psBeginPage ("", "", aViewport, aFormat, aSortType,
771                     GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT/* | GL2PS_SIMPLE_LINE_OFFSET*/,
772                     GL_RGBA, 0, NULL,
773                     0, 0, 0, aBufferSize, aFileH, theFileName);
774     if (anErrCode != GL2PS_SUCCESS)
775     {
776       // initialization failed
777       if (aFileH != NULL)
778         fclose (aFileH);
779       break;
780     }
781     Redraw();
782
783     anErrCode = gl2psEndPage();
784     if (aFileH != NULL)
785       fclose (aFileH);
786
787     if (anErrCode == GL2PS_OVERFLOW)
788       aBufferSize *= 2;
789     else
790       break;
791   }
792   return anErrCode == GL2PS_SUCCESS;
793 }
794 #else
795 Standard_Boolean OpenGl_View::Export (const Standard_CString /*theFileName*/,
796                                       const Graphic3d_ExportFormat /*theFormat*/,
797                                       const Graphic3d_SortType /*theSortType*/)
798 {
799     return Standard_False;
800 }
801 #endif
802
803 //=======================================================================
804 //function : displayStructure
805 //purpose  :
806 //=======================================================================
807 void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure,
808                                     const Standard_Integer              thePriority)
809 {
810   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
811   const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
812   myZLayers.AddStructure (aStruct, aZLayer, thePriority);
813 }
814
815 //=======================================================================
816 //function : eraseStructure
817 //purpose  :
818 //=======================================================================
819 void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure)
820 {
821   const OpenGl_Structure*  aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
822   myZLayers.RemoveStructure (aStruct);
823 }
824
825 //=======================================================================
826 //function : changeZLayer
827 //purpose  :
828 //=======================================================================
829 void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure,
830                                 const Graphic3d_ZLayerId theNewLayerId)
831 {
832   const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
833   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
834   myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
835   Update (Aspect_TOU_WAIT, anOldLayer);
836   Update (Aspect_TOU_WAIT, theNewLayerId);
837 }
838
839 //=======================================================================
840 //function : changePriority
841 //purpose  :
842 //=======================================================================
843 void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure,
844                                   const Standard_Integer theNewPriority)
845 {
846   const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
847   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
848   myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority);
849 }
850
851 //=======================================================================
852 //function : DiagnosticInformation
853 //purpose  :
854 //=======================================================================
855 void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
856                                          Graphic3d_DiagnosticInfo theFlags) const
857 {
858   Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
859   if (!myWorkspace->Activate()
860    || aCtx.IsNull())
861   {
862     return;
863   }
864
865   aCtx->DiagnosticInformation (theDict, theFlags);
866   if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
867   {
868     TCollection_AsciiString aResRatio (myRenderParams.ResolutionRatio());
869     theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio;
870   }
871 }