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