0029477: Visualization, TKOpenGl - MSAA FBO initialization failure on OpenGL ES 3...
[occt.git] / src / OpenGl / OpenGl_View.cxx
CommitLineData
b311480e 1// Created on: 2011-09-20
2// Created by: Sergey ZERCHANINOV
973c2be1 3// Copyright (c) 2011-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
c357e426 16#include <OpenGl_View.hxx>
5f8b738e 17
c357e426 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>
bf75be98 25#include <OpenGl_Context.hxx>
c357e426 26#include <OpenGl_FrameBuffer.hxx>
30f0ad28 27#include <OpenGl_GlCore11.hxx>
28#include <OpenGl_GraduatedTrihedron.hxx>
392ac980 29#include <OpenGl_GraphicDriver.hxx>
30f0ad28 30#include <OpenGl_ShaderManager.hxx>
bf75be98 31#include <OpenGl_Texture.hxx>
c357e426 32#include <OpenGl_Window.hxx>
30f0ad28 33#include <OpenGl_Workspace.hxx>
f5b72419 34#include <OSD_Parallel.hxx>
c357e426 35#include <Standard_CLocaleSentry.hxx>
2166f0fa 36
f5b72419 37#include "../Graphic3d/Graphic3d_Structure.pxx"
38
92efcf78 39IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,Graphic3d_CView)
40
c357e426 41#ifdef HAVE_GL2PS
42#include <gl2ps.h>
43#endif
2166f0fa 44
c357e426 45// =======================================================================
46// function : Constructor
47// purpose :
48// =======================================================================
49OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
50 const Handle(OpenGl_GraphicDriver)& theDriver,
51 const Handle(OpenGl_Caps)& theCaps,
c357e426 52 OpenGl_StateCounter* theCounter)
53: Graphic3d_CView (theMgr),
54 myDriver (theDriver.operator->()),
55 myCaps (theCaps),
c357e426 56 myWasRedrawnGL (Standard_False),
c357e426 57 myCulling (Standard_True),
58 myShadingModel (Graphic3d_TOSM_FACET),
c357e426 59 myBackfacing (Graphic3d_TOBM_AUTOMATIC),
b6472664 60 myBgColor (Quantity_NOC_BLACK),
c357e426 61 myCamera (new Graphic3d_Camera()),
c357e426 62 myToShowGradTrihedron (false),
f5b72419 63 myZLayers (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1),
c357e426 64 myStateCounter (theCounter),
992ed6b3 65 myCurrLightSourceState (theCounter->Increment()),
66 myLightsRevision (0),
0b0320e7 67 myLastLightSourceState (0, 0),
3c4b62a4 68 myFboColorFormat (GL_RGBA8),
69 myFboDepthFormat (GL_DEPTH24_STENCIL8),
70 myToFlipOutput (Standard_False),
c357e426 71 myFrameCounter (0),
72 myHasFboBlit (Standard_True),
a1073ae2 73 myToDisableOIT (Standard_False),
74 myToDisableOITMSAA (Standard_False),
7ccf8676 75 myToDisableMSAA (Standard_False),
c357e426 76 myTransientDrawToFront (Standard_True),
77 myBackBufferRestored (Standard_False),
78 myIsImmediateDrawn (Standard_False),
0b0320e7 79 myTextureParams (new OpenGl_AspectFace()),
80 myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
91c60b57 81 myBgTextureArray (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)),
82 // ray-tracing fields initialization
c357e426 83 myRaytraceInitStatus (OpenGl_RT_NONE),
84 myIsRaytraceDataValid (Standard_False),
91c60b57 85 myIsRaytraceWarnTextures (Standard_False),
f5b72419 86 myRaytraceBVHBuilder (new BVH_BinnedBuilder<Standard_ShortReal, 3, BVH_Constants_NbBinsBest> (BVH_Constants_LeafNodeSizeAverage,
87 BVH_Constants_MaxTreeDepth,
88 Standard_False,
89 OSD_Parallel::NbLogicalProcessors() + 1)),
90 myRaytraceSceneRadius (0.0f),
91 myRaytraceSceneEpsilon (1.0e-6f),
91c60b57 92 myToUpdateEnvironmentMap (Standard_False),
b27ab03d 93 myRaytraceLayerListState (0),
94 myPrevCameraApertureRadius(0.f),
95 myPrevCameraFocalPlaneDist(0.f)
2166f0fa 96{
c357e426 97 myWorkspace = new OpenGl_Workspace (this, NULL);
2166f0fa 98
992ed6b3 99 Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT);
100 aLight->SetHeadlight (false);
101 aLight->SetColor (Quantity_NOC_WHITE);
102 myNoShadingLight = new Graphic3d_LightSet();
103 myNoShadingLight->Add (aLight);
016e5959 104
a1073ae2 105 myMainSceneFbos[0] = new OpenGl_FrameBuffer();
106 myMainSceneFbos[1] = new OpenGl_FrameBuffer();
107 myMainSceneFbosOit[0] = new OpenGl_FrameBuffer();
108 myMainSceneFbosOit[1] = new OpenGl_FrameBuffer();
109 myImmediateSceneFbos[0] = new OpenGl_FrameBuffer();
110 myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
111 myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer();
112 myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer();
113 myOpenGlFBO = new OpenGl_FrameBuffer();
114 myOpenGlFBO2 = new OpenGl_FrameBuffer();
115 myRaytraceFBO1[0] = new OpenGl_FrameBuffer();
116 myRaytraceFBO1[1] = new OpenGl_FrameBuffer();
117 myRaytraceFBO2[0] = new OpenGl_FrameBuffer();
118 myRaytraceFBO2[1] = new OpenGl_FrameBuffer();
c357e426 119}
120
121// =======================================================================
122// function : Destructor
123// purpose :
124// =======================================================================
0b0320e7 125OpenGl_View::~OpenGl_View()
2166f0fa 126{
bf75be98 127 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
0b0320e7 128 OpenGl_Element::Destroy (NULL, myBgGradientArray);
129 OpenGl_Element::Destroy (NULL, myBgTextureArray);
130 OpenGl_Element::Destroy (NULL, myTextureParams);
bf75be98 131}
132
c357e426 133// =======================================================================
134// function : ReleaseGlResources
135// purpose :
136// =======================================================================
bf75be98 137void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
138{
536d98e2 139 myGraduatedTrihedron.Release (theCtx.operator->());
15669413 140 myFrameStatsPrs.Release (theCtx.operator->());
30f0ad28 141
bf75be98 142 if (!myTextureEnv.IsNull())
143 {
cc8cbabe 144 for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
145 {
146 theCtx->DelayedRelease (aTextureIter.ChangeValue());
147 aTextureIter.ChangeValue().Nullify();
148 }
bf75be98 149 myTextureEnv.Nullify();
150 }
0b0320e7 151
152 if (myTextureParams != NULL)
153 {
154 myTextureParams->Release (theCtx.operator->());
155 }
156 if (myBgGradientArray != NULL)
157 {
158 myBgGradientArray->Release (theCtx.operator->());
159 }
160 if (myBgTextureArray != NULL)
bf75be98 161 {
0b0320e7 162 myBgTextureArray->Release (theCtx.operator->());
bf75be98 163 }
91c60b57 164
a1073ae2 165 myMainSceneFbos[0] ->Release (theCtx.operator->());
166 myMainSceneFbos[1] ->Release (theCtx.operator->());
167 myMainSceneFbosOit[0] ->Release (theCtx.operator->());
168 myMainSceneFbosOit[1] ->Release (theCtx.operator->());
169 myImmediateSceneFbos[0] ->Release (theCtx.operator->());
170 myImmediateSceneFbos[1] ->Release (theCtx.operator->());
171 myImmediateSceneFbosOit[0]->Release (theCtx.operator->());
172 myImmediateSceneFbosOit[1]->Release (theCtx.operator->());
173 myOpenGlFBO ->Release (theCtx.operator->());
174 myOpenGlFBO2 ->Release (theCtx.operator->());
175 myFullScreenQuad .Release (theCtx.operator->());
176 myFullScreenQuadFlip .Release (theCtx.operator->());
c357e426 177
91c60b57 178 releaseRaytraceResources (theCtx);
bf75be98 179}
2166f0fa 180
c357e426 181// =======================================================================
182// function : Remove
183// purpose :
184// =======================================================================
185void OpenGl_View::Remove()
bf75be98 186{
c357e426 187 if (IsRemoved())
bf75be98 188 {
c357e426 189 return;
bf75be98 190 }
191
c357e426 192 myDriver->RemoveView (this);
193 myWindow.Nullify();
194
195 Graphic3d_CView::Remove();
196}
197
198// =======================================================================
199// function : SetTextureEnv
200// purpose :
201// =======================================================================
7c3ef2f7 202void OpenGl_View::SetCamera(const Handle(Graphic3d_Camera)& theCamera)
203{
204 myCamera = theCamera;
205}
206
207// =======================================================================
208// function : SetLocalOrigin
209// purpose :
210// =======================================================================
211void OpenGl_View::SetLocalOrigin (const gp_XYZ& theOrigin)
212{
213 myLocalOrigin = theOrigin;
214 const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
215 if (!aCtx.IsNull())
216 {
217 aCtx->ShaderManager()->SetLocalOrigin (theOrigin);
218 }
219}
220
221// =======================================================================
222// function : SetTextureEnv
223// purpose :
224// =======================================================================
c357e426 225void OpenGl_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv)
226{
227 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
228 if (!aCtx.IsNull() && !myTextureEnv.IsNull())
229 {
cc8cbabe 230 for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
231 {
232 aCtx->DelayedRelease (aTextureIter.ChangeValue());
233 aTextureIter.ChangeValue().Nullify();
234 }
c357e426 235 }
236
237 myToUpdateEnvironmentMap = Standard_True;
238 myTextureEnvData = theTextureEnv;
239 myTextureEnv.Nullify();
240 initTextureEnv (aCtx);
241}
242
243// =======================================================================
244// function : initTextureEnv
245// purpose :
246// =======================================================================
247void OpenGl_View::initTextureEnv (const Handle(OpenGl_Context)& theContext)
248{
249 if (myTextureEnvData.IsNull()
250 || theContext.IsNull()
251 || !theContext->MakeCurrent())
bf75be98 252 {
253 return;
254 }
255
cc8cbabe 256 myTextureEnv = new OpenGl_TextureSet (1);
257 Handle(OpenGl_Texture)& aTextureEnv = myTextureEnv->ChangeFirst();
258 aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams());
c357e426 259 Handle(Image_PixMap) anImage = myTextureEnvData->GetImage();
e276548b 260 if (!anImage.IsNull())
c357e426 261 {
cc8cbabe 262 aTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type());
c357e426 263 }
264}
e276548b 265
c357e426 266// =======================================================================
267// function : SetImmediateModeDrawToFront
268// purpose :
269// =======================================================================
270Standard_Boolean OpenGl_View::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
271{
272 const Standard_Boolean aPrevMode = myTransientDrawToFront;
273 myTransientDrawToFront = theDrawToFrontBuffer;
274 return aPrevMode;
e276548b 275}
276
c357e426 277// =======================================================================
278// function : SetWindow
279// purpose :
280// =======================================================================
281void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow,
a521d90d 282 const Aspect_RenderingContext theContext)
e276548b 283{
c357e426 284 myWindow = myDriver->CreateRenderWindow (theWindow, theContext);
285 Standard_ASSERT_RAISE (!myWindow.IsNull(),
286 "OpenGl_View::SetWindow, "
287 "Failed to create OpenGl window.");
e276548b 288
c357e426 289 myWorkspace = new OpenGl_Workspace (this, myWindow);
290 myWorldViewProjState.Reset();
91c60b57 291 myToUpdateEnvironmentMap = Standard_True;
c357e426 292 myHasFboBlit = Standard_True;
293 Invalidate();
294
295 // Environment texture resource does not support lazy initialization.
296 initTextureEnv (myWorkspace->GetGlContext());
297}
298
299// =======================================================================
300// function : Resized
301// purpose :
302// =======================================================================
303void OpenGl_View::Resized()
304{
305 if (myWindow.IsNull())
306 return;
307
308 myWindow->Resize();
309}
310
311// =======================================================================
c357e426 312// function : SetMinMaxValuesCallback
313// purpose :
314// =======================================================================
315static void SetMinMaxValuesCallback (Graphic3d_CView* theView)
316{
317 OpenGl_View* aView = dynamic_cast<OpenGl_View*>(theView);
318 if (aView == NULL)
319 return;
320
321 Bnd_Box aBox = theView->MinMaxValues();
322 if (!aBox.IsVoid())
2166f0fa 323 {
c357e426 324 gp_Pnt aMin = aBox.CornerMin();
325 gp_Pnt aMax = aBox.CornerMax();
326
327 Graphic3d_Vec3 aMinVec ((Standard_ShortReal )aMin.X(), (Standard_ShortReal )aMin.Y(), (Standard_ShortReal )aMin.Z());
328 Graphic3d_Vec3 aMaxVec ((Standard_ShortReal )aMax.X(), (Standard_ShortReal )aMax.Y(), (Standard_ShortReal )aMax.Z());
329 aView->GraduatedTrihedronMinMaxValues (aMinVec, aMaxVec);
2166f0fa
SK
330 }
331}
332
c357e426 333// =======================================================================
334// function : GraduatedTrihedronDisplay
335// purpose :
336// =======================================================================
337void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData)
338{
339 myGTrihedronData = theTrihedronData;
340 myGTrihedronData.PtrView = this;
341 myGTrihedronData.CubicAxesCallback = SetMinMaxValuesCallback;
342 myGraduatedTrihedron.SetValues (myGTrihedronData);
343 myToShowGradTrihedron = true;
344}
2166f0fa 345
c357e426 346// =======================================================================
347// function : GraduatedTrihedronErase
348// purpose :
349// =======================================================================
350void OpenGl_View::GraduatedTrihedronErase()
2166f0fa 351{
c357e426 352 myGTrihedronData.PtrView = NULL;
353 myGraduatedTrihedron.Release (myWorkspace->GetGlContext().operator->());
354 myToShowGradTrihedron = false;
2166f0fa
SK
355}
356
c357e426 357// =======================================================================
358// function : GraduatedTrihedronMinMaxValues
359// purpose :
360// =======================================================================
361void OpenGl_View::GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax)
362{
363 myGraduatedTrihedron.SetMinMax (theMin, theMax);
364}
2166f0fa 365
c357e426 366// =======================================================================
c357e426 367// function : BufferDump
368// purpose :
369// =======================================================================
370Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType)
371{
38d90bb3 372 if (theBufferType != Graphic3d_BT_RGB_RayTraceHdrLeft)
373 {
374 return myWorkspace->BufferDump(myFBO, theImage, theBufferType);
375 }
376
377 if (!myRaytraceParameters.AdaptiveScreenSampling)
378 {
379 return myWorkspace->BufferDump(myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType);
380 }
381
382#if defined(GL_ES_VERSION_2_0)
383 return false;
384#else
385 if (theImage.Format() != Image_Format_RGBF)
386 {
387 return false;
388 }
389
390 const GLuint aW = myRaytraceOutputTexture[0]->SizeX();
391 const GLuint aH = myRaytraceOutputTexture[0]->SizeY();
392 if (aW / 3 != theImage.SizeX() || aH / 2 != theImage.SizeY())
393 {
394 return false;
395 }
396
397 std::vector<GLfloat> aValues;
398 try
399 {
400 aValues.resize (aW * aH);
401 }
402 catch (const std::bad_alloc&)
403 {
404 return false;
405 }
406
407 glBindTexture (GL_TEXTURE_RECTANGLE, myRaytraceOutputTexture[0]->TextureId());
408 glGetTexImage (GL_TEXTURE_RECTANGLE, 0, OpenGl_TextureFormat::Create<GLfloat, 1>().Format(), GL_FLOAT, &aValues[0]);
409 glBindTexture (GL_TEXTURE_RECTANGLE, 0);
410 for (unsigned int aRow = 0; aRow < aH; aRow += 2)
411 {
412 for (unsigned int aCol = 0; aCol < aW; aCol += 3)
413 {
414 float* anImageValue = theImage.ChangeValue<float[3]> ((aH - aRow) / 2 - 1, aCol / 3);
415 float aInvNbSamples = 1.f / aValues[aRow * aW + aCol + aW];
416 anImageValue[0] = aValues[aRow * aW + aCol] * aInvNbSamples;
417 anImageValue[1] = aValues[aRow * aW + aCol + 1] * aInvNbSamples;
418 anImageValue[2] = aValues[aRow * aW + aCol + 1 + aW] * aInvNbSamples;
419 }
420 }
421
422 return true;
423#endif
c357e426 424}
425
426// =======================================================================
427// function : Background
428// purpose :
429// =======================================================================
430Aspect_Background OpenGl_View::Background() const
431{
b6472664 432 return Aspect_Background (myBgColor.GetRGB());
c357e426 433}
434
435// =======================================================================
436// function : SetBackground
437// purpose :
438// =======================================================================
439void OpenGl_View::SetBackground (const Aspect_Background& theBackground)
440{
b6472664 441 myBgColor.SetRGB (theBackground.Color());
c357e426 442}
443
444// =======================================================================
445// function : GradientBackground
446// purpose :
447// =======================================================================
448Aspect_GradientBackground OpenGl_View::GradientBackground() const
449{
450 Quantity_Color aColor1, aColor2;
451 aColor1.SetValues (myBgGradientArray->GradientColor (0).r(),
452 myBgGradientArray->GradientColor (0).g(),
453 myBgGradientArray->GradientColor (0).b(), Quantity_TOC_RGB);
454 aColor2.SetValues (myBgGradientArray->GradientColor (1).r(),
455 myBgGradientArray->GradientColor (1).g(),
456 myBgGradientArray->GradientColor (1).b(), Quantity_TOC_RGB);
457 return Aspect_GradientBackground (aColor1, aColor2, myBgGradientArray->GradientFillMethod());
458}
2166f0fa 459
c357e426 460// =======================================================================
461// function : SetGradientBackground
462// purpose :
463// =======================================================================
464void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground)
2166f0fa 465{
c357e426 466 Quantity_Color aColor1, aColor2;
467 theBackground.Colors (aColor1, aColor2);
468 myBgGradientArray->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod());
469}
470
471// =======================================================================
472// function : SetBackgroundImage
473// purpose :
474// =======================================================================
475void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath)
476{
477 // Prepare aspect for texture storage
478 myBackgroundImagePath = theFilePath;
479 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
480 Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
481 aTextureMap->EnableRepeat();
482 aTextureMap->DisableModulate();
483 aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
484 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
485 Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
486 anAspect->SetTextureMap (aTextureMap);
487 anAspect->SetInteriorStyle (Aspect_IS_SOLID);
b6472664 488 anAspect->SetSuppressBackFaces (false);
c357e426 489 // Enable texture mapping
490 if (aTextureMap->IsDone())
2166f0fa 491 {
c357e426 492 anAspect->SetTextureMapOn();
2166f0fa
SK
493 }
494 else
495 {
c357e426 496 anAspect->SetTextureMapOff();
497 return;
498 }
2166f0fa 499
c357e426 500 // Set texture parameters
501 myTextureParams->SetAspect (anAspect);
502}
2166f0fa 503
c357e426 504// =======================================================================
505// function : BackgroundImageStyle
506// purpose :
507// =======================================================================
508Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const
509{
510 return myBgTextureArray->TextureFillMethod();
2166f0fa
SK
511}
512
c357e426 513// =======================================================================
514// function : SetBackgroundImageStyle
515// purpose :
516// =======================================================================
517void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle)
518{
519 myBgTextureArray->SetTextureFillMethod (theFillStyle);
520}
2166f0fa 521
c357e426 522//=======================================================================
523//function : AddZLayer
524//purpose :
525//=======================================================================
526void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
2166f0fa 527{
c357e426 528 myZLayers.AddLayer (theLayerId);
2166f0fa
SK
529}
530
c357e426 531//=======================================================================
532//function : RemoveZLayer
533//purpose :
534//=======================================================================
535void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
536{
537 myZLayers.RemoveLayer (theLayerId);
538}
2166f0fa 539
c357e426 540//=======================================================================
541//function : SetZLayerSettings
542//purpose :
543//=======================================================================
544void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
545 const Graphic3d_ZLayerSettings& theSettings)
2166f0fa 546{
c357e426 547 myZLayers.SetLayerSettings (theLayerId, theSettings);
2166f0fa
SK
548}
549
c357e426 550//=======================================================================
50d06d8f 551//function : ZLayerMax
552//purpose :
553//=======================================================================
554Standard_Integer OpenGl_View::ZLayerMax() const
555{
556 Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default;
557 for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next())
558 {
559 aLayerMax = Max (aLayerMax, aMapIt.Value());
560 }
561
562 return aLayerMax;
563}
564
565//=======================================================================
566//function : InvalidateZLayerBoundingBox
567//purpose :
568//=======================================================================
569void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const
570{
571 if (myZLayers.LayerIDs().IsBound (theLayerId))
572 {
573 myZLayers.Layer (theLayerId).InvalidateBoundingBox();
574 }
575 else
576 {
1475265b 577 const Standard_Integer aLayerMax = ZLayerMax();
578 for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < aLayerMax; ++aLayerId)
50d06d8f 579 {
580 if (myZLayers.LayerIDs().IsBound (aLayerId))
581 {
582 const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId);
583 if (aLayer.NbOfTransformPersistenceObjects() > 0)
584 {
585 aLayer.InvalidateBoundingBox();
586 }
587 }
588 }
589 }
590}
591
592//=======================================================================
593//function : ZLayerBoundingBox
594//purpose :
595//=======================================================================
7c3ef2f7 596Bnd_Box OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
597 const Handle(Graphic3d_Camera)& theCamera,
598 const Standard_Integer theWindowWidth,
599 const Standard_Integer theWindowHeight,
600 const Standard_Boolean theToIncludeAuxiliary) const
50d06d8f 601{
7c3ef2f7 602 Bnd_Box aBox;
50d06d8f 603 if (myZLayers.LayerIDs().IsBound (theLayerId))
604 {
71d8ccc7 605 aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(),
50d06d8f 606 theCamera,
607 theWindowWidth,
608 theWindowHeight,
3fe9ce0e 609 theToIncludeAuxiliary);
50d06d8f 610 }
611
71d8ccc7 612 // add bounding box of gradient/texture background for proper Z-fit
613 if (theToIncludeAuxiliary
614 && theLayerId == Graphic3d_ZLayerId_BotOSD
615 && (myBgTextureArray->IsDefined()
616 || myBgGradientArray->IsDefined()))
617 {
618 // Background is drawn using 2D transformation persistence
619 // (e.g. it is actually placed in 3D coordinates within active camera position).
620 // We add here full-screen plane with 2D transformation persistence
621 // for simplicity (myBgTextureArray might define a little bit different options
622 // but it is updated within ::Render())
7c3ef2f7 623 const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
624 const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix();
625 Graphic3d_BndBox3d aBox2d (Graphic3d_Vec3d (0.0, 0.0, 0.0),
626 Graphic3d_Vec3d (double(theWindowWidth), double(theWindowHeight), 0.0));
71d8ccc7 627
778cd667 628 Graphic3d_TransformPers aTrsfPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER);
71d8ccc7 629 aTrsfPers.Apply (theCamera,
630 aProjectionMat,
631 aWorldViewMat,
632 theWindowWidth,
633 theWindowHeight,
634 aBox2d);
7c3ef2f7 635 aBox.Add (gp_Pnt (aBox2d.CornerMin().x(), aBox2d.CornerMin().y(), aBox2d.CornerMin().z()));
636 aBox.Add (gp_Pnt (aBox2d.CornerMax().x(), aBox2d.CornerMax().y(), aBox2d.CornerMax().z()));
71d8ccc7 637 }
638
639 return aBox;
50d06d8f 640}
641
642//=======================================================================
643//function : considerZoomPersistenceObjects
644//purpose :
645//=======================================================================
646Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId theLayerId,
647 const Handle(Graphic3d_Camera)& theCamera,
648 const Standard_Integer theWindowWidth,
3fe9ce0e 649 const Standard_Integer theWindowHeight) const
50d06d8f 650{
1d92133e 651 if (myZLayers.LayerIDs().IsBound (theLayerId))
50d06d8f 652 {
653 return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(),
654 theCamera,
655 theWindowWidth,
3fe9ce0e 656 theWindowHeight);
50d06d8f 657 }
658
659 return 1.0;
660}
661
662//=======================================================================
c357e426 663//function : FBO
664//purpose :
665//=======================================================================
b128c892 666Handle(Standard_Transient) OpenGl_View::FBO() const
c357e426 667{
b128c892 668 return Handle(Standard_Transient)(myFBO);
c357e426 669}
2166f0fa 670
c357e426 671//=======================================================================
672//function : SetFBO
673//purpose :
674//=======================================================================
b128c892 675void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo)
2166f0fa 676{
b128c892 677 myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
2166f0fa
SK
678}
679
c357e426 680//=======================================================================
681//function : FBOCreate
682//purpose :
683//=======================================================================
b128c892 684Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth,
685 const Standard_Integer theHeight)
c357e426 686{
687 return myWorkspace->FBOCreate (theWidth, theHeight);
688}
2166f0fa 689
c357e426 690//=======================================================================
691//function : FBORelease
692//purpose :
693//=======================================================================
b128c892 694void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo)
2166f0fa 695{
b128c892 696 Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
697 if (aFrameBuffer.IsNull())
698 {
699 return;
700 }
701
702 myWorkspace->FBORelease (aFrameBuffer);
703 theFbo.Nullify();
c357e426 704}
705
706//=======================================================================
707//function : FBOGetDimensions
708//purpose :
709//=======================================================================
b128c892 710void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo,
c357e426 711 Standard_Integer& theWidth,
712 Standard_Integer& theHeight,
713 Standard_Integer& theWidthMax,
714 Standard_Integer& theHeightMax)
715{
b128c892 716 const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
717 if (aFrameBuffer.IsNull())
718 {
719 return;
720 }
721
c357e426 722 theWidth = aFrameBuffer->GetVPSizeX(); // current viewport size
723 theHeight = aFrameBuffer->GetVPSizeY();
724 theWidthMax = aFrameBuffer->GetSizeX(); // texture size
725 theHeightMax = aFrameBuffer->GetSizeY();
726}
727
728//=======================================================================
729//function : FBOChangeViewport
730//purpose :
731//=======================================================================
b128c892 732void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo,
c357e426 733 const Standard_Integer theWidth,
734 const Standard_Integer theHeight)
735{
b128c892 736 const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
737 if (aFrameBuffer.IsNull())
738 {
739 return;
740 }
741
c357e426 742 aFrameBuffer->ChangeViewport (theWidth, theHeight);
743}
744
745// =======================================================================
746// function : Export
747// purpose :
748// =======================================================================
749#ifdef HAVE_GL2PS
750Standard_Boolean OpenGl_View::Export (const Standard_CString theFileName,
751 const Graphic3d_ExportFormat theFormat,
752 const Graphic3d_SortType theSortType)
753{
754 // gl2psBeginPage() will call OpenGL functions
755 // so we should activate correct GL context before redraw scene call
756 if (!myWorkspace->Activate())
757 {
758 return Standard_False;
759 }
760
761 Standard_Integer aFormat = -1;
762 Standard_Integer aSortType = Graphic3d_ST_BSP_Tree;
763 switch (theFormat)
764 {
765 case Graphic3d_EF_PostScript:
766 aFormat = GL2PS_PS;
767 break;
768 case Graphic3d_EF_EnhPostScript:
769 aFormat = GL2PS_EPS;
770 break;
771 case Graphic3d_EF_TEX:
772 aFormat = GL2PS_TEX;
773 break;
774 case Graphic3d_EF_PDF:
775 aFormat = GL2PS_PDF;
776 break;
777 case Graphic3d_EF_SVG:
778 aFormat = GL2PS_SVG;
779 break;
780 case Graphic3d_EF_PGF:
781 aFormat = GL2PS_PGF;
782 break;
783 case Graphic3d_EF_EMF:
784 //aFormat = GL2PS_EMF;
785 aFormat = GL2PS_PGF + 1; // 6
786 break;
787 default:
788 // unsupported format
789 return Standard_False;
790 }
791
792 switch (theSortType)
793 {
794 case Graphic3d_ST_Simple:
795 aSortType = GL2PS_SIMPLE_SORT;
796 break;
797 case Graphic3d_ST_BSP_Tree:
798 aSortType = GL2PS_BSP_SORT;
799 break;
800 }
801
802 GLint aViewport[4];
803 aViewport[0] = 0;
804 aViewport[1] = 0;
805 aViewport[2] = myWindow->Width();
806 aViewport[3] = myWindow->Height();
807
808 GLint aBufferSize = 1024 * 1024;
809 GLint anErrCode = GL2PS_SUCCESS;
810
811 // gl2ps uses standard write functions and do not check locale
812 Standard_CLocaleSentry aLocaleSentry;
813
814 while (aBufferSize > 0)
815 {
816 // current patch for EMF support in gl2ps uses WinAPI functions to create file
817 FILE* aFileH = (theFormat != Graphic3d_EF_EMF) ? fopen (theFileName, "wb") : NULL;
818 anErrCode = gl2psBeginPage ("", "", aViewport, aFormat, aSortType,
819 GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT/* | GL2PS_SIMPLE_LINE_OFFSET*/,
820 GL_RGBA, 0, NULL,
821 0, 0, 0, aBufferSize, aFileH, theFileName);
822 if (anErrCode != GL2PS_SUCCESS)
823 {
824 // initialization failed
825 if (aFileH != NULL)
826 fclose (aFileH);
827 break;
828 }
829 Redraw();
830
831 anErrCode = gl2psEndPage();
832 if (aFileH != NULL)
833 fclose (aFileH);
834
835 if (anErrCode == GL2PS_OVERFLOW)
836 aBufferSize *= 2;
837 else
838 break;
839 }
840 return anErrCode == GL2PS_SUCCESS;
841}
842#else
843Standard_Boolean OpenGl_View::Export (const Standard_CString /*theFileName*/,
844 const Graphic3d_ExportFormat /*theFormat*/,
845 const Graphic3d_SortType /*theSortType*/)
846{
847 return Standard_False;
848}
849#endif
850
851//=======================================================================
852//function : displayStructure
853//purpose :
854//=======================================================================
855void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure,
856 const Standard_Integer thePriority)
857{
858 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
859 const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
860 myZLayers.AddStructure (aStruct, aZLayer, thePriority);
861}
862
863//=======================================================================
864//function : eraseStructure
865//purpose :
866//=======================================================================
867void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure)
868{
869 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
870 myZLayers.RemoveStructure (aStruct);
871}
872
873//=======================================================================
874//function : changeZLayer
875//purpose :
876//=======================================================================
877void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure,
878 const Graphic3d_ZLayerId theNewLayerId)
879{
880 const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
881 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
882 myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
cfece3ef 883 Update (anOldLayer);
884 Update (theNewLayerId);
c357e426 885}
886
887//=======================================================================
888//function : changePriority
889//purpose :
890//=======================================================================
891void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure,
892 const Standard_Integer theNewPriority)
893{
894 const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
895 const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
896 myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority);
2166f0fa 897}
26d9c835 898
899//=======================================================================
900//function : DiagnosticInformation
901//purpose :
902//=======================================================================
903void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
904 Graphic3d_DiagnosticInfo theFlags) const
905{
906 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
907 if (!myWorkspace->Activate()
908 || aCtx.IsNull())
909 {
910 return;
911 }
912
913 aCtx->DiagnosticInformation (theDict, theFlags);
914 if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
915 {
916 TCollection_AsciiString aResRatio (myRenderParams.ResolutionRatio());
917 theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio;
918 }
919}