From 05e2200bbfcb3e474f704a0190018b731cb4a4e1 Mon Sep 17 00:00:00 2001 From: kgv Date: Thu, 30 Oct 2014 13:51:14 +0300 Subject: [PATCH] 0025422: Visualization, TKOpenGl - support re-assignment of new window to existing View Do not throw "Window already defined" exception in Visual3d_View/V3d_View. Handle window change within OpenGl_GraphicDriver::View(). OpenGl_GraphicDriver - introduce dedicated methods to initialize/release shared OpenGL context. ::InitEglContext() to using existing EGL context. OpenGl_Context - always enable NPOT textures on OpenGL ES 2.0 OpenGl_Workspace - do not call glDisable/glEnable(GL_TEXTURE_2D) on GL ES OpenGl_GraphicDriver::ReleaseContext() - release EGL context on destruction OpenGl_GraphicDriver::InitEglContext() - escape method implementation with HAVE_EGL macros OpenGl_ShaderManager - clear shader programs on shared context invalidation --- src/Graphic3d/Graphic3d_Camera.hxx | 16 +- src/OpenGl/OpenGl_Context.cxx | 25 ++- src/OpenGl/OpenGl_Context.hxx | 3 + src/OpenGl/OpenGl_GraphicDriver.cxx | 226 ++++++++++++++++++-------- src/OpenGl/OpenGl_GraphicDriver.hxx | 30 +++- src/OpenGl/OpenGl_GraphicDriver_7.cxx | 21 ++- src/OpenGl/OpenGl_ShaderManager.cxx | 16 +- src/OpenGl/OpenGl_ShaderManager.hxx | 5 +- src/OpenGl/OpenGl_Workspace.cxx | 4 +- src/V3d/V3d_View.cxx | 19 +-- src/Visual3d/Visual3d_View.cxx | 16 +- 11 files changed, 265 insertions(+), 116 deletions(-) mode change 100755 => 100644 src/OpenGl/OpenGl_ShaderManager.cxx mode change 100755 => 100644 src/OpenGl/OpenGl_ShaderManager.hxx diff --git a/src/Graphic3d/Graphic3d_Camera.hxx b/src/Graphic3d/Graphic3d_Camera.hxx index b0635a86be..f7346179d5 100644 --- a/src/Graphic3d/Graphic3d_Camera.hxx +++ b/src/Graphic3d/Graphic3d_Camera.hxx @@ -485,6 +485,14 @@ public: //! Please note that this method is used for rendering for Projection_Stereo. Standard_EXPORT const Graphic3d_Mat4& ProjectionStereoRightF() const; + //! Invalidate state of projection matrix. + //! The matrix will be updated on request. + Standard_EXPORT void InvalidateProjection(); + + //! Invalidate orientation matrix. + //! The matrix will be updated on request. + Standard_EXPORT void InvalidateOrientation(); + //! @name Managing projection and orientation cache private: @@ -500,14 +508,6 @@ private: Standard_EXPORT TransformMatrices& UpdateOrientation (TransformMatrices& theMatrices) const; - //! Invalidate state of projection matrix. - //! The matrix will be updated on request. - void InvalidateProjection(); - - //! Invalidate orientation matrix. - //! The matrix will be updated on request. - void InvalidateOrientation(); - private: //! Compose orthographic projection matrix for diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 9702d155f0..786fcde471 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -199,6 +199,23 @@ OpenGl_Context::~OpenGl_Context() #endif } +// ======================================================================= +// function : forcedRelease +// purpose : +// ======================================================================= +void OpenGl_Context::forcedRelease() +{ + ReleaseDelayed(); + for (NCollection_DataMap::Iterator anIter (*mySharedResources); + anIter.More(); anIter.Next()) + { + anIter.Value()->Release (this); + } + mySharedResources->Clear(); + myShaderManager->clear(); + myShaderManager->SetContext (NULL); +} + // ======================================================================= // function : MaxDegreeOfAnisotropy // purpose : @@ -878,8 +895,12 @@ void OpenGl_Context::init() hasTexRGBA8 = IsGlGreaterEqual (3, 0) || CheckExtension ("GL_OES_rgb8_rgba8"); - arbNPTW = IsGlGreaterEqual (3, 0) - || CheckExtension ("GL_OES_texture_npot"); + // NPOT textures has limited support within OpenGL ES 2.0 + // which are relaxed by OpenGL ES 3.0 or some extensions + //arbNPTW = IsGlGreaterEqual (3, 0) + // || CheckExtension ("GL_OES_texture_npot") + // || CheckExtension ("GL_NV_texture_npot_2D_mipmap"); + arbNPTW = Standard_True; arbTexRG = IsGlGreaterEqual (3, 0) || CheckExtension ("GL_EXT_texture_rg"); extBgra = CheckExtension ("GL_EXT_texture_format_BGRA8888"); diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index c5140b7566..07c218c376 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -168,6 +168,9 @@ public: //! Destructor. Standard_EXPORT virtual ~OpenGl_Context(); + //! Release all resources, including shared ones + Standard_EXPORT void forcedRelease(); + //! Share GL context resources. //! theShareCtx - handle to context to retrieve handles to shared resources. Standard_EXPORT void Share (const Handle(OpenGl_Context)& theShareCtx); diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index 3221eb998c..574c82e441 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -51,8 +51,9 @@ namespace // purpose : // ======================================================================= OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnection)& theDisp, - const Standard_Boolean theToStealActiveContext) + const Standard_Boolean theToInitialize) : Graphic3d_GraphicDriver (theDisp), + myIsOwnContext (Standard_False), #if defined(HAVE_EGL) || defined(__ANDROID__) myEglDisplay ((Aspect_Display )EGL_NO_DISPLAY), myEglContext ((Aspect_RenderingContext )EGL_NO_CONTEXT), @@ -82,77 +83,134 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnectio int aDummy; if (!XQueryExtension (aDisplay, "GLX", &aDummy, &aDummy, &aDummy)) { - #ifdef DEBUG - std::cerr << "This system doesn't appear to support OpenGL\n"; - #endif + ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, this system doesn't appear to support OpenGL!", Message_Warning); } #endif #endif + if (theToInitialize + && !InitContext()) + { + Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: default context can not be initialized!"); + } +} -#if defined(HAVE_EGL) || defined(__ANDROID__) - if (theToStealActiveContext) +// ======================================================================= +// function : ~OpenGl_GraphicDriver +// purpose : +// ======================================================================= +OpenGl_GraphicDriver::~OpenGl_GraphicDriver() +{ + ReleaseContext(); +} + +// ======================================================================= +// function : ReleaseContext +// purpose : +// ======================================================================= +void OpenGl_GraphicDriver::ReleaseContext() +{ + Handle(OpenGl_Context) aCtxShared; + for (NCollection_DataMap::Iterator aWindowIter (myMapOfWS); + aWindowIter.More(); aWindowIter.Next()) { - myEglDisplay = (Aspect_Display )eglGetCurrentDisplay(); - myEglContext = (Aspect_RenderingContext )eglGetCurrentContext(); - EGLSurface aEglSurf = eglGetCurrentSurface(EGL_DRAW); - if ((EGLDisplay )myEglDisplay == EGL_NO_DISPLAY - || (EGLContext )myEglContext == EGL_NO_CONTEXT) + const Handle(OpenGl_Workspace)& aWindow = aWindowIter.ChangeValue(); + const Handle(OpenGl_Context)& aCtx = aWindow->GetGlContext(); + if (aCtx->MakeCurrent() + && aCtxShared.IsNull()) { - Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: no active EGL context to steal!"); - return; + aCtxShared = aCtx; } + } + + if (!aCtxShared.IsNull()) + { + aCtxShared->MakeCurrent(); + } + for (NCollection_DataMap::Iterator aViewIter (myMapOfView); + aViewIter.More(); aViewIter.Next()) + { + const Handle(OpenGl_View)& aView = aViewIter.ChangeValue(); + aView->ReleaseGlResources (aCtxShared); + } + + for (NCollection_DataMap::Iterator aStructIt (myMapOfStructure); + aStructIt.More (); aStructIt.Next()) + { + OpenGl_Structure* aStruct = aStructIt.ChangeValue(); + aStruct->ReleaseGlResources (aCtxShared); + } + myTempText->Release (aCtxShared.operator->()); + myDeviceLostFlag = myDeviceLostFlag || !myMapOfStructure.IsEmpty(); - TCollection_AsciiString anEglInfo = TCollection_AsciiString() - + "EGL info" - + "\n Version: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_VERSION) - + "\n Vendor: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_VENDOR) - + "\n Client APIs: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_CLIENT_APIS) - + "\n Extensions: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_EXTENSIONS); - ::Message::DefaultMessenger()->Send (anEglInfo, Message_Info); - - EGLint aCfgId = 0; - eglQuerySurface((EGLDisplay )myEglDisplay, aEglSurf, EGL_CONFIG_ID, &aCfgId); - const EGLint aConfigAttribs[] = + for (NCollection_DataMap::Iterator aWindowIter (myMapOfWS); + aWindowIter.More(); aWindowIter.Next()) + { + const Handle(OpenGl_Workspace)& aWindow = aWindowIter.ChangeValue(); + const Handle(OpenGl_Context)& aCtx = aWindow->GetGlContext(); + aCtx->forcedRelease(); + } + +#if defined(HAVE_EGL) || defined(__ANDROID__) + if (myIsOwnContext) + { + if (myEglContext != (Aspect_RenderingContext )EGL_NO_CONTEXT) { - EGL_CONFIG_ID, aCfgId, - EGL_NONE - }; + if (eglMakeCurrent ((EGLDisplay )myEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) + { + ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, FAILED to release OpenGL context!", Message_Warning); + } + eglDestroyContext ((EGLDisplay )myEglDisplay, (EGLContext )myEglContext); + } - EGLint aNbConfigs = 0; - if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE) + if (myEglDisplay != (Aspect_Display )EGL_NO_DISPLAY) { - Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL does not provide compatible configurations!"); + if (eglTerminate ((EGLDisplay )myEglDisplay) != EGL_TRUE) + { + ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, EGL, eglTerminate FAILED!", Message_Warning); + } } - return; } + myEglDisplay = (Aspect_Display )EGL_NO_DISPLAY; + myEglContext = (Aspect_RenderingContext )EGL_NO_CONTEXT; + myEglConfig = NULL; +#endif + myIsOwnContext = Standard_False; +} + +// ======================================================================= +// function : InitContext +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_GraphicDriver::InitContext() +{ + ReleaseContext(); +#if defined(HAVE_EGL) || defined(__ANDROID__) + #if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) + if (myDisplayConnection.IsNull()) + { + return Standard_False; + } + Display* aDisplay = myDisplayConnection->GetDisplay(); myEglDisplay = (Aspect_Display )eglGetDisplay (aDisplay); #else myEglDisplay = (Aspect_Display )eglGetDisplay (EGL_DEFAULT_DISPLAY); #endif if ((EGLDisplay )myEglDisplay == EGL_NO_DISPLAY) { - Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: no EGL display!"); - return; + ::Message::DefaultMessenger()->Send ("Error: no EGL display!", Message_Fail); + return Standard_False; } EGLint aVerMajor = 0; EGLint aVerMinor = 0; if (eglInitialize ((EGLDisplay )myEglDisplay, &aVerMajor, &aVerMinor) != EGL_TRUE) { - Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL display is unavailable!"); - return; + ::Message::DefaultMessenger()->Send ("Error: EGL display is unavailable!", Message_Fail); + return Standard_False; } - TCollection_AsciiString anEglInfo = TCollection_AsciiString() - + "EGL info" - + "\n Version: " + aVerMajor + "." + aVerMinor + " (" + eglQueryString ((EGLDisplay )myEglDisplay, EGL_VERSION) - + "\n Vendor: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_VENDOR) - + "\n Client APIs: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_CLIENT_APIS) - + "\n Extensions: " + eglQueryString ((EGLDisplay )myEglDisplay, EGL_EXTENSIONS); - ::Message::DefaultMessenger()->Send (anEglInfo, Message_Info); - - const EGLint aConfigAttribs[] = + EGLint aConfigAttribs[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, @@ -169,25 +227,18 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnectio }; EGLint aNbConfigs = 0; - if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE) - { - Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL does not provide compatible configurations!"); - return; - } - -#if defined(GL_ES_VERSION_2_0) - if (eglBindAPI (EGL_OPENGL_ES_API) != EGL_TRUE) - { - Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL does not provide OpenGL ES client!"); - return; - } -#else - if (eglBindAPI (EGL_OPENGL_API) != EGL_TRUE) + if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE + || myEglConfig == NULL) { - Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL does not provide OpenGL client!"); - return; + eglGetError(); + aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer + if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE + || myEglConfig == NULL) + { + ::Message::DefaultMessenger()->Send ("Error: EGL does not provide compatible configurations!", Message_Fail); + return Standard_False; + } } -#endif #if defined(GL_ES_VERSION_2_0) EGLint anEglCtxAttribs[] = @@ -195,26 +246,65 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnectio EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + if (eglBindAPI (EGL_OPENGL_ES_API) != EGL_TRUE) + { + ::Message::DefaultMessenger()->Send ("Error: EGL does not provide OpenGL ES client!", Message_Fail); + return Standard_False; + } #else EGLint* anEglCtxAttribs = NULL; + if (eglBindAPI (EGL_OPENGL_API) != EGL_TRUE) + { + ::Message::DefaultMessenger()->Send ("Error: EGL does not provide OpenGL client!", Message_Fail); + return Standard_False; + } #endif myEglContext = (Aspect_RenderingContext )eglCreateContext ((EGLDisplay )myEglDisplay, myEglConfig, EGL_NO_CONTEXT, anEglCtxAttribs); if ((EGLContext )myEglContext == EGL_NO_CONTEXT) { - Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL is unable to create OpenGL context!"); - return; + ::Message::DefaultMessenger()->Send ("Error: EGL is unable to create OpenGL context!", Message_Fail); + return Standard_False; } if (eglMakeCurrent ((EGLDisplay )myEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, (EGLContext )myEglContext) != EGL_TRUE) { - Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: EGL is unable bind OpenGL context!"); - return; + ::Message::DefaultMessenger()->Send ("Error: EGL is unable bind OpenGL context!", Message_Fail); + return Standard_False; + } +#endif + myIsOwnContext = Standard_True; + return Standard_True; +} + +#if defined(HAVE_EGL) || defined(__ANDROID__) +// ======================================================================= +// function : InitEglContext +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_GraphicDriver::InitEglContext (Aspect_Display theEglDisplay, + Aspect_RenderingContext theEglContext, + void* theEglConfig) +{ + ReleaseContext(); +#if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) + if (myDisplayConnection.IsNull()) + { + return Standard_False; } -#else - // not yet implemented - (void )theToStealActiveContext; #endif + + if ((EGLDisplay )theEglDisplay == EGL_NO_DISPLAY + || (EGLContext )theEglContext == EGL_NO_CONTEXT + || theEglConfig == NULL) + { + return Standard_False; + } + myEglDisplay = theEglDisplay; + myEglContext = theEglContext; + myEglConfig = theEglConfig; + return Standard_True; } +#endif // ======================================================================= // function : InquireLightLimit diff --git a/src/OpenGl/OpenGl_GraphicDriver.hxx b/src/OpenGl/OpenGl_GraphicDriver.hxx index 4d7b5535b2..3895f64331 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.hxx +++ b/src/OpenGl/OpenGl_GraphicDriver.hxx @@ -95,9 +95,28 @@ public: //! Constructor. //! @param theDisp connection to display, required on Linux but optional on other systems - //! @param theToStealActiveContext option to use OpenGL context currently bound to the thread rather than creating own one, currently implemented only for Android + //! @param theToInitialize perform initialization of default OpenGL context on construction Standard_EXPORT OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnection)& theDisp, - const Standard_Boolean theToStealActiveContext = Standard_False); + const Standard_Boolean theToInitialize = Standard_True); + + //! Destructor. + Standard_EXPORT virtual ~OpenGl_GraphicDriver(); + + //! Release default context. + Standard_EXPORT void ReleaseContext(); + + //! Perform initialization of default OpenGL context. + Standard_EXPORT Standard_Boolean InitContext(); + +#if defined(HAVE_EGL) || defined(__ANDROID__) + //! Initialize default OpenGL context using existing one. + //! @param theEglDisplay EGL connection to the Display + //! @param theEglContext EGL rendering context + //! @param theEglConfig EGL configuration + Standard_EXPORT Standard_Boolean InitEglContext (Aspect_Display theEglDisplay, + Aspect_RenderingContext theEglContext, + void* theEglConfig); +#endif Standard_EXPORT Standard_Integer InquireLightLimit (); Standard_EXPORT Standard_Integer InquireViewLimit (); @@ -334,10 +353,11 @@ public: private: + Standard_Boolean myIsOwnContext; //!< indicates that shared context has been created within OpenGl_GraphicDriver #if defined(HAVE_EGL) || defined(__ANDROID__) - Aspect_Display myEglDisplay; //!< EGL connection to the Display : EGLDisplay - Aspect_RenderingContext myEglContext; //!< EGL rendering context : EGLContext - void* myEglConfig; //!< EGL configuration : EGLConfig + Aspect_Display myEglDisplay; //!< EGL connection to the Display : EGLDisplay + Aspect_RenderingContext myEglContext; //!< EGL rendering context : EGLContext + void* myEglConfig; //!< EGL configuration : EGLConfig #endif Handle(OpenGl_Caps) myCaps; diff --git a/src/OpenGl/OpenGl_GraphicDriver_7.cxx b/src/OpenGl/OpenGl_GraphicDriver_7.cxx index 12ca8a95e0..ab44eb4ba5 100644 --- a/src/OpenGl/OpenGl_GraphicDriver_7.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_7.cxx @@ -492,13 +492,25 @@ void OpenGl_GraphicDriver::InvalidateBVHData (Graphic3d_CView& theCView, const S Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView) { - if (myMapOfView.IsBound (theCView.ViewId) - || myMapOfWS .IsBound (theCView.WsId)) + Handle(OpenGl_Context) aShareCtx = GetSharedContext(); + if (myMapOfView.IsBound (theCView.ViewId)) { - return Standard_False; + OpenGl_CView* aCView = (OpenGl_CView* )theCView.ptrView; + if (!myMapOfWS.IsBound (theCView.WsId) + || aCView == NULL) + { + return Standard_False; + } + + Handle(OpenGl_Workspace) aWS = new OpenGl_Workspace (this, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx); + aCView->WS = aWS; + aWS->SetActiveView (aCView->View); + + myMapOfWS.UnBind (theCView.WsId); + myMapOfWS.Bind (theCView.WsId, aWS); + return Standard_True; } - Handle(OpenGl_Context) aShareCtx = GetSharedContext(); Handle(OpenGl_Workspace) aWS = new OpenGl_Workspace (this, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx); Handle(OpenGl_View) aView = new OpenGl_View (theCView.Context, &myStateCounter); myMapOfWS .Bind (theCView.WsId, aWS); @@ -508,6 +520,7 @@ Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView) aCView->View = aView; aCView->WS = aWS; theCView.ptrView = aCView; + aWS->SetActiveView (aCView->View); return Standard_True; } diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx old mode 100755 new mode 100644 index c0ce0eba42..7146cd3a12 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -216,6 +216,20 @@ OpenGl_ShaderManager::~OpenGl_ShaderManager() myProgramList.Clear(); } +// ======================================================================= +// function : clear +// purpose : +// ======================================================================= +void OpenGl_ShaderManager::clear() +{ + myProgramList.Clear(); + myLightPrograms.Nullify(); + myFlatPrograms = OpenGl_SetOfShaderPrograms(); + myMapOfLightPrograms.Clear(); + myFontProgram.Nullify(); + switchLightPrograms(); +} + // ======================================================================= // function : Create // purpose : Creates new shader program @@ -996,7 +1010,7 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro PushMaterialState (theProgram); PushWorldViewState (theProgram); PushModelWorldState (theProgram); - PushProjectionState (theProgram); + PushProjectionState (theProgram); PushLightSourceState (theProgram); } diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx old mode 100755 new mode 100644 index 6e637688f8..5a5e10dd75 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -52,6 +52,9 @@ public: //! Releases resources of shader manager. Standard_EXPORT virtual ~OpenGl_ShaderManager(); + //! Release all resources. + Standard_EXPORT void clear(); + //! Creates new shader program or re-use shared instance. //! @param theProxy [IN] program definition //! @param theShareKey [OUT] sharing key @@ -222,7 +225,7 @@ public: Standard_EXPORT const OpenGl_MaterialState* MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const; public: - + //! Pushes current state of OCCT graphics parameters to specified program. Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const; diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index bf715d8790..f4d485c1fc 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -337,8 +337,8 @@ Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture() glDisable (GL_POINT_SPRITE); } } - #endif glDisable (GL_TEXTURE_2D); + #endif break; } default: break; @@ -562,8 +562,8 @@ void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& glEnable (GL_TEXTURE_GEN_S); glEnable (GL_TEXTURE_GEN_T); } - #endif glEnable (GL_TEXTURE_2D); + #endif break; } default: break; diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx index 189a6e10a7..9eb2e8d5c9 100644 --- a/src/V3d/V3d_View.cxx +++ b/src/V3d/V3d_View.cxx @@ -94,9 +94,6 @@ To solve the problem (for lack of a better solution) I make 2 passes. #define BUC60952 //GG Enable to rotate around the view axis // and the required view point -#define RIC120302 //GG Add a NEW SetWindow method which enable -// to connect a graphic widget and context to OGL. - #define IMP260302 //GG To avoid conflicting in Window destructor // nullify this handle in Remove method @@ -333,14 +330,8 @@ void V3d_View::SetMagnify(const Handle(Aspect_Window)& TheWindow, //============================================================================= void V3d_View::SetWindow(const Handle(Aspect_Window)& TheWindow) { - Standard_MultiplyDefined_Raise_if( MyView->IsDefined(), - "V3d_View::SetWindow, window of view already defined"); - MyView->SetWindow(TheWindow) ; - // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before - // calling Redraw(). Otherwise it is impossible to call certain methods of - // V3d_View like Convert() inside the context of Redraw(), - // particularly in class NIS_View. + // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw() MyWindow = TheWindow; // SetWindow carries out SetRatio and modifies MyView->SetContext(MyViewContext) ; @@ -358,13 +349,7 @@ void V3d_View::SetWindow(const Handle(Aspect_Window)& aWindow, const Aspect_GraphicCallbackProc& aDisplayCB, const Standard_Address aClientData) { - Standard_MultiplyDefined_Raise_if( MyView->IsDefined(), - "V3d_View::SetWindow, " - "window of view already defined"); - // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before - // calling Redraw(). Otherwise it is impossible to call certain methods of - // V3d_View like Convert() inside the context of Redraw(), - // particularly in class NIS_View. + // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw() MyWindow = aWindow; MyView->SetWindow(aWindow, aContext, aDisplayCB, aClientData) ; MyView->SetContext(MyViewContext) ; diff --git a/src/Visual3d/Visual3d_View.cxx b/src/Visual3d/Visual3d_View.cxx index 8d2717d9ca..d7b6c1dd65 100644 --- a/src/Visual3d/Visual3d_View.cxx +++ b/src/Visual3d/Visual3d_View.cxx @@ -85,10 +85,6 @@ void Visual3d_View::SetWindow (const Handle(Aspect_Window)& theWindow, { return; } - else if (IsDefined()) - { - Visual3d_ViewDefinitionError::Raise ("Window already defined"); - } MyCView.GContext = theContext; MyCView.GDisplayCB = theDisplayCB; @@ -106,10 +102,6 @@ void Visual3d_View::SetWindow (const Handle(Aspect_Window)& theWindow) { return; } - else if (IsDefined()) - { - Visual3d_ViewDefinitionError::Raise ("Window already defined"); - } MyWindow = theWindow; MyCView.WsId = MyCView.ViewId; @@ -159,6 +151,14 @@ void Visual3d_View::SetWindow (const Handle(Aspect_Window)& theWindow) // In fact, association view-window is done, but the // display is produced only if the view is activated (Activate). SetRatio(); + + // invalidate camera + const Handle(Graphic3d_Camera)& aCamera = MyCView.Context.Camera; + if (!aCamera.IsNull()) + { + aCamera->InvalidateProjection(); + aCamera->InvalidateOrientation(); + } } // ======================================================================= -- 2.20.1