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