1 // Created on: 2013-09-26 2 // Created by: Denis BOGOLEPOV 3 // Copyright (c) 2013-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 #ifndef _OpenGl_ShaderManager_HeaderFile 17 #define _OpenGl_ShaderManager_HeaderFile 18 19 #include <Graphic3d_ShaderProgram.hxx> 20 #include <Graphic3d_StereoMode.hxx> 21 22 #include <NCollection_DataMap.hxx> 23 #include <NCollection_Sequence.hxx> 24 25 #include <OpenGl_SetOfShaderPrograms.hxx> 26 #include <OpenGl_ShaderStates.hxx> 27 #include <OpenGl_Aspects.hxx> 28 #include <OpenGl_MaterialState.hxx> 29 #include <OpenGl_Texture.hxx> 30 31 class OpenGl_View; 32 class OpenGl_VertexBuffer; 33 34 //! List of shader programs. 35 typedef NCollection_Sequence<Handle(OpenGl_ShaderProgram)> OpenGl_ShaderProgramList; 36 37 //! This class is responsible for managing shader programs. 38 class OpenGl_ShaderManager : public Standard_Transient 39 { 40 DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient) 41 friend class OpenGl_ShaderProgram; 42 public: 43 44 //! Creates new empty shader manager. 45 Standard_EXPORT OpenGl_ShaderManager (OpenGl_Context* theContext); 46 47 //! Releases resources of shader manager. 48 Standard_EXPORT virtual ~OpenGl_ShaderManager(); 49 50 //! Release all resources. 51 Standard_EXPORT void clear(); 52 53 //! Return local camera transformation. LocalOrigin() const54 const gp_XYZ& LocalOrigin() const { return myLocalOrigin; } 55 56 //! Setup local camera transformation for compensating float precision issues. SetLocalOrigin(const gp_XYZ & theOrigin)57 void SetLocalOrigin (const gp_XYZ& theOrigin) 58 { 59 myLocalOrigin = theOrigin; 60 myHasLocalOrigin = !theOrigin.IsEqual (gp_XYZ(0.0, 0.0, 0.0), gp::Resolution()); 61 } 62 63 //! Return clipping plane W equation value moved considering local camera transformation. LocalClippingPlaneW(const Graphic3d_ClipPlane & thePlane) const64 Standard_Real LocalClippingPlaneW (const Graphic3d_ClipPlane& thePlane) const 65 { 66 const Graphic3d_Vec4d& anEq = thePlane.GetEquation(); 67 if (myHasLocalOrigin) 68 { 69 const gp_XYZ aPos = thePlane.ToPlane().Position().Location().XYZ() - myLocalOrigin; 70 return -(anEq.x() * aPos.X() + anEq.y() * aPos.Y() + anEq.z() * aPos.Z()); 71 } 72 return anEq.w(); 73 } 74 75 //! Creates new shader program or re-use shared instance. 76 //! @param theProxy [IN] program definition 77 //! @param theShareKey [OUT] sharing key 78 //! @param theProgram [OUT] OpenGL program 79 //! @return true on success 80 Standard_EXPORT Standard_Boolean Create (const Handle(Graphic3d_ShaderProgram)& theProxy, 81 TCollection_AsciiString& theShareKey, 82 Handle(OpenGl_ShaderProgram)& theProgram); 83 84 //! Unregisters specified shader program. 85 Standard_EXPORT void Unregister (TCollection_AsciiString& theShareKey, 86 Handle(OpenGl_ShaderProgram)& theProgram); 87 88 //! Returns list of registered shader programs. 89 Standard_EXPORT const OpenGl_ShaderProgramList& ShaderPrograms() const; 90 91 //! Returns true if no program objects are registered in the manager. 92 Standard_EXPORT Standard_Boolean IsEmpty() const; 93 94 //! Bind program for filled primitives rendering BindFaceProgram(const Handle (OpenGl_TextureSet)& theTextures,Graphic3d_TypeOfShadingModel theShadingModel,Graphic3d_AlphaMode theAlphaMode,Standard_Boolean theHasVertColor,Standard_Boolean theEnableEnvMap,const Handle (OpenGl_ShaderProgram)& theCustomProgram)95 Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures, 96 Graphic3d_TypeOfShadingModel theShadingModel, 97 Graphic3d_AlphaMode theAlphaMode, 98 Standard_Boolean theHasVertColor, 99 Standard_Boolean theEnableEnvMap, 100 const Handle(OpenGl_ShaderProgram)& theCustomProgram) 101 { 102 return BindFaceProgram (theTextures, theShadingModel, theAlphaMode, Aspect_IS_SOLID, 103 theHasVertColor, theEnableEnvMap, false, theCustomProgram); 104 } 105 106 //! Bind program for filled primitives rendering BindFaceProgram(const Handle (OpenGl_TextureSet)& theTextures,Graphic3d_TypeOfShadingModel theShadingModel,Graphic3d_AlphaMode theAlphaMode,Aspect_InteriorStyle theInteriorStyle,Standard_Boolean theHasVertColor,Standard_Boolean theEnableEnvMap,Standard_Boolean theEnableMeshEdges,const Handle (OpenGl_ShaderProgram)& theCustomProgram)107 Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures, 108 Graphic3d_TypeOfShadingModel theShadingModel, 109 Graphic3d_AlphaMode theAlphaMode, 110 Aspect_InteriorStyle theInteriorStyle, 111 Standard_Boolean theHasVertColor, 112 Standard_Boolean theEnableEnvMap, 113 Standard_Boolean theEnableMeshEdges, 114 const Handle(OpenGl_ShaderProgram)& theCustomProgram) 115 { 116 if (!theCustomProgram.IsNull() 117 || myContext->caps->ffpEnable) 118 { 119 return bindProgramWithState (theCustomProgram); 120 } 121 122 const Graphic3d_TypeOfShadingModel aShadeModelOnFace = theShadingModel != Graphic3d_TOSM_UNLIT 123 && (theTextures.IsNull() || theTextures->IsModulate()) 124 ? theShadingModel 125 : Graphic3d_TOSM_UNLIT; 126 const Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, theInteriorStyle, theHasVertColor, theEnableEnvMap, theEnableMeshEdges); 127 Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (aShadeModelOnFace, aBits); 128 return bindProgramWithState (aProgram); 129 } 130 131 //! Bind program for line rendering BindLineProgram(const Handle (OpenGl_TextureSet)& theTextures,const Aspect_TypeOfLine theLineType,const Graphic3d_TypeOfShadingModel theShadingModel,const Graphic3d_AlphaMode theAlphaMode,const Standard_Boolean theHasVertColor,const Handle (OpenGl_ShaderProgram)& theCustomProgram)132 Standard_Boolean BindLineProgram (const Handle(OpenGl_TextureSet)& theTextures, 133 const Aspect_TypeOfLine theLineType, 134 const Graphic3d_TypeOfShadingModel theShadingModel, 135 const Graphic3d_AlphaMode theAlphaMode, 136 const Standard_Boolean theHasVertColor, 137 const Handle(OpenGl_ShaderProgram)& theCustomProgram) 138 { 139 if (!theCustomProgram.IsNull() 140 || myContext->caps->ffpEnable) 141 { 142 return bindProgramWithState (theCustomProgram); 143 } 144 145 Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, Aspect_IS_SOLID, theHasVertColor, false, false); 146 if (theLineType != Aspect_TOL_SOLID) 147 { 148 aBits |= OpenGl_PO_StippleLine; 149 } 150 151 Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theShadingModel, aBits); 152 return bindProgramWithState (aProgram); 153 } 154 155 //! Bind program for point rendering 156 Standard_EXPORT Standard_Boolean BindMarkerProgram (const Handle(OpenGl_TextureSet)& theTextures, 157 Graphic3d_TypeOfShadingModel theShadingModel, 158 Graphic3d_AlphaMode theAlphaMode, 159 Standard_Boolean theHasVertColor, 160 const Handle(OpenGl_ShaderProgram)& theCustomProgram); 161 162 //! Bind program for rendering alpha-textured font. BindFontProgram(const Handle (OpenGl_ShaderProgram)& theCustomProgram)163 Standard_Boolean BindFontProgram (const Handle(OpenGl_ShaderProgram)& theCustomProgram) 164 { 165 if (!theCustomProgram.IsNull() 166 || myContext->caps->ffpEnable) 167 { 168 return bindProgramWithState (theCustomProgram); 169 } 170 171 if (myFontProgram.IsNull()) 172 { 173 prepareStdProgramFont(); 174 } 175 176 return bindProgramWithState (myFontProgram); 177 } 178 179 //! Bind program for outline rendering BindOutlineProgram()180 Standard_Boolean BindOutlineProgram() 181 { 182 if (myContext->caps->ffpEnable) 183 { 184 return false; 185 } 186 187 const Standard_Integer aBits = getProgramBits (Handle(OpenGl_TextureSet)(), Graphic3d_AlphaMode_Opaque, Aspect_IS_SOLID, false, false, false); 188 if (myOutlinePrograms.IsNull()) 189 { 190 myOutlinePrograms = new OpenGl_SetOfPrograms(); 191 } 192 Handle(OpenGl_ShaderProgram)& aProgram = myOutlinePrograms->ChangeValue (aBits); 193 if (aProgram.IsNull()) 194 { 195 prepareStdProgramUnlit (aProgram, aBits, true); 196 } 197 return bindProgramWithState (aProgram); 198 } 199 200 //! Bind program for FBO blit operation. BindFboBlitProgram()201 Standard_Boolean BindFboBlitProgram() 202 { 203 if (myBlitProgram.IsNull()) 204 { 205 prepareStdProgramFboBlit(); 206 } 207 return !myBlitProgram.IsNull() 208 && myContext->BindProgram (myBlitProgram); 209 } 210 211 //! Bind program for blended order-independent transparency buffers compositing. BindOitCompositingProgram(const Standard_Boolean theIsMSAAEnabled)212 Standard_Boolean BindOitCompositingProgram (const Standard_Boolean theIsMSAAEnabled) 213 { 214 const Standard_Integer aProgramIdx = theIsMSAAEnabled ? 1 : 0; 215 if (myOitCompositingProgram[aProgramIdx].IsNull()) 216 { 217 prepareStdProgramOitCompositing (theIsMSAAEnabled); 218 } 219 220 const Handle(OpenGl_ShaderProgram)& aProgram = myOitCompositingProgram [aProgramIdx]; 221 return !aProgram.IsNull() && myContext->BindProgram (aProgram); 222 } 223 224 //! Bind program for rendering stereoscopic image. BindStereoProgram(const Graphic3d_StereoMode theStereoMode)225 Standard_Boolean BindStereoProgram (const Graphic3d_StereoMode theStereoMode) 226 { 227 if (theStereoMode < 0 || theStereoMode >= Graphic3d_StereoMode_NB) 228 { 229 return Standard_False; 230 } 231 232 if (myStereoPrograms[theStereoMode].IsNull()) 233 { 234 prepareStdProgramStereo (myStereoPrograms[theStereoMode], theStereoMode); 235 } 236 const Handle(OpenGl_ShaderProgram)& aProgram = myStereoPrograms[theStereoMode]; 237 return !aProgram.IsNull() 238 && myContext->BindProgram (aProgram); 239 } 240 241 //! Bind program for rendering bounding box. BindBoundBoxProgram()242 Standard_Boolean BindBoundBoxProgram() 243 { 244 if (myBoundBoxProgram.IsNull()) 245 { 246 prepareStdProgramBoundBox(); 247 } 248 return bindProgramWithState (myBoundBoxProgram); 249 } 250 251 //! Returns bounding box vertex buffer. Handle(OpenGl_VertexBuffer)252 const Handle(OpenGl_VertexBuffer)& BoundBoxVertBuffer() const { return myBoundBoxVertBuffer; } 253 254 //! Generates shader program to render environment cubemap as background. 255 Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram (); 256 257 public: 258 259 //! Returns current state of OCCT light sources. LightSourceState() const260 const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; } 261 262 //! Updates state of OCCT light sources. 263 Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights); 264 265 //! Invalidate state of OCCT light sources. 266 Standard_EXPORT void UpdateLightSourceState(); 267 268 //! Pushes current state of OCCT light sources to specified program (only on state change). PushLightSourceState(const Handle (OpenGl_ShaderProgram)& theProgram) const269 void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const 270 { 271 if (myLightSourceState.Index() != theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)) 272 { 273 pushLightSourceState (theProgram); 274 } 275 } 276 277 //! Pushes current state of OCCT light sources to specified program. 278 Standard_EXPORT void pushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const; 279 280 public: 281 282 //! Returns current state of OCCT projection transform. ProjectionState() const283 const OpenGl_ProjectionState& ProjectionState() const { return myProjectionState; } 284 285 //! Updates state of OCCT projection transform. 286 Standard_EXPORT void UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix); 287 288 //! Pushes current state of OCCT projection transform to specified program (only on state change). PushProjectionState(const Handle (OpenGl_ShaderProgram)& theProgram) const289 void PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const 290 { 291 if (myProjectionState.Index() != theProgram->ActiveState (OpenGl_PROJECTION_STATE)) 292 { 293 pushProjectionState (theProgram); 294 } 295 } 296 297 //! Pushes current state of OCCT projection transform to specified program. 298 Standard_EXPORT void pushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const; 299 300 public: 301 302 //! Returns current state of OCCT model-world transform. ModelWorldState() const303 const OpenGl_ModelWorldState& ModelWorldState() const { return myModelWorldState; } 304 305 //! Updates state of OCCT model-world transform. 306 Standard_EXPORT void UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix); 307 308 //! Pushes current state of OCCT model-world transform to specified program (only on state change). PushModelWorldState(const Handle (OpenGl_ShaderProgram)& theProgram) const309 void PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const 310 { 311 if (myModelWorldState.Index() != theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE)) 312 { 313 pushModelWorldState (theProgram); 314 } 315 } 316 317 //! Pushes current state of OCCT model-world transform to specified program. 318 Standard_EXPORT void pushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const; 319 320 public: 321 322 //! Returns current state of OCCT world-view transform. WorldViewState() const323 const OpenGl_WorldViewState& WorldViewState() const { return myWorldViewState; } 324 325 //! Updates state of OCCT world-view transform. 326 Standard_EXPORT void UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix); 327 328 //! Pushes current state of OCCT world-view transform to specified program (only on state change). PushWorldViewState(const Handle (OpenGl_ShaderProgram)& theProgram) const329 void PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const 330 { 331 if (myWorldViewState.Index() != theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE)) 332 { 333 pushWorldViewState (theProgram); 334 } 335 } 336 337 //! Pushes current state of OCCT world-view transform to specified program. 338 Standard_EXPORT void pushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const; 339 340 public: 341 342 //! Updates state of OCCT clipping planes. 343 Standard_EXPORT void UpdateClippingState(); 344 345 //! Reverts state of OCCT clipping planes. 346 Standard_EXPORT void RevertClippingState(); 347 348 //! Pushes current state of OCCT clipping planes to specified program (only on state change). PushClippingState(const Handle (OpenGl_ShaderProgram)& theProgram) const349 void PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const 350 { 351 if (myClippingState.Index() != theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE)) 352 { 353 pushClippingState (theProgram); 354 } 355 } 356 357 //! Pushes current state of OCCT clipping planes to specified program. 358 Standard_EXPORT void pushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const; 359 360 public: 361 362 //! Returns current state of material. MaterialState() const363 const OpenGl_MaterialState& MaterialState() const { return myMaterialState; } 364 365 //! Updates state of material. UpdateMaterialStateTo(const OpenGl_Material & theFrontMat,const OpenGl_Material & theBackMat,const float theAlphaCutoff,const bool theToDistinguish,const bool theToMapTexture)366 void UpdateMaterialStateTo (const OpenGl_Material& theFrontMat, 367 const OpenGl_Material& theBackMat, 368 const float theAlphaCutoff, 369 const bool theToDistinguish, 370 const bool theToMapTexture) 371 { 372 myMaterialState.Set (theFrontMat, theBackMat, theAlphaCutoff, theToDistinguish, theToMapTexture); 373 myMaterialState.Update(); 374 } 375 376 //! Updates state of material. UpdateMaterialState()377 void UpdateMaterialState() 378 { 379 myMaterialState.Update(); 380 } 381 382 //! Pushes current state of material to specified program (only on state change). PushMaterialState(const Handle (OpenGl_ShaderProgram)& theProgram) const383 void PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const 384 { 385 if (myMaterialState.Index() != theProgram->ActiveState (OpenGl_MATERIAL_STATE)) 386 { 387 pushMaterialState (theProgram); 388 } 389 } 390 391 //! Pushes current state of material to specified program. 392 Standard_EXPORT void pushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const; 393 394 public: 395 396 //! Setup interior style line edges variables. 397 Standard_EXPORT void PushInteriorState (const Handle(OpenGl_ShaderProgram)& theProgram, 398 const Handle(Graphic3d_Aspects)& theAspect) const; 399 400 public: 401 402 //! Returns state of OIT uniforms. OitState() const403 const OpenGl_OitState& OitState() const { return myOitState; } 404 405 //! Set the state of OIT rendering pass (only on state change). 406 //! @param theToEnableOitWrite [in] flag indicating whether the special output should be written for OIT algorithm. 407 //! @param theDepthFactor [in] the scalar factor of depth influence to the fragment's coverage. SetOitState(const bool theToEnableOitWrite,const float theDepthFactor)408 void SetOitState (const bool theToEnableOitWrite, const float theDepthFactor) 409 { 410 myOitState.Set (theToEnableOitWrite, theDepthFactor); 411 myOitState.Update(); 412 } 413 414 //! Pushes state of OIT uniforms to the specified program. PushOitState(const Handle (OpenGl_ShaderProgram)& theProgram) const415 void PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const 416 { 417 if (theProgram->IsValid() 418 && myOitState.Index() != theProgram->ActiveState (OpenGL_OIT_STATE)) 419 { 420 pushOitState (theProgram); 421 } 422 } 423 424 //! Pushes state of OIT uniforms to the specified program. 425 Standard_EXPORT void pushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const; 426 427 public: 428 429 //! Pushes current state of OCCT graphics parameters to specified program. 430 Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const; 431 432 public: 433 434 //! Overwrites context SetContext(OpenGl_Context * theCtx)435 void SetContext (OpenGl_Context* theCtx) 436 { 437 myContext = theCtx; 438 } 439 440 //! Returns true when provided context is the same as used one by shader manager. IsSameContext(OpenGl_Context * theCtx) const441 bool IsSameContext (OpenGl_Context* theCtx) const 442 { 443 return myContext == theCtx; 444 } 445 446 //! Choose Shading Model for filled primitives. 447 //! Fallbacks to FACET model if there are no normal attributes. ChooseFaceShadingModel(Graphic3d_TypeOfShadingModel theCustomModel,bool theHasNodalNormals) const448 Graphic3d_TypeOfShadingModel ChooseFaceShadingModel (Graphic3d_TypeOfShadingModel theCustomModel, 449 bool theHasNodalNormals) const 450 { 451 if (!myContext->ColorMask()) 452 { 453 return Graphic3d_TOSM_UNLIT; 454 } 455 Graphic3d_TypeOfShadingModel aModel = theCustomModel != Graphic3d_TOSM_DEFAULT ? theCustomModel : myShadingModel; 456 switch (aModel) 457 { 458 case Graphic3d_TOSM_DEFAULT: 459 case Graphic3d_TOSM_UNLIT: 460 case Graphic3d_TOSM_FACET: 461 return aModel; 462 case Graphic3d_TOSM_VERTEX: 463 case Graphic3d_TOSM_FRAGMENT: 464 return theHasNodalNormals ? aModel : Graphic3d_TOSM_FACET; 465 } 466 return Graphic3d_TOSM_UNLIT; 467 } 468 469 //! Choose Shading Model for line primitives. 470 //! Fallbacks to UNLIT model if there are no normal attributes. ChooseLineShadingModel(Graphic3d_TypeOfShadingModel theCustomModel,bool theHasNodalNormals) const471 Graphic3d_TypeOfShadingModel ChooseLineShadingModel (Graphic3d_TypeOfShadingModel theCustomModel, 472 bool theHasNodalNormals) const 473 { 474 if (!myContext->ColorMask()) 475 { 476 return Graphic3d_TOSM_UNLIT; 477 } 478 Graphic3d_TypeOfShadingModel aModel = theCustomModel != Graphic3d_TOSM_DEFAULT ? theCustomModel : myShadingModel; 479 switch (aModel) 480 { 481 case Graphic3d_TOSM_DEFAULT: 482 case Graphic3d_TOSM_UNLIT: 483 case Graphic3d_TOSM_FACET: 484 return Graphic3d_TOSM_UNLIT; 485 case Graphic3d_TOSM_VERTEX: 486 case Graphic3d_TOSM_FRAGMENT: 487 return theHasNodalNormals ? aModel : Graphic3d_TOSM_UNLIT; 488 } 489 return Graphic3d_TOSM_UNLIT; 490 } 491 492 //! Choose Shading Model for Marker primitives. ChooseMarkerShadingModel(Graphic3d_TypeOfShadingModel theCustomModel,bool theHasNodalNormals) const493 Graphic3d_TypeOfShadingModel ChooseMarkerShadingModel (Graphic3d_TypeOfShadingModel theCustomModel, 494 bool theHasNodalNormals) const 495 { 496 return ChooseLineShadingModel (theCustomModel, theHasNodalNormals); 497 } 498 499 //! Returns default Shading Model. ShadingModel() const500 Graphic3d_TypeOfShadingModel ShadingModel() const { return myShadingModel; } 501 502 //! Sets shading model. 503 Standard_EXPORT void SetShadingModel (const Graphic3d_TypeOfShadingModel theModel); 504 505 //! Sets last view manger used with. 506 //! Helps to handle matrix states in multi-view configurations. SetLastView(const OpenGl_View * theLastView)507 void SetLastView (const OpenGl_View* theLastView) 508 { 509 myLastView = theLastView; 510 } 511 512 //! Returns true when provided view is the same as cached one. IsSameView(const OpenGl_View * theView) const513 bool IsSameView (const OpenGl_View* theView) const 514 { 515 return myLastView == theView; 516 } 517 518 protected: 519 520 //! Define clipping planes program bits. getClipPlaneBits() const521 Standard_Integer getClipPlaneBits() const 522 { 523 const Standard_Integer aNbPlanes = myContext->Clipping().NbClippingOrCappingOn(); 524 if (aNbPlanes <= 0) 525 { 526 return 0; 527 } 528 529 Standard_Integer aBits = 0; 530 if (myContext->Clipping().HasClippingChains()) 531 { 532 aBits |= OpenGl_PO_ClipChains; 533 } 534 535 if (aNbPlanes == 1) 536 { 537 aBits |= OpenGl_PO_ClipPlanes1; 538 } 539 else if (aNbPlanes == 2) 540 { 541 aBits |= OpenGl_PO_ClipPlanes2; 542 } 543 else 544 { 545 aBits |= OpenGl_PO_ClipPlanesN; 546 } 547 return aBits; 548 } 549 550 //! Define program bits. getProgramBits(const Handle (OpenGl_TextureSet)& theTextures,Graphic3d_AlphaMode theAlphaMode,Aspect_InteriorStyle theInteriorStyle,Standard_Boolean theHasVertColor,Standard_Boolean theEnableEnvMap,Standard_Boolean theEnableMeshEdges) const551 Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures, 552 Graphic3d_AlphaMode theAlphaMode, 553 Aspect_InteriorStyle theInteriorStyle, 554 Standard_Boolean theHasVertColor, 555 Standard_Boolean theEnableEnvMap, 556 Standard_Boolean theEnableMeshEdges) const 557 { 558 Standard_Integer aBits = 0; 559 if (theAlphaMode == Graphic3d_AlphaMode_Mask) 560 { 561 aBits |= OpenGl_PO_AlphaTest; 562 } 563 564 aBits |= getClipPlaneBits(); 565 if (theEnableMeshEdges 566 && myContext->hasGeometryStage != OpenGl_FeatureNotAvailable) 567 { 568 aBits |= OpenGl_PO_MeshEdges; 569 if (theInteriorStyle == Aspect_IS_HOLLOW) 570 { 571 aBits |= OpenGl_PO_AlphaTest; 572 } 573 } 574 575 if (theEnableEnvMap) 576 { 577 // Environment map overwrites material texture 578 aBits |= OpenGl_PO_TextureEnv; 579 } 580 else if (!theTextures.IsNull() 581 && theTextures->HasNonPointSprite()) 582 { 583 aBits |= OpenGl_PO_TextureRGB; 584 } 585 if (theHasVertColor 586 && theInteriorStyle != Aspect_IS_HIDDENLINE) 587 { 588 aBits |= OpenGl_PO_VertColor; 589 } 590 591 if (myOitState.ToEnableWrite()) 592 { 593 aBits |= OpenGl_PO_WriteOit; 594 } 595 return aBits; 596 } 597 598 //! Prepare standard GLSL program. Handle(OpenGl_ShaderProgram)599 Handle(OpenGl_ShaderProgram)& getStdProgram (Graphic3d_TypeOfShadingModel theShadingModel, 600 Standard_Integer theBits) 601 { 602 if (theShadingModel == Graphic3d_TOSM_UNLIT 603 || (theBits & OpenGl_PO_TextureEnv) != 0) 604 { 605 // If environment map is enabled lighting calculations are 606 // not needed (in accordance with default OCCT behavior) 607 Handle(OpenGl_ShaderProgram)& aProgram = myUnlitPrograms->ChangeValue (theBits); 608 if (aProgram.IsNull()) 609 { 610 prepareStdProgramUnlit (aProgram, theBits, false); 611 } 612 return aProgram; 613 } 614 615 Handle(OpenGl_ShaderProgram)& aProgram = myLightPrograms->ChangeValue (theShadingModel, theBits); 616 if (aProgram.IsNull()) 617 { 618 prepareStdProgramLight (aProgram, theShadingModel, theBits); 619 } 620 return aProgram; 621 } 622 623 //! Prepare standard GLSL program for accessing point sprite alpha. 624 Standard_EXPORT TCollection_AsciiString pointSpriteAlphaSrc (Standard_Integer theBits); 625 626 //! Prepare standard GLSL program for computing point sprite shading. 627 Standard_EXPORT TCollection_AsciiString pointSpriteShadingSrc (const TCollection_AsciiString& theBaseColorSrc, 628 Standard_Integer theBits); 629 630 //! Prepare standard GLSL program for textured font. 631 Standard_EXPORT Standard_Boolean prepareStdProgramFont(); 632 633 //! Prepare standard GLSL program for FBO blit operation. 634 Standard_EXPORT Standard_Boolean prepareStdProgramFboBlit(); 635 636 //! Prepare standard GLSL programs for OIT compositing operation. 637 Standard_EXPORT Standard_Boolean prepareStdProgramOitCompositing (const Standard_Boolean theMsaa); 638 639 //! Prepare standard GLSL program without lighting. 640 Standard_EXPORT Standard_Boolean prepareStdProgramUnlit (Handle(OpenGl_ShaderProgram)& theProgram, 641 Standard_Integer theBits, 642 Standard_Boolean theIsOutline = false); 643 644 //! Prepare standard GLSL program with lighting. prepareStdProgramLight(Handle (OpenGl_ShaderProgram)& theProgram,Graphic3d_TypeOfShadingModel theShadingModel,Standard_Integer theBits)645 Standard_Boolean prepareStdProgramLight (Handle(OpenGl_ShaderProgram)& theProgram, 646 Graphic3d_TypeOfShadingModel theShadingModel, 647 Standard_Integer theBits) 648 { 649 switch (theShadingModel) 650 { 651 case Graphic3d_TOSM_UNLIT: return prepareStdProgramUnlit (theProgram, theBits, false); 652 case Graphic3d_TOSM_FACET: return prepareStdProgramPhong (theProgram, theBits, true); 653 case Graphic3d_TOSM_VERTEX: return prepareStdProgramGouraud(theProgram, theBits); 654 case Graphic3d_TOSM_DEFAULT: 655 case Graphic3d_TOSM_FRAGMENT: return prepareStdProgramPhong (theProgram, theBits, false); 656 } 657 return false; 658 } 659 660 //! Prepare standard GLSL program with per-vertex lighting. 661 Standard_EXPORT Standard_Boolean prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram, 662 const Standard_Integer theBits); 663 664 //! Prepare standard GLSL program with per-pixel lighting. 665 //! @param theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will be computed instead 666 Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram, 667 const Standard_Integer theBits, 668 const Standard_Boolean theIsFlatNormal = false); 669 670 //! Define computeLighting GLSL function depending on current lights configuration 671 //! @param theNbLights [out] number of defined light sources 672 //! @param theHasVertColor [in] flag to use getVertColor() instead of Ambient and Diffuse components of active material 673 Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights, 674 Standard_Boolean theHasVertColor); 675 676 //! Bind specified program to current context and apply state. 677 Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram); 678 679 //! Set pointer myLightPrograms to active lighting programs set from myMapOfLightPrograms 680 Standard_EXPORT void switchLightPrograms(); 681 682 //! Prepare standard GLSL program for stereoscopic image. 683 Standard_EXPORT Standard_Boolean prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram, 684 const Graphic3d_StereoMode theStereoMode); 685 686 //! Prepare standard GLSL program for bounding box. 687 Standard_EXPORT Standard_Boolean prepareStdProgramBoundBox(); 688 689 //! Prepare GLSL version header. 690 Standard_EXPORT Standard_Integer defaultGlslVersion (const Handle(Graphic3d_ShaderProgram)& theProgram, 691 const TCollection_AsciiString& theName, 692 Standard_Integer theBits, 693 bool theUsesDerivates = false) const; 694 695 //! Prepare GLSL source for geometry shader according to parameters. 696 Standard_EXPORT TCollection_AsciiString prepareGeomMainSrc (OpenGl_ShaderObject::ShaderVariableList& theUnifoms, 697 OpenGl_ShaderObject::ShaderVariableList& theStageInOuts, 698 Standard_Integer theBits); 699 700 protected: 701 702 //! Packed properties of light source 703 struct OpenGl_ShaderLightParameters 704 { 705 OpenGl_Vec4 Color; 706 OpenGl_Vec4 Position; 707 OpenGl_Vec4 Direction; 708 OpenGl_Vec4 Parameters; 709 710 //! Returns packed (serialized) representation of light source properties PackedOpenGl_ShaderManager::OpenGl_ShaderLightParameters711 const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); } NbOfVec4OpenGl_ShaderManager::OpenGl_ShaderLightParameters712 static Standard_Integer NbOfVec4() { return 4; } 713 }; 714 715 //! Packed light source type information 716 struct OpenGl_ShaderLightType 717 { 718 Standard_Integer Type; 719 Standard_Integer IsHeadlight; 720 721 //! Returns packed (serialized) representation of light source type PackedOpenGl_ShaderManager::OpenGl_ShaderLightType722 const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); } NbOfVec2iOpenGl_ShaderManager::OpenGl_ShaderLightType723 static Standard_Integer NbOfVec2i() { return 1; } 724 }; 725 726 //! Fake OpenGL program for tracking FFP state in the way consistent to programmable pipeline. 727 class OpenGl_ShaderProgramFFP : public OpenGl_ShaderProgram 728 { 729 DEFINE_STANDARD_RTTI_INLINE(OpenGl_ShaderProgramFFP, OpenGl_ShaderProgram) 730 friend class OpenGl_ShaderManager; 731 protected: OpenGl_ShaderProgramFFP()732 OpenGl_ShaderProgramFFP() {} 733 }; 734 735 protected: 736 737 //! Append clipping plane definition to temporary buffers. addClippingPlane(Standard_Integer & thePlaneId,const Graphic3d_ClipPlane & thePlane,const Graphic3d_Vec4d & theEq,const Standard_Integer theChainFwd) const738 void addClippingPlane (Standard_Integer& thePlaneId, 739 const Graphic3d_ClipPlane& thePlane, 740 const Graphic3d_Vec4d& theEq, 741 const Standard_Integer theChainFwd) const 742 { 743 myClipChainArray.SetValue (thePlaneId, theChainFwd); 744 OpenGl_Vec4& aPlaneEq = myClipPlaneArray.ChangeValue (thePlaneId); 745 aPlaneEq.x() = float(theEq.x()); 746 aPlaneEq.y() = float(theEq.y()); 747 aPlaneEq.z() = float(theEq.z()); 748 aPlaneEq.w() = float(theEq.w()); 749 if (myHasLocalOrigin) 750 { 751 aPlaneEq.w() = float(LocalClippingPlaneW (thePlane)); 752 } 753 ++thePlaneId; 754 } 755 756 protected: 757 758 Handle(OpenGl_ShaderProgramFFP) myFfpProgram; 759 760 Graphic3d_TypeOfShadingModel myShadingModel; //!< lighting shading model 761 OpenGl_ShaderProgramList myProgramList; //!< The list of shader programs 762 Handle(OpenGl_SetOfShaderPrograms) myLightPrograms; //!< pointer to active lighting programs matrix 763 Handle(OpenGl_SetOfPrograms) myUnlitPrograms; //!< programs matrix without lighting 764 Handle(OpenGl_SetOfPrograms) myOutlinePrograms; //!< programs matrix without lighting for outline presentation 765 Handle(OpenGl_ShaderProgram) myFontProgram; //!< standard program for textured text 766 Handle(OpenGl_ShaderProgram) myBlitProgram; //!< standard program for FBO blit emulation 767 Handle(OpenGl_ShaderProgram) myBoundBoxProgram; //!< standard program for bounding box 768 Handle(OpenGl_ShaderProgram) myOitCompositingProgram[2]; //!< standard program for OIT compositing (default and MSAA). 769 OpenGl_MapOfShaderPrograms myMapOfLightPrograms; //!< map of lighting programs depending on lights configuration 770 771 Handle(Graphic3d_ShaderProgram) myBgCubeMapProgram; //!< program for background cubemap rendering 772 773 Handle(OpenGl_ShaderProgram) myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs 774 775 Handle(OpenGl_VertexBuffer) myBoundBoxVertBuffer; //!< bounding box vertex buffer 776 777 OpenGl_Context* myContext; //!< OpenGL context 778 779 protected: 780 781 OpenGl_ProjectionState myProjectionState; //!< State of OCCT projection transformation 782 OpenGl_ModelWorldState myModelWorldState; //!< State of OCCT model-world transformation 783 OpenGl_WorldViewState myWorldViewState; //!< State of OCCT world-view transformation 784 OpenGl_ClippingState myClippingState; //!< State of OCCT clipping planes 785 OpenGl_LightSourceState myLightSourceState; //!< State of OCCT light sources 786 OpenGl_MaterialState myMaterialState; //!< State of Front and Back materials 787 OpenGl_OitState myOitState; //!< State of OIT uniforms 788 789 gp_XYZ myLocalOrigin; //!< local camera transformation 790 Standard_Boolean myHasLocalOrigin; //!< flag indicating that local camera transformation has been set 791 792 mutable NCollection_Array1<OpenGl_ShaderLightType> myLightTypeArray; 793 mutable NCollection_Array1<OpenGl_ShaderLightParameters> myLightParamsArray; 794 mutable NCollection_Array1<OpenGl_Vec4> myClipPlaneArray; 795 mutable NCollection_Array1<OpenGl_Vec4d> myClipPlaneArrayFfp; 796 mutable NCollection_Array1<Standard_Integer> myClipChainArray; 797 798 private: 799 800 const OpenGl_View* myLastView; //!< Pointer to the last view shader manager used with 801 802 }; 803 804 DEFINE_STANDARD_HANDLE(OpenGl_ShaderManager, Standard_Transient) 805 806 #endif // _OpenGl_ShaderManager_HeaderFile 807