| 1 | // Created on: 2011-09-20 |
| 2 | // Created by: Sergey ZERCHANINOV |
| 3 | // Copyright (c) 2011-2014 OPEN CASCADE SAS |
| 4 | // |
| 5 | // This file is part of Open CASCADE Technology software library. |
| 6 | // |
| 7 | // This library is free software; you can redistribute it and/or modify it under |
| 8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
| 9 | // by the Free Software Foundation, with special exception defined in the file |
| 10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
| 11 | // distribution for complete text of the license and disclaimer of any warranty. |
| 12 | // |
| 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
| 14 | // commercial license or contractual agreement. |
| 15 | |
| 16 | #include <OpenGl_View.hxx> |
| 17 | |
| 18 | #include <Aspect_RenderingContext.hxx> |
| 19 | #include <Aspect_Window.hxx> |
| 20 | #include <Graphic3d_AspectFillArea3d.hxx> |
| 21 | #include <Graphic3d_Texture2Dmanual.hxx> |
| 22 | #include <Graphic3d_TextureEnv.hxx> |
| 23 | #include <Graphic3d_Mat4d.hxx> |
| 24 | #include <NCollection_Mat4.hxx> |
| 25 | #include <OpenGl_Context.hxx> |
| 26 | #include <OpenGl_FrameBuffer.hxx> |
| 27 | #include <OpenGl_GlCore11.hxx> |
| 28 | #include <OpenGl_GraduatedTrihedron.hxx> |
| 29 | #include <OpenGl_GraphicDriver.hxx> |
| 30 | #include <OpenGl_ShaderManager.hxx> |
| 31 | #include <OpenGl_Texture.hxx> |
| 32 | #include <OpenGl_Trihedron.hxx> |
| 33 | #include <OpenGl_Window.hxx> |
| 34 | #include <OpenGl_Workspace.hxx> |
| 35 | #include <Standard_CLocaleSentry.hxx> |
| 36 | |
| 37 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,Graphic3d_CView) |
| 38 | |
| 39 | #ifdef HAVE_GL2PS |
| 40 | #include <gl2ps.h> |
| 41 | #endif |
| 42 | |
| 43 | // ======================================================================= |
| 44 | // function : Constructor |
| 45 | // purpose : |
| 46 | // ======================================================================= |
| 47 | OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr, |
| 48 | const Handle(OpenGl_GraphicDriver)& theDriver, |
| 49 | const Handle(OpenGl_Caps)& theCaps, |
| 50 | Standard_Boolean& theDeviceLostFlag, |
| 51 | OpenGl_StateCounter* theCounter) |
| 52 | : Graphic3d_CView (theMgr), |
| 53 | myDriver (theDriver.operator->()), |
| 54 | myCaps (theCaps), |
| 55 | myDeviceLostFlag (theDeviceLostFlag), |
| 56 | myWasRedrawnGL (Standard_False), |
| 57 | myCulling (Standard_True), |
| 58 | myShadingModel (Graphic3d_TOSM_FACET), |
| 59 | myBackfacing (Graphic3d_TOBM_AUTOMATIC), |
| 60 | myBgColor (Quantity_NOC_BLACK), |
| 61 | myCamera (new Graphic3d_Camera()), |
| 62 | myUseGLLight (Standard_True), |
| 63 | myToShowTrihedron (false), |
| 64 | myToShowGradTrihedron (false), |
| 65 | myStateCounter (theCounter), |
| 66 | myLastLightSourceState (0, 0), |
| 67 | myFboColorFormat (GL_RGBA8), |
| 68 | myFboDepthFormat (GL_DEPTH24_STENCIL8), |
| 69 | myToFlipOutput (Standard_False), |
| 70 | myFrameCounter (0), |
| 71 | myHasFboBlit (Standard_True), |
| 72 | myToDisableMSAA (Standard_False), |
| 73 | myTransientDrawToFront (Standard_True), |
| 74 | myBackBufferRestored (Standard_False), |
| 75 | myIsImmediateDrawn (Standard_False), |
| 76 | myTextureParams (new OpenGl_AspectFace()), |
| 77 | myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)), |
| 78 | myBgTextureArray (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)), |
| 79 | // ray-tracing fields initialization |
| 80 | myRaytraceInitStatus (OpenGl_RT_NONE), |
| 81 | myIsRaytraceDataValid (Standard_False), |
| 82 | myIsRaytraceWarnTextures (Standard_False), |
| 83 | myToUpdateEnvironmentMap (Standard_False), |
| 84 | myLayerListState (0) |
| 85 | { |
| 86 | myWorkspace = new OpenGl_Workspace (this, NULL); |
| 87 | |
| 88 | OpenGl_Light aLight; |
| 89 | aLight.Type = Graphic3d_TOLS_AMBIENT; |
| 90 | aLight.IsHeadlight = Standard_False; |
| 91 | aLight.Color.r() = 1.; |
| 92 | aLight.Color.g() = 1.; |
| 93 | aLight.Color.b() = 1.; |
| 94 | myNoShadingLight.Append (aLight); |
| 95 | |
| 96 | myCurrLightSourceState = myStateCounter->Increment(); |
| 97 | myMainSceneFbos[0] = new OpenGl_FrameBuffer(); |
| 98 | myMainSceneFbos[1] = new OpenGl_FrameBuffer(); |
| 99 | myImmediateSceneFbos[0] = new OpenGl_FrameBuffer(); |
| 100 | myImmediateSceneFbos[1] = new OpenGl_FrameBuffer(); |
| 101 | myOpenGlFBO = new OpenGl_FrameBuffer(); |
| 102 | myOpenGlFBO2 = new OpenGl_FrameBuffer(); |
| 103 | myRaytraceFBO1[0] = new OpenGl_FrameBuffer(); |
| 104 | myRaytraceFBO1[1] = new OpenGl_FrameBuffer(); |
| 105 | myRaytraceFBO2[0] = new OpenGl_FrameBuffer(); |
| 106 | myRaytraceFBO2[1] = new OpenGl_FrameBuffer(); |
| 107 | } |
| 108 | |
| 109 | // ======================================================================= |
| 110 | // function : Destructor |
| 111 | // purpose : |
| 112 | // ======================================================================= |
| 113 | OpenGl_View::~OpenGl_View() |
| 114 | { |
| 115 | ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context |
| 116 | OpenGl_Element::Destroy (NULL, myBgGradientArray); |
| 117 | OpenGl_Element::Destroy (NULL, myBgTextureArray); |
| 118 | OpenGl_Element::Destroy (NULL, myTextureParams); |
| 119 | } |
| 120 | |
| 121 | // ======================================================================= |
| 122 | // function : ReleaseGlResources |
| 123 | // purpose : |
| 124 | // ======================================================================= |
| 125 | void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx) |
| 126 | { |
| 127 | myTrihedron .Release (theCtx.operator->()); |
| 128 | myGraduatedTrihedron.Release (theCtx.operator->()); |
| 129 | |
| 130 | if (!myTextureEnv.IsNull()) |
| 131 | { |
| 132 | theCtx->DelayedRelease (myTextureEnv); |
| 133 | myTextureEnv.Nullify(); |
| 134 | } |
| 135 | |
| 136 | if (myTextureParams != NULL) |
| 137 | { |
| 138 | myTextureParams->Release (theCtx.operator->()); |
| 139 | } |
| 140 | if (myBgGradientArray != NULL) |
| 141 | { |
| 142 | myBgGradientArray->Release (theCtx.operator->()); |
| 143 | } |
| 144 | if (myBgTextureArray != NULL) |
| 145 | { |
| 146 | myBgTextureArray->Release (theCtx.operator->()); |
| 147 | } |
| 148 | |
| 149 | myMainSceneFbos[0] ->Release (theCtx.operator->()); |
| 150 | myMainSceneFbos[1] ->Release (theCtx.operator->()); |
| 151 | myImmediateSceneFbos[0]->Release (theCtx.operator->()); |
| 152 | myImmediateSceneFbos[1]->Release (theCtx.operator->()); |
| 153 | myOpenGlFBO ->Release (theCtx.operator->()); |
| 154 | myOpenGlFBO2 ->Release (theCtx.operator->()); |
| 155 | myFullScreenQuad .Release (theCtx.operator->()); |
| 156 | myFullScreenQuadFlip .Release (theCtx.operator->()); |
| 157 | |
| 158 | releaseRaytraceResources (theCtx); |
| 159 | } |
| 160 | |
| 161 | // ======================================================================= |
| 162 | // function : Remove |
| 163 | // purpose : |
| 164 | // ======================================================================= |
| 165 | void OpenGl_View::Remove() |
| 166 | { |
| 167 | if (IsRemoved()) |
| 168 | { |
| 169 | return; |
| 170 | } |
| 171 | |
| 172 | myDriver->RemoveView (this); |
| 173 | myWindow.Nullify(); |
| 174 | |
| 175 | Graphic3d_CView::Remove(); |
| 176 | } |
| 177 | |
| 178 | // ======================================================================= |
| 179 | // function : SetTextureEnv |
| 180 | // purpose : |
| 181 | // ======================================================================= |
| 182 | void OpenGl_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv) |
| 183 | { |
| 184 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); |
| 185 | if (!aCtx.IsNull() && !myTextureEnv.IsNull()) |
| 186 | { |
| 187 | aCtx->DelayedRelease (myTextureEnv); |
| 188 | } |
| 189 | |
| 190 | myToUpdateEnvironmentMap = Standard_True; |
| 191 | myTextureEnvData = theTextureEnv; |
| 192 | myTextureEnv.Nullify(); |
| 193 | initTextureEnv (aCtx); |
| 194 | } |
| 195 | |
| 196 | // ======================================================================= |
| 197 | // function : initTextureEnv |
| 198 | // purpose : |
| 199 | // ======================================================================= |
| 200 | void OpenGl_View::initTextureEnv (const Handle(OpenGl_Context)& theContext) |
| 201 | { |
| 202 | if (myTextureEnvData.IsNull() |
| 203 | || theContext.IsNull() |
| 204 | || !theContext->MakeCurrent()) |
| 205 | { |
| 206 | return; |
| 207 | } |
| 208 | |
| 209 | myTextureEnv = new OpenGl_Texture (myTextureEnvData->GetParams()); |
| 210 | Handle(Image_PixMap) anImage = myTextureEnvData->GetImage(); |
| 211 | if (!anImage.IsNull()) |
| 212 | { |
| 213 | myTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type()); |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | // ======================================================================= |
| 218 | // function : SetImmediateModeDrawToFront |
| 219 | // purpose : |
| 220 | // ======================================================================= |
| 221 | Standard_Boolean OpenGl_View::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer) |
| 222 | { |
| 223 | const Standard_Boolean aPrevMode = myTransientDrawToFront; |
| 224 | myTransientDrawToFront = theDrawToFrontBuffer; |
| 225 | return aPrevMode; |
| 226 | } |
| 227 | |
| 228 | // ======================================================================= |
| 229 | // function : SetWindow |
| 230 | // purpose : |
| 231 | // ======================================================================= |
| 232 | void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow, |
| 233 | const Aspect_RenderingContext theContext) |
| 234 | { |
| 235 | myWindow = myDriver->CreateRenderWindow (theWindow, theContext); |
| 236 | Standard_ASSERT_RAISE (!myWindow.IsNull(), |
| 237 | "OpenGl_View::SetWindow, " |
| 238 | "Failed to create OpenGl window."); |
| 239 | |
| 240 | myWorkspace = new OpenGl_Workspace (this, myWindow); |
| 241 | myWorldViewProjState.Reset(); |
| 242 | myToUpdateEnvironmentMap = Standard_True; |
| 243 | myHasFboBlit = Standard_True; |
| 244 | Invalidate(); |
| 245 | |
| 246 | // Environment texture resource does not support lazy initialization. |
| 247 | initTextureEnv (myWorkspace->GetGlContext()); |
| 248 | } |
| 249 | |
| 250 | // ======================================================================= |
| 251 | // function : Resized |
| 252 | // purpose : |
| 253 | // ======================================================================= |
| 254 | void OpenGl_View::Resized() |
| 255 | { |
| 256 | if (myWindow.IsNull()) |
| 257 | return; |
| 258 | |
| 259 | myWindow->Resize(); |
| 260 | } |
| 261 | |
| 262 | // ======================================================================= |
| 263 | // function : TriedronDisplay |
| 264 | // purpose : |
| 265 | // ======================================================================= |
| 266 | void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition, |
| 267 | const Quantity_NameOfColor theColor, |
| 268 | const Standard_Real theScale, |
| 269 | const Standard_Boolean theAsWireframe) |
| 270 | { |
| 271 | myToShowTrihedron = true; |
| 272 | myTrihedron.SetWireframe (theAsWireframe); |
| 273 | myTrihedron.SetPosition (thePosition); |
| 274 | myTrihedron.SetScale (theScale); |
| 275 | myTrihedron.SetLabelsColor (theColor); |
| 276 | } |
| 277 | |
| 278 | // ======================================================================= |
| 279 | // function : TriedronErase |
| 280 | // purpose : |
| 281 | // ======================================================================= |
| 282 | void OpenGl_View::TriedronErase() |
| 283 | { |
| 284 | myToShowTrihedron = false; |
| 285 | myTrihedron.Release (myWorkspace->GetGlContext().operator->()); |
| 286 | } |
| 287 | |
| 288 | // ======================================================================= |
| 289 | // function : ZBufferTriedronSetup |
| 290 | // purpose : |
| 291 | // ======================================================================= |
| 292 | void OpenGl_View::ZBufferTriedronSetup (const Quantity_NameOfColor theXColor, |
| 293 | const Quantity_NameOfColor theYColor, |
| 294 | const Quantity_NameOfColor theZColor, |
| 295 | const Standard_Real theSizeRatio, |
| 296 | const Standard_Real theAxisDiametr, |
| 297 | const Standard_Integer theNbFacettes) |
| 298 | { |
| 299 | myTrihedron.SetArrowsColors (theXColor, theYColor, theZColor); |
| 300 | myTrihedron.SetSizeRatio (theSizeRatio); |
| 301 | myTrihedron.SetNbFacets (theNbFacettes); |
| 302 | myTrihedron.SetArrowDiameter (theAxisDiametr); |
| 303 | } |
| 304 | |
| 305 | // ======================================================================= |
| 306 | // function : TriedronEcho |
| 307 | // purpose : |
| 308 | // ======================================================================= |
| 309 | void OpenGl_View::TriedronEcho (const Aspect_TypeOfTriedronEcho /*theType*/) |
| 310 | { |
| 311 | // do nothing |
| 312 | } |
| 313 | |
| 314 | // ======================================================================= |
| 315 | // function : SetMinMaxValuesCallback |
| 316 | // purpose : |
| 317 | // ======================================================================= |
| 318 | static void SetMinMaxValuesCallback (Graphic3d_CView* theView) |
| 319 | { |
| 320 | OpenGl_View* aView = dynamic_cast<OpenGl_View*>(theView); |
| 321 | if (aView == NULL) |
| 322 | return; |
| 323 | |
| 324 | Bnd_Box aBox = theView->MinMaxValues(); |
| 325 | if (!aBox.IsVoid()) |
| 326 | { |
| 327 | gp_Pnt aMin = aBox.CornerMin(); |
| 328 | gp_Pnt aMax = aBox.CornerMax(); |
| 329 | |
| 330 | Graphic3d_Vec3 aMinVec ((Standard_ShortReal )aMin.X(), (Standard_ShortReal )aMin.Y(), (Standard_ShortReal )aMin.Z()); |
| 331 | Graphic3d_Vec3 aMaxVec ((Standard_ShortReal )aMax.X(), (Standard_ShortReal )aMax.Y(), (Standard_ShortReal )aMax.Z()); |
| 332 | aView->GraduatedTrihedronMinMaxValues (aMinVec, aMaxVec); |
| 333 | } |
| 334 | } |
| 335 | |
| 336 | // ======================================================================= |
| 337 | // function : GraduatedTrihedronDisplay |
| 338 | // purpose : |
| 339 | // ======================================================================= |
| 340 | void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData) |
| 341 | { |
| 342 | myGTrihedronData = theTrihedronData; |
| 343 | myGTrihedronData.PtrView = this; |
| 344 | myGTrihedronData.CubicAxesCallback = SetMinMaxValuesCallback; |
| 345 | myGraduatedTrihedron.SetValues (myGTrihedronData); |
| 346 | myToShowGradTrihedron = true; |
| 347 | } |
| 348 | |
| 349 | // ======================================================================= |
| 350 | // function : GraduatedTrihedronErase |
| 351 | // purpose : |
| 352 | // ======================================================================= |
| 353 | void OpenGl_View::GraduatedTrihedronErase() |
| 354 | { |
| 355 | myGTrihedronData.PtrView = NULL; |
| 356 | myGraduatedTrihedron.Release (myWorkspace->GetGlContext().operator->()); |
| 357 | myToShowGradTrihedron = false; |
| 358 | } |
| 359 | |
| 360 | // ======================================================================= |
| 361 | // function : GraduatedTrihedronMinMaxValues |
| 362 | // purpose : |
| 363 | // ======================================================================= |
| 364 | void OpenGl_View::GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax) |
| 365 | { |
| 366 | myGraduatedTrihedron.SetMinMax (theMin, theMax); |
| 367 | } |
| 368 | |
| 369 | // ======================================================================= |
| 370 | // function : BufferDump |
| 371 | // purpose : |
| 372 | // ======================================================================= |
| 373 | Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType) |
| 374 | { |
| 375 | return myWorkspace->BufferDump (myFBO, theImage, theBufferType); |
| 376 | } |
| 377 | |
| 378 | // ======================================================================= |
| 379 | // function : Background |
| 380 | // purpose : |
| 381 | // ======================================================================= |
| 382 | Aspect_Background OpenGl_View::Background() const |
| 383 | { |
| 384 | return Aspect_Background (myBgColor.GetRGB()); |
| 385 | } |
| 386 | |
| 387 | // ======================================================================= |
| 388 | // function : SetBackground |
| 389 | // purpose : |
| 390 | // ======================================================================= |
| 391 | void OpenGl_View::SetBackground (const Aspect_Background& theBackground) |
| 392 | { |
| 393 | myBgColor.SetRGB (theBackground.Color()); |
| 394 | } |
| 395 | |
| 396 | // ======================================================================= |
| 397 | // function : GradientBackground |
| 398 | // purpose : |
| 399 | // ======================================================================= |
| 400 | Aspect_GradientBackground OpenGl_View::GradientBackground() const |
| 401 | { |
| 402 | Quantity_Color aColor1, aColor2; |
| 403 | aColor1.SetValues (myBgGradientArray->GradientColor (0).r(), |
| 404 | myBgGradientArray->GradientColor (0).g(), |
| 405 | myBgGradientArray->GradientColor (0).b(), Quantity_TOC_RGB); |
| 406 | aColor2.SetValues (myBgGradientArray->GradientColor (1).r(), |
| 407 | myBgGradientArray->GradientColor (1).g(), |
| 408 | myBgGradientArray->GradientColor (1).b(), Quantity_TOC_RGB); |
| 409 | return Aspect_GradientBackground (aColor1, aColor2, myBgGradientArray->GradientFillMethod()); |
| 410 | } |
| 411 | |
| 412 | // ======================================================================= |
| 413 | // function : SetGradientBackground |
| 414 | // purpose : |
| 415 | // ======================================================================= |
| 416 | void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground) |
| 417 | { |
| 418 | Quantity_Color aColor1, aColor2; |
| 419 | theBackground.Colors (aColor1, aColor2); |
| 420 | myBgGradientArray->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod()); |
| 421 | } |
| 422 | |
| 423 | // ======================================================================= |
| 424 | // function : SetBackgroundImage |
| 425 | // purpose : |
| 426 | // ======================================================================= |
| 427 | void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath) |
| 428 | { |
| 429 | // Prepare aspect for texture storage |
| 430 | myBackgroundImagePath = theFilePath; |
| 431 | Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); |
| 432 | Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath)); |
| 433 | aTextureMap->EnableRepeat(); |
| 434 | aTextureMap->DisableModulate(); |
| 435 | aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL, |
| 436 | Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f), |
| 437 | Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f)); |
| 438 | anAspect->SetTextureMap (aTextureMap); |
| 439 | anAspect->SetInteriorStyle (Aspect_IS_SOLID); |
| 440 | anAspect->SetSuppressBackFaces (false); |
| 441 | // Enable texture mapping |
| 442 | if (aTextureMap->IsDone()) |
| 443 | { |
| 444 | anAspect->SetTextureMapOn(); |
| 445 | } |
| 446 | else |
| 447 | { |
| 448 | anAspect->SetTextureMapOff(); |
| 449 | return; |
| 450 | } |
| 451 | |
| 452 | // Set texture parameters |
| 453 | myTextureParams->SetAspect (anAspect); |
| 454 | } |
| 455 | |
| 456 | // ======================================================================= |
| 457 | // function : BackgroundImageStyle |
| 458 | // purpose : |
| 459 | // ======================================================================= |
| 460 | Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const |
| 461 | { |
| 462 | return myBgTextureArray->TextureFillMethod(); |
| 463 | } |
| 464 | |
| 465 | // ======================================================================= |
| 466 | // function : SetBackgroundImageStyle |
| 467 | // purpose : |
| 468 | // ======================================================================= |
| 469 | void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle) |
| 470 | { |
| 471 | myBgTextureArray->SetTextureFillMethod (theFillStyle); |
| 472 | } |
| 473 | |
| 474 | //======================================================================= |
| 475 | //function : AddZLayer |
| 476 | //purpose : |
| 477 | //======================================================================= |
| 478 | void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId) |
| 479 | { |
| 480 | myZLayers.AddLayer (theLayerId); |
| 481 | } |
| 482 | |
| 483 | //======================================================================= |
| 484 | //function : RemoveZLayer |
| 485 | //purpose : |
| 486 | //======================================================================= |
| 487 | void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId) |
| 488 | { |
| 489 | myZLayers.RemoveLayer (theLayerId); |
| 490 | } |
| 491 | |
| 492 | //======================================================================= |
| 493 | //function : SetZLayerSettings |
| 494 | //purpose : |
| 495 | //======================================================================= |
| 496 | void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, |
| 497 | const Graphic3d_ZLayerSettings& theSettings) |
| 498 | { |
| 499 | myZLayers.SetLayerSettings (theLayerId, theSettings); |
| 500 | } |
| 501 | |
| 502 | //======================================================================= |
| 503 | //function : ZLayerMax |
| 504 | //purpose : |
| 505 | //======================================================================= |
| 506 | Standard_Integer OpenGl_View::ZLayerMax() const |
| 507 | { |
| 508 | Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default; |
| 509 | for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next()) |
| 510 | { |
| 511 | aLayerMax = Max (aLayerMax, aMapIt.Value()); |
| 512 | } |
| 513 | |
| 514 | return aLayerMax; |
| 515 | } |
| 516 | |
| 517 | //======================================================================= |
| 518 | //function : InvalidateZLayerBoundingBox |
| 519 | //purpose : |
| 520 | //======================================================================= |
| 521 | void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const |
| 522 | { |
| 523 | if (myZLayers.LayerIDs().IsBound (theLayerId)) |
| 524 | { |
| 525 | myZLayers.Layer (theLayerId).InvalidateBoundingBox(); |
| 526 | } |
| 527 | else |
| 528 | { |
| 529 | for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < ZLayerMax(); ++aLayerId) |
| 530 | { |
| 531 | if (myZLayers.LayerIDs().IsBound (aLayerId)) |
| 532 | { |
| 533 | const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId); |
| 534 | if (aLayer.NbOfTransformPersistenceObjects() > 0) |
| 535 | { |
| 536 | aLayer.InvalidateBoundingBox(); |
| 537 | } |
| 538 | } |
| 539 | } |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | //======================================================================= |
| 544 | //function : ZLayerBoundingBox |
| 545 | //purpose : |
| 546 | //======================================================================= |
| 547 | Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId, |
| 548 | const Handle(Graphic3d_Camera)& theCamera, |
| 549 | const Standard_Integer theWindowWidth, |
| 550 | const Standard_Integer theWindowHeight, |
| 551 | const Standard_Boolean theToIgnoreInfiniteFlag) const |
| 552 | { |
| 553 | if (myZLayers.LayerIDs().IsBound (theLayerId)) |
| 554 | { |
| 555 | return myZLayers.Layer (theLayerId).BoundingBox (Identification(), |
| 556 | theCamera, |
| 557 | theWindowWidth, |
| 558 | theWindowHeight, |
| 559 | theToIgnoreInfiniteFlag); |
| 560 | } |
| 561 | |
| 562 | return Graphic3d_BndBox4f(); |
| 563 | } |
| 564 | |
| 565 | //======================================================================= |
| 566 | //function : considerZoomPersistenceObjects |
| 567 | //purpose : |
| 568 | //======================================================================= |
| 569 | Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId theLayerId, |
| 570 | const Handle(Graphic3d_Camera)& theCamera, |
| 571 | const Standard_Integer theWindowWidth, |
| 572 | const Standard_Integer theWindowHeight, |
| 573 | const Standard_Boolean theToIgnoreInfiniteFlag) const |
| 574 | { |
| 575 | if (myZLayers.LayerIDs().IsBound (theLayerId)) |
| 576 | { |
| 577 | return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(), |
| 578 | theCamera, |
| 579 | theWindowWidth, |
| 580 | theWindowHeight, |
| 581 | theToIgnoreInfiniteFlag); |
| 582 | } |
| 583 | |
| 584 | return 1.0; |
| 585 | } |
| 586 | |
| 587 | //======================================================================= |
| 588 | //function : FBO |
| 589 | //purpose : |
| 590 | //======================================================================= |
| 591 | Handle(Standard_Transient) OpenGl_View::FBO() const |
| 592 | { |
| 593 | return Handle(Standard_Transient)(myFBO); |
| 594 | } |
| 595 | |
| 596 | //======================================================================= |
| 597 | //function : SetFBO |
| 598 | //purpose : |
| 599 | //======================================================================= |
| 600 | void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo) |
| 601 | { |
| 602 | myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
| 603 | } |
| 604 | |
| 605 | //======================================================================= |
| 606 | //function : FBOCreate |
| 607 | //purpose : |
| 608 | //======================================================================= |
| 609 | Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth, |
| 610 | const Standard_Integer theHeight) |
| 611 | { |
| 612 | return myWorkspace->FBOCreate (theWidth, theHeight); |
| 613 | } |
| 614 | |
| 615 | //======================================================================= |
| 616 | //function : FBORelease |
| 617 | //purpose : |
| 618 | //======================================================================= |
| 619 | void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo) |
| 620 | { |
| 621 | Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
| 622 | if (aFrameBuffer.IsNull()) |
| 623 | { |
| 624 | return; |
| 625 | } |
| 626 | |
| 627 | myWorkspace->FBORelease (aFrameBuffer); |
| 628 | theFbo.Nullify(); |
| 629 | } |
| 630 | |
| 631 | //======================================================================= |
| 632 | //function : FBOGetDimensions |
| 633 | //purpose : |
| 634 | //======================================================================= |
| 635 | void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo, |
| 636 | Standard_Integer& theWidth, |
| 637 | Standard_Integer& theHeight, |
| 638 | Standard_Integer& theWidthMax, |
| 639 | Standard_Integer& theHeightMax) |
| 640 | { |
| 641 | const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
| 642 | if (aFrameBuffer.IsNull()) |
| 643 | { |
| 644 | return; |
| 645 | } |
| 646 | |
| 647 | theWidth = aFrameBuffer->GetVPSizeX(); // current viewport size |
| 648 | theHeight = aFrameBuffer->GetVPSizeY(); |
| 649 | theWidthMax = aFrameBuffer->GetSizeX(); // texture size |
| 650 | theHeightMax = aFrameBuffer->GetSizeY(); |
| 651 | } |
| 652 | |
| 653 | //======================================================================= |
| 654 | //function : FBOChangeViewport |
| 655 | //purpose : |
| 656 | //======================================================================= |
| 657 | void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo, |
| 658 | const Standard_Integer theWidth, |
| 659 | const Standard_Integer theHeight) |
| 660 | { |
| 661 | const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
| 662 | if (aFrameBuffer.IsNull()) |
| 663 | { |
| 664 | return; |
| 665 | } |
| 666 | |
| 667 | aFrameBuffer->ChangeViewport (theWidth, theHeight); |
| 668 | } |
| 669 | |
| 670 | // ======================================================================= |
| 671 | // function : Export |
| 672 | // purpose : |
| 673 | // ======================================================================= |
| 674 | #ifdef HAVE_GL2PS |
| 675 | Standard_Boolean OpenGl_View::Export (const Standard_CString theFileName, |
| 676 | const Graphic3d_ExportFormat theFormat, |
| 677 | const Graphic3d_SortType theSortType) |
| 678 | { |
| 679 | // gl2psBeginPage() will call OpenGL functions |
| 680 | // so we should activate correct GL context before redraw scene call |
| 681 | if (!myWorkspace->Activate()) |
| 682 | { |
| 683 | return Standard_False; |
| 684 | } |
| 685 | |
| 686 | Standard_Integer aFormat = -1; |
| 687 | Standard_Integer aSortType = Graphic3d_ST_BSP_Tree; |
| 688 | switch (theFormat) |
| 689 | { |
| 690 | case Graphic3d_EF_PostScript: |
| 691 | aFormat = GL2PS_PS; |
| 692 | break; |
| 693 | case Graphic3d_EF_EnhPostScript: |
| 694 | aFormat = GL2PS_EPS; |
| 695 | break; |
| 696 | case Graphic3d_EF_TEX: |
| 697 | aFormat = GL2PS_TEX; |
| 698 | break; |
| 699 | case Graphic3d_EF_PDF: |
| 700 | aFormat = GL2PS_PDF; |
| 701 | break; |
| 702 | case Graphic3d_EF_SVG: |
| 703 | aFormat = GL2PS_SVG; |
| 704 | break; |
| 705 | case Graphic3d_EF_PGF: |
| 706 | aFormat = GL2PS_PGF; |
| 707 | break; |
| 708 | case Graphic3d_EF_EMF: |
| 709 | //aFormat = GL2PS_EMF; |
| 710 | aFormat = GL2PS_PGF + 1; // 6 |
| 711 | break; |
| 712 | default: |
| 713 | // unsupported format |
| 714 | return Standard_False; |
| 715 | } |
| 716 | |
| 717 | switch (theSortType) |
| 718 | { |
| 719 | case Graphic3d_ST_Simple: |
| 720 | aSortType = GL2PS_SIMPLE_SORT; |
| 721 | break; |
| 722 | case Graphic3d_ST_BSP_Tree: |
| 723 | aSortType = GL2PS_BSP_SORT; |
| 724 | break; |
| 725 | } |
| 726 | |
| 727 | GLint aViewport[4]; |
| 728 | aViewport[0] = 0; |
| 729 | aViewport[1] = 0; |
| 730 | aViewport[2] = myWindow->Width(); |
| 731 | aViewport[3] = myWindow->Height(); |
| 732 | |
| 733 | GLint aBufferSize = 1024 * 1024; |
| 734 | GLint anErrCode = GL2PS_SUCCESS; |
| 735 | |
| 736 | // gl2ps uses standard write functions and do not check locale |
| 737 | Standard_CLocaleSentry aLocaleSentry; |
| 738 | |
| 739 | while (aBufferSize > 0) |
| 740 | { |
| 741 | // current patch for EMF support in gl2ps uses WinAPI functions to create file |
| 742 | FILE* aFileH = (theFormat != Graphic3d_EF_EMF) ? fopen (theFileName, "wb") : NULL; |
| 743 | anErrCode = gl2psBeginPage ("", "", aViewport, aFormat, aSortType, |
| 744 | GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT/* | GL2PS_SIMPLE_LINE_OFFSET*/, |
| 745 | GL_RGBA, 0, NULL, |
| 746 | 0, 0, 0, aBufferSize, aFileH, theFileName); |
| 747 | if (anErrCode != GL2PS_SUCCESS) |
| 748 | { |
| 749 | // initialization failed |
| 750 | if (aFileH != NULL) |
| 751 | fclose (aFileH); |
| 752 | break; |
| 753 | } |
| 754 | Redraw(); |
| 755 | |
| 756 | anErrCode = gl2psEndPage(); |
| 757 | if (aFileH != NULL) |
| 758 | fclose (aFileH); |
| 759 | |
| 760 | if (anErrCode == GL2PS_OVERFLOW) |
| 761 | aBufferSize *= 2; |
| 762 | else |
| 763 | break; |
| 764 | } |
| 765 | return anErrCode == GL2PS_SUCCESS; |
| 766 | } |
| 767 | #else |
| 768 | Standard_Boolean OpenGl_View::Export (const Standard_CString /*theFileName*/, |
| 769 | const Graphic3d_ExportFormat /*theFormat*/, |
| 770 | const Graphic3d_SortType /*theSortType*/) |
| 771 | { |
| 772 | return Standard_False; |
| 773 | } |
| 774 | #endif |
| 775 | |
| 776 | //======================================================================= |
| 777 | //function : displayStructure |
| 778 | //purpose : |
| 779 | //======================================================================= |
| 780 | void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure, |
| 781 | const Standard_Integer thePriority) |
| 782 | { |
| 783 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->()); |
| 784 | const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer(); |
| 785 | myZLayers.AddStructure (aStruct, aZLayer, thePriority); |
| 786 | } |
| 787 | |
| 788 | //======================================================================= |
| 789 | //function : eraseStructure |
| 790 | //purpose : |
| 791 | //======================================================================= |
| 792 | void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure) |
| 793 | { |
| 794 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->()); |
| 795 | myZLayers.RemoveStructure (aStruct); |
| 796 | } |
| 797 | |
| 798 | //======================================================================= |
| 799 | //function : changeZLayer |
| 800 | //purpose : |
| 801 | //======================================================================= |
| 802 | void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure, |
| 803 | const Graphic3d_ZLayerId theNewLayerId) |
| 804 | { |
| 805 | const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer(); |
| 806 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->()); |
| 807 | myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId); |
| 808 | Update (Aspect_TOU_WAIT, anOldLayer); |
| 809 | Update (Aspect_TOU_WAIT, theNewLayerId); |
| 810 | } |
| 811 | |
| 812 | //======================================================================= |
| 813 | //function : changePriority |
| 814 | //purpose : |
| 815 | //======================================================================= |
| 816 | void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure, |
| 817 | const Standard_Integer theNewPriority) |
| 818 | { |
| 819 | const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer(); |
| 820 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->()); |
| 821 | myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority); |
| 822 | } |