From 62e1beed962f76420131e79de4ffa8748e70e50d Mon Sep 17 00:00:00 2001 From: kgv Date: Mon, 20 Jul 2015 11:08:12 +0300 Subject: [PATCH] 0026392: Visualization, TKD3DHost - provide straight-forward base for integration of TKOpenGl viewer into D3D-based application D3DHost_GraphicDriver - new graphic driver providing D3D host for OpenGL workspace. WNT_Window - handle virtual dimensions within virtual window. OpenGl_FrameBuffer::Init() - add protection against 0 dimensions. V3d_View::IsInvalidated() - add method to check view cache validation state. ViewerTest::ViewerInit() - create virtual window without decorations on Windows. --- adm/UDLIST | 2 + samples/CSharp/OCCTProxy_D3D/BridgeFBO.cxx | 152 -------- samples/CSharp/OCCTProxy_D3D/BridgeFBO.hxx | 53 --- .../CSharp/OCCTProxy_D3D/Direct3DProxy.cpp | 278 ------------- samples/CSharp/OCCTProxy_D3D/OCCTProxyD3D.cpp | 122 ++---- .../CSharp/OCCTProxy_D3D/OCCTProxy_D3D.vcproj | 8 - .../OCCTProxy_D3D/OCCTProxy_D3D.vcxproj | 5 - samples/CSharp/WPF_D3D/D3DViewer.cs | 46 +-- samples/CSharp/WPF_D3D/MainWindow.xaml.cs | 2 +- samples/CSharp/WPF_D3D/OCCViewer.cs | 4 +- samples/CSharp/msvc_D3D.bat | 14 +- src/D3DHost/D3DHost_FrameBuffer.cxx | 286 ++++++++++++++ src/D3DHost/D3DHost_FrameBuffer.hxx | 83 ++++ src/D3DHost/D3DHost_GraphicDriver.cxx | 104 +++++ src/D3DHost/D3DHost_GraphicDriver.hxx | 49 +++ src/D3DHost/D3DHost_Workspace.cxx | 364 ++++++++++++++++++ src/D3DHost/D3DHost_Workspace.hxx | 110 ++++++ src/D3DHost/FILES | 6 + src/Graphic3d/Graphic3d_GraphicDriver.hxx | 5 +- src/OS/Visualization.tcl | 8 + src/OpenGl/OpenGl_FrameBuffer.cxx | 30 +- src/OpenGl/OpenGl_GraphicDriver.cxx | 9 + src/OpenGl/OpenGl_GraphicDriver.hxx | 8 +- src/OpenGl/OpenGl_GraphicDriver_7.cxx | 9 +- src/OpenGl/OpenGl_View.hxx | 6 +- src/OpenGl/OpenGl_Window.cxx | 5 +- src/OpenGl/OpenGl_Window.hxx | 28 +- src/OpenGl/OpenGl_Workspace.cxx | 144 ++++--- src/OpenGl/OpenGl_Workspace.hxx | 51 ++- src/TKD3DHost/EXTERNLIB | 8 + src/TKD3DHost/FILES | 2 + src/TKD3DHost/PACKAGES | 1 + src/V3d/V3d_View.cxx | 10 + src/V3d/V3d_View.hxx | 5 +- src/ViewerTest/ViewerTest_ViewerCommands.cxx | 2 +- src/Visual3d/Visual3d_View.cxx | 9 + src/Visual3d/Visual3d_View.hxx | 5 +- src/WNT/WNT_Window.cxx | 32 +- 38 files changed, 1316 insertions(+), 749 deletions(-) delete mode 100644 samples/CSharp/OCCTProxy_D3D/BridgeFBO.cxx delete mode 100644 samples/CSharp/OCCTProxy_D3D/BridgeFBO.hxx delete mode 100644 samples/CSharp/OCCTProxy_D3D/Direct3DProxy.cpp create mode 100644 src/D3DHost/D3DHost_FrameBuffer.cxx create mode 100644 src/D3DHost/D3DHost_FrameBuffer.hxx create mode 100644 src/D3DHost/D3DHost_GraphicDriver.cxx create mode 100644 src/D3DHost/D3DHost_GraphicDriver.hxx create mode 100644 src/D3DHost/D3DHost_Workspace.cxx create mode 100644 src/D3DHost/D3DHost_Workspace.hxx create mode 100644 src/D3DHost/FILES create mode 100644 src/TKD3DHost/EXTERNLIB create mode 100644 src/TKD3DHost/FILES create mode 100644 src/TKD3DHost/PACKAGES diff --git a/adm/UDLIST b/adm/UDLIST index 31d9078946..2a97d10b02 100644 --- a/adm/UDLIST +++ b/adm/UDLIST @@ -202,6 +202,7 @@ n Graphic3d n Image n MeshVS n OpenGl +n D3DHost n Prs3d n PrsMgr n Select3D @@ -220,6 +221,7 @@ r Textures r Shaders t TKMeshVS t TKOpenGl +t TKD3DHost t TKService t TKV3d t TKVoxel diff --git a/samples/CSharp/OCCTProxy_D3D/BridgeFBO.cxx b/samples/CSharp/OCCTProxy_D3D/BridgeFBO.cxx deleted file mode 100644 index 12fa944964..0000000000 --- a/samples/CSharp/OCCTProxy_D3D/BridgeFBO.cxx +++ /dev/null @@ -1,152 +0,0 @@ -#include "BridgeFBO.hxx" - -#include - -#include - -#include - -// list of required libraries -#pragma comment(lib, "TKOpenGl.lib") -#pragma comment(lib, "opengl32.lib") - -// ======================================================================= -// function : Init -// purpose : -// ======================================================================= -Standard_Boolean BridgeFBO::Init (const Handle(OpenGl_Context)& theGlContext, - void* theD3DDevice) -{ - const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11; - if (aFuncs->wglDXOpenDeviceNV == NULL) - { - return Standard_False; - } - - myGlD3DHandle = aFuncs->wglDXOpenDeviceNV (theD3DDevice); - if (myGlD3DHandle == NULL) - { - std::cerr << "Could not create the GL <-> DirectX Interop" << std::endl; - return Standard_False; - } - - theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId); - return Standard_True; -} - -// ======================================================================= -// function : Release -// purpose : -// ======================================================================= -void BridgeFBO::Release (OpenGl_Context* theGlContext) -{ - if (myGlD3DHandle != NULL) - { - const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11; - if (myGlD3DSharedColorHandle != NULL) - { - aFuncs->wglDXUnregisterObjectNV (myGlD3DHandle, myGlD3DSharedColorHandle); - myGlD3DSharedColorHandle = NULL; - } - - aFuncs->wglDXCloseDeviceNV (myGlD3DHandle); - myGlD3DHandle = NULL; - } - - OpenGl_FrameBuffer::Release (theGlContext); -} - -// ======================================================================= -// function : RegisterD3DColorBuffer -// purpose : -// ======================================================================= -Standard_Boolean BridgeFBO::RegisterD3DColorBuffer (const Handle(OpenGl_Context)& theGlContext, - void* theD3DBuffer, - void* theBufferShare) -{ - const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11; - if (myGlD3DSharedColorHandle != NULL) - { - if (!aFuncs->wglDXUnregisterObjectNV (myGlD3DHandle, myGlD3DSharedColorHandle)) - { - return Standard_False; - } - myGlD3DSharedColorHandle = NULL; - } - - if (!aFuncs->wglDXSetResourceShareHandleNV (theD3DBuffer, theBufferShare)) - { - return Standard_False; - } - - myColorTexture->Release (theGlContext.operator->()); - myColorTexture->Create (theGlContext); - - myGlD3DSharedColorHandle = aFuncs->wglDXRegisterObjectNV (myGlD3DHandle, - theD3DBuffer, myColorTexture->TextureId(), GL_TEXTURE_2D, WGL_ACCESS_WRITE_DISCARD_NV); - - if (myGlD3DSharedColorHandle == NULL) - { - std::cerr << "Could not register color buffer" << std::endl; - return Standard_False; - } - - return Standard_True; -} - -// ======================================================================= -// function : Resize -// purpose : -// ======================================================================= -void BridgeFBO::Resize (const Handle(OpenGl_Context)& theGlContext, - int theSizeX, - int theSizeY) -{ - myVPSizeX = theSizeX; - myVPSizeY = theSizeY; - - myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8, - GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, - myVPSizeX, myVPSizeY, Graphic3d_TOT_2D); -} - -// ======================================================================= -// function : BindBuffer -// purpose : -// ======================================================================= -void BridgeFBO::BindBuffer (const Handle(OpenGl_Context)& theGlContext) -{ - if (myGlD3DSharedColorHandle != NULL) - { - // Lock for OpenGL - const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11; - aFuncs->wglDXLockObjectsNV (myGlD3DHandle, 1, &myGlD3DSharedColorHandle); - } - - OpenGl_FrameBuffer::BindBuffer (theGlContext); - theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, myColorTexture->TextureId(), 0); - theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, - GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0); - if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - { - std::cerr << "Invalid FBO can not be bound!\n"; - Release (theGlContext.operator->()); - } -} - -// ======================================================================= -// function : UnbindBuffer -// purpose : -// ======================================================================= -void BridgeFBO::UnbindBuffer (const Handle(OpenGl_Context)& theGlContext) -{ - // Unbind the frame buffer - OpenGl_FrameBuffer::UnbindBuffer (theGlContext); - if (myGlD3DSharedColorHandle != NULL) - { - // Unlock for Direct3D - const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11; - aFuncs->wglDXUnlockObjectsNV (myGlD3DHandle, 1, &myGlD3DSharedColorHandle); - } -} diff --git a/samples/CSharp/OCCTProxy_D3D/BridgeFBO.hxx b/samples/CSharp/OCCTProxy_D3D/BridgeFBO.hxx deleted file mode 100644 index 9860015179..0000000000 --- a/samples/CSharp/OCCTProxy_D3D/BridgeFBO.hxx +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef BRIDGE_FBO_HEADER -#define BRIDGE_FBO_HEADER - -#include -#include - -//! Implements bridge FBO for direct rendering to Direct3D surfaces. -class BridgeFBO : public OpenGl_FrameBuffer -{ -public: - - //! Creates new bridge FBO. - BridgeFBO() : OpenGl_FrameBuffer() - { - // - } - - //! Releases resources of bridge FBO. - ~BridgeFBO() - { - Release (NULL); - } - - //! Releases resources of bridge FBO. - virtual void Release (OpenGl_Context* theGlContext); - - //! Initializes OpenGL FBO for Direct3D interoperability. - Standard_Boolean Init (const Handle(OpenGl_Context)& theGlContext, - void* theD3DDevice); - - //! Binds Direcr3D color buffer to OpenGL texture. - Standard_Boolean RegisterD3DColorBuffer (const Handle(OpenGl_Context)& theGlContext, - void* theD3DBuffer, - void* theBufferShare); - - //! Locks Direct3D objects for OpenGL drawing. - virtual void BindBuffer (const Handle(OpenGl_Context)& theGlContext); - - //! Unlocks Direct3D objects after OpenGL drawing. - virtual void UnbindBuffer (const Handle(OpenGl_Context)& theGlContext); - - //! Resizes buffer according to Direct3D surfaces. - void Resize (const Handle(OpenGl_Context)& theGlContext, - int theSizeX, - int theSizeY); - -private: - - HANDLE myGlD3DHandle; - HANDLE myGlD3DSharedColorHandle; -}; - -#endif \ No newline at end of file diff --git a/samples/CSharp/OCCTProxy_D3D/Direct3DProxy.cpp b/samples/CSharp/OCCTProxy_D3D/Direct3DProxy.cpp deleted file mode 100644 index 407d93f7ab..0000000000 --- a/samples/CSharp/OCCTProxy_D3D/Direct3DProxy.cpp +++ /dev/null @@ -1,278 +0,0 @@ -#include -#include -#include - -using namespace System::Runtime::InteropServices; - -typedef HRESULT (WINAPI *DIRECT3DCREATE9EX)(UINT SDKVersion, IDirect3D9Ex**); - -LRESULT WINAPI MsgProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - return DefWindowProcW (hWnd, msg, wParam, lParam); -} - -WNDCLASSEXW THE_WNDCLASS_D3D = -{ - sizeof (WNDCLASSEXW), - CS_CLASSDC, MsgProc, NULL, NULL, - GetModuleHandle (NULL), - NULL, NULL, NULL, NULL, L"D3D", NULL -}; - -// ======================================================================= -// function : GetVertexProcessingCaps -// purpose : -// ======================================================================= -DWORD GetVertexProcessingCaps (LPDIRECT3D9 theD3D) -{ - D3DCAPS9 aCaps; - return !SUCCEEDED (theD3D->GetDeviceCaps (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &aCaps)) - || !(aCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) - ? D3DCREATE_SOFTWARE_VERTEXPROCESSING - : D3DCREATE_HARDWARE_VERTEXPROCESSING; -} - -//! Encapsulates state of Direct3D renderer. -class D3DRender -{ -public: - - D3DRender (int theSizeX = 512, - int theSizeY = 512) - : D3D (NULL), - D3DEx (NULL), - D3DDevice (NULL), - D3DDeviceEx (NULL), - D3DColorSurf (NULL), - D3DColorSurfShare (NULL), - FuncCreate9Ex (NULL), - WinSizeX (theSizeX), - WinSizeY (theSizeY) - { - CheckRegisterClass(); - WinHandle = CreateWindowW (L"D3D", L"D3D", - WS_OVERLAPPEDWINDOW, 0, 0, 1, 1, - NULL, NULL, THE_WNDCLASS_D3D.hInstance, NULL); - Init(); - } - - ~D3DRender() - { - // do not release class instance shared between all renderers - //UnregisterClass (NULL, THE_WNDCLASS_D3D.hInstance); - if (D3DDevice != NULL) - { - D3DDevice->Release(); - } - if (D3DDeviceEx != NULL) - { - D3DDeviceEx->Release(); - } - if (D3D != NULL) - { - D3D->Release(); - } - if (D3DEx != NULL) - { - D3DEx->Release(); - } - if (D3DColorSurf != NULL) - { - D3DColorSurf->Release(); - D3DColorSurfShare = NULL; - } - } - - //! Creates Direct3D render target. - bool CreateRenderTarget() - { - if (!SetWindowPos (WinHandle, 0, 0, 0, WinSizeX, WinSizeY, 0)) - { - return false; - } - - if (D3DColorSurf != NULL) - { - D3DColorSurf->Release(); - D3DColorSurfShare = NULL; - } - - // Note: Render target surface should be lockable on - // Windows XP and non-lockable on Windows Vista or higher - if (FAILED (D3DDevice->CreateRenderTarget (WinSizeX, WinSizeY, - D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FuncCreate9Ex != NULL, - &D3DColorSurf, FuncCreate9Ex == NULL ? NULL : &D3DColorSurfShare))) - { - return false; - } - - D3DDevice->SetRenderTarget (0, D3DColorSurf); - return true; - } - -private: - - void Init() - { - // Vista requires the D3D "Ex" functions for optimal performance. - // The Ex functions are only supported with WDDM drivers, so they will not be available on XP. - HMODULE aD3D9 = GetModuleHandleW (L"d3d9"); - FuncCreate9Ex = (DIRECT3DCREATE9EX )GetProcAddress (aD3D9, "Direct3DCreate9Ex"); - - // Set up the structure used to create the D3DDevice - D3DPRESENT_PARAMETERS aParams; - ZeroMemory (&aParams, sizeof(aParams)); - aParams.Windowed = TRUE; - aParams.BackBufferHeight = 1; - aParams.BackBufferWidth = 1; - aParams.SwapEffect = D3DSWAPEFFECT_DISCARD; - aParams.BackBufferFormat = D3DFMT_X8R8G8B8; - (FuncCreate9Ex != NULL) ? InitializeD3DEx (aParams) : InitializeD3D (aParams); - } - - bool InitializeD3D (D3DPRESENT_PARAMETERS theParams) - { - D3D = Direct3DCreate9 (D3D_SDK_VERSION); - if (D3D == NULL) - return false; - - DWORD aVertProcessCaps = GetVertexProcessingCaps (D3D); - HRESULT aResult = D3D->CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, WinHandle, - aVertProcessCaps | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, - &theParams, &D3DDevice); - return SUCCEEDED (aResult); - } - - bool InitializeD3DEx (D3DPRESENT_PARAMETERS theParams) - { - if (FAILED (FuncCreate9Ex (D3D_SDK_VERSION, &D3DEx)) - || FAILED (D3DEx->QueryInterface (__uuidof (IDirect3D9), reinterpret_cast (&D3D)))) - { - return false; - } - - DWORD aVertProcessCaps = GetVertexProcessingCaps (D3D); - if (FAILED (D3DEx->CreateDeviceEx (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, WinHandle, - aVertProcessCaps | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, - &theParams, NULL, &D3DDeviceEx))) - return false; - - return SUCCEEDED (D3DDeviceEx->QueryInterface (__uuidof (IDirect3DDevice9), reinterpret_cast (&D3DDevice))); - } - - static void CheckRegisterClass() - { - static bool isRegistered = false; - if (!isRegistered) - { - RegisterClassExW (&THE_WNDCLASS_D3D); - isRegistered = true; - } - } - -public: - - LPDIRECT3D9 D3D; - LPDIRECT3D9EX D3DEx; - LPDIRECT3DDEVICE9 D3DDevice; - LPDIRECT3DDEVICE9EX D3DDeviceEx; - - LPDIRECT3DSURFACE9 D3DColorSurf; - HANDLE D3DColorSurfShare; - - DIRECT3DCREATE9EX FuncCreate9Ex; - - HWND WinHandle; - INT WinSizeX; - INT WinSizeY; - -}; - -public ref struct WndSize -{ -public: - - WndSize(int theSizeX, int theSizeY) - { - mySize = new SIZE(); - mySize->cx = theSizeX; - mySize->cy = theSizeY; - } - - ~WndSize() - { - delete mySize; - } - - property int cx - { - int get() { return mySize->cx; } - } - - property int cy - { - int get() { return mySize->cy; } - } - - LPSIZE GetPointer() - { - return mySize; - } - -private: - - LPSIZE mySize; -}; - -public ref class Direct3DProxy -{ -public : - - Direct3DProxy() - { - // - } - - // ======================================================================= - // function : InitializeScene - // purpose : - // ======================================================================= - static System::IntPtr InitRender ([Out] System::IntPtr% theWinHandle, - [Out] System::IntPtr% theD3DDevice) - { - D3DRender* aRender = new D3DRender(); - theWinHandle = System::IntPtr(aRender->WinHandle); - theD3DDevice = System::IntPtr(aRender->D3DDevice); - - return System::IntPtr(aRender); - } - - // ======================================================================= - // function : ResizeWindow - // purpose : - // ======================================================================= - static void ResizeWindow ([In] System::IntPtr% theRender, - [In] WndSize^% theWndSize, - [Out] System::IntPtr% theColorSurf, - [Out] System::IntPtr% theColorSurfShare) - { - D3DRender* aRender = reinterpret_cast (theRender.ToPointer()); - LPSIZE aSize = theWndSize->GetPointer(); - aRender->WinSizeX = aSize->cx; - aRender->WinSizeY = aSize->cy; - aRender->CreateRenderTarget(); - - theColorSurf = System::IntPtr(aRender->D3DColorSurf); - theColorSurfShare = System::IntPtr(aRender->D3DColorSurfShare); - } - - // ======================================================================= - // function : ReleaseRender - // purpose : - // ======================================================================= - static void ReleaseRender ([In] System::IntPtr% theRender) - { - D3DRender* aRender = reinterpret_cast (theRender.ToPointer()); - delete aRender; - } -}; \ No newline at end of file diff --git a/samples/CSharp/OCCTProxy_D3D/OCCTProxyD3D.cpp b/samples/CSharp/OCCTProxy_D3D/OCCTProxyD3D.cpp index aeb5f7c8bc..6ca5c9ef01 100644 --- a/samples/CSharp/OCCTProxy_D3D/OCCTProxyD3D.cpp +++ b/samples/CSharp/OCCTProxy_D3D/OCCTProxyD3D.cpp @@ -1,16 +1,15 @@ -#include "BridgeFBO.hxx" +#include // include required OCCT headers #include #include //for OCC graphic -#include #include +#include #include #include #include -#include -#include +#include //for object display #include #include @@ -47,11 +46,14 @@ #pragma comment(lib, "TKService.lib") #pragma comment(lib, "TKV3d.lib") #pragma comment(lib, "TKOpenGl.lib") +#pragma comment(lib, "TKD3dHost.lib") #pragma comment(lib, "TKIGES.lib") #pragma comment(lib, "TKSTEP.lib") #pragma comment(lib, "TKStl.lib") #pragma comment(lib, "TKVrml.lib") +#pragma comment(lib, "D3D9.lib") + /// /// Proxy class encapsulating calls to OCCT C++ classes within /// C++/CLI class visible from .Net (CSharp) @@ -60,10 +62,7 @@ public ref class OCCTProxyD3D { public: - OCCTProxyD3D() : myBridgeFBO (NULL) - { - // - } + OCCTProxyD3D() {} // ============================================ // Viewer functionality @@ -73,9 +72,10 @@ public: ///Initialize a viewer /// /// System.IntPtr that contains the window handle (HWND) of the control - bool InitViewer (System::IntPtr theWnd) + bool InitViewer() { - myGraphicDriver() = new OpenGl_GraphicDriver (Handle(Aspect_DisplayConnection)()); + myGraphicDriver() = new D3DHost_GraphicDriver(); + myGraphicDriver()->ChangeOptions().buffersNoSwap = true; //myGraphicDriver()->ChangeOptions().contextDebug = true; TCollection_ExtendedString a3DName ("Visu3D"); @@ -87,76 +87,26 @@ public: myViewer()->SetDefaultLights(); myViewer()->SetLightOn(); myView() = myViewer()->CreateView(); - Handle(WNT_Window) aWNTWindow = new WNT_Window (reinterpret_cast (theWnd.ToPointer())); + + static Handle(WNT_WClass) aWClass = new WNT_WClass ("OCC_Viewer", NULL, CS_OWNDC); + Handle(WNT_Window) aWNTWindow = new WNT_Window ("OCC_Viewer", aWClass, WS_POPUP, 64, 64, 64, 64); + aWNTWindow->SetVirtual (Standard_True); myView()->SetWindow(aWNTWindow); - if (!aWNTWindow->IsMapped()) - { - aWNTWindow->Map(); - } myAISContext() = new AIS_InteractiveContext (myViewer()); myAISContext()->UpdateCurrentViewer(); myView()->MustBeResized(); return true; } - /// Initializes OCCT viewer for OpenGL-Direct3D interoperability. - bool InitViewer (System::IntPtr theHWND, - System::IntPtr theD3DDevice) - { - if (!InitViewer (theHWND)) - { - return false; - } - - Graphic3d_CView* aCView = reinterpret_cast (myView()->View()->CView()); - OpenGl_CView* aCViewGl = reinterpret_cast (aCView->ptrView); - Handle(OpenGl_Context) aGlContext = aCViewGl->WS->GetGlContext(); - if (aGlContext.IsNull()) - { - return false; - } - if (!aGlContext->IsCurrent()) - { - aGlContext->MakeCurrent(); - } - - myBridgeFBO = new BridgeFBO(); - if (!myBridgeFBO->Init (aGlContext, theD3DDevice.ToPointer())) - { - return false; - } - - aCView->ptrFBO = myBridgeFBO; - return true; - } - /// Resizes custom FBO for Direct3D output. - bool ResizeBridgeFBO (int theWinSizeX, - int theWinSizeY, - System::IntPtr theColorSurf, - System::IntPtr theColorSurfShare) + System::IntPtr ResizeBridgeFBO (int theWinSizeX, + int theWinSizeY) { - if (myBridgeFBO == NULL) - { - return false; - } - - OpenGl_CView* aCView = reinterpret_cast (reinterpret_cast (myView()->View()->CView())->ptrView); - Handle(OpenGl_Context) aGlContext = aCView->WS->GetGlContext(); - if (aGlContext.IsNull() - || !aGlContext->MakeCurrent()) - { - return false; - } - - myBridgeFBO->Resize (aGlContext, theWinSizeX, theWinSizeY); - if (!myBridgeFBO->RegisterD3DColorBuffer (aGlContext, theColorSurf.ToPointer(), theColorSurfShare.ToPointer())) - { - return false; - } - - myView()->Camera()->SetAspect (Standard_Real (theWinSizeX) / Standard_Real (theWinSizeY)); - return true; + Handle(WNT_Window) aWNTWindow = Handle(WNT_Window)::DownCast (myView()->Window()); + aWNTWindow->SetPos (0, 0, theWinSizeX, theWinSizeY); + myView()->MustBeResized(); + myView()->Invalidate(); + return System::IntPtr(myGraphicDriver()->D3dColorSurface (myView()->View())); } /// @@ -729,33 +679,6 @@ public: return -1; } - /// - ///Create new view - /// - /// System.IntPtr that contains the window handle (HWND) of the control - void CreateNewView (System::IntPtr theWnd) - { - if (myAISContext().IsNull()) - { - return; - } - - myView() = myAISContext()->CurrentViewer()->CreateView(); - if (myGraphicDriver().IsNull()) - { - myGraphicDriver() = new OpenGl_GraphicDriver (Handle(Aspect_DisplayConnection)()); - //myGraphicDriver()->ChangeOptions().contextDebug = true; - } - Handle(WNT_Window) aWNTWindow = new WNT_Window (reinterpret_cast (theWnd.ToPointer())); - myView()->SetWindow (aWNTWindow); - Standard_Integer aWidth = 100, aHeight = 100; - aWNTWindow->Size (aWidth, aHeight); - if (!aWNTWindow->IsMapped()) - { - aWNTWindow->Map(); - } - } - /// ///Set AISContext /// @@ -1047,7 +970,6 @@ private: NCollection_Haft myViewer; NCollection_Haft myView; NCollection_Haft myAISContext; - NCollection_Haft myGraphicDriver; - BridgeFBO* myBridgeFBO; //!< Provides output to Direct3D buffers + NCollection_Haft myGraphicDriver; }; diff --git a/samples/CSharp/OCCTProxy_D3D/OCCTProxy_D3D.vcproj b/samples/CSharp/OCCTProxy_D3D/OCCTProxy_D3D.vcproj index db2b50a78d..c4dcc5ebeb 100644 --- a/samples/CSharp/OCCTProxy_D3D/OCCTProxy_D3D.vcproj +++ b/samples/CSharp/OCCTProxy_D3D/OCCTProxy_D3D.vcproj @@ -348,10 +348,6 @@ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > - - @@ -362,10 +358,6 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > - - - - - - - diff --git a/samples/CSharp/WPF_D3D/D3DViewer.cs b/samples/CSharp/WPF_D3D/D3DViewer.cs index 4eb26351ef..a888079c21 100644 --- a/samples/CSharp/WPF_D3D/D3DViewer.cs +++ b/samples/CSharp/WPF_D3D/D3DViewer.cs @@ -11,9 +11,6 @@ namespace IE_WPF_D3D /// class D3DViewer { - /// Direct3D renderer. - private IntPtr myD3DRender; - /// Direct3D output image. private D3DImage myD3DImage = new D3DImage (); @@ -60,24 +57,14 @@ namespace IE_WPF_D3D if (myD3DImage.IsFrontBufferAvailable) { - IntPtr aWinHandle; - IntPtr aD3DDevice; - - // Initialize Direct3D device and render target - myD3DRender = Direct3DProxy.InitRender(out aWinHandle, out aD3DDevice); - Viewer = new OCCViewer(); - if (!Viewer.InitInterop (aWinHandle, aD3DDevice)) + if (!Viewer.InitViewer()) { MessageBox.Show ("Failed to initialize OpenGL-Direct3D interoperability!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); myIsFailed = true; - - if (myD3DRender != IntPtr.Zero) - Direct3DProxy.ReleaseRender(ref myD3DRender); - return; } @@ -87,32 +74,28 @@ namespace IE_WPF_D3D } } - /// Initializes Direct3D-OCCT rendering. + /// Releases Direct3D-OCCT rendering. public void StopRenderingScene () { // This method is called when WPF loses its Direct3D device, // so we should just release our custom Direct3D scene CompositionTarget.Rendering -= OnRendering; - - if (myD3DRender != IntPtr.Zero) - Direct3DProxy.ReleaseRender(ref myD3DRender); - myColorSurf = IntPtr.Zero; } - /// Initializes Direct3D-OCCT rendering. + /// Performs Direct3D-OCCT rendering. private void OnRendering (object sender, EventArgs e) { UpdateScene (); } - /// Current size of rendering window. - private WndSize mySize = new WndSize(1, 1); - - /// Initializes Direct3D-OCCT rendering. + /// Performs Direct3D-OCCT rendering. private void UpdateScene () { - if (!myIsFailed && myD3DImage.IsFrontBufferAvailable && myColorSurf != IntPtr.Zero) + if (!myIsFailed + && myD3DImage.IsFrontBufferAvailable + && myColorSurf != IntPtr.Zero + && (myD3DImage.PixelWidth != 0 && myD3DImage.PixelHeight != 0)) { myD3DImage.Lock (); { @@ -120,7 +103,7 @@ namespace IE_WPF_D3D Viewer.View.RedrawView (); // Invalidate the updated region of the D3DImage - myD3DImage.AddDirtyRect(new Int32Rect(0, 0, mySize.cx, mySize.cy)); + myD3DImage.AddDirtyRect(new Int32Rect(0, 0, myD3DImage.PixelWidth, myD3DImage.PixelHeight)); } myD3DImage.Unlock (); } @@ -129,23 +112,16 @@ namespace IE_WPF_D3D /// Resizes Direct3D surfaces and OpenGL FBO. public void Resize (int theSizeX, int theSizeY) { - mySize = new WndSize(theSizeX, theSizeY); - if (!myIsFailed && myD3DImage.IsFrontBufferAvailable) { - IntPtr aColorSurfShare; - - // Initialize Direct3D device and render target - Direct3DProxy.ResizeWindow(ref myD3DRender, ref mySize, out myColorSurf, out aColorSurfShare); - // Set the back buffer for Direct3D WPF image myD3DImage.Lock (); { + myD3DImage.SetBackBuffer (D3DResourceType.IDirect3DSurface9, IntPtr.Zero); + myColorSurf = Viewer.View.ResizeBridgeFBO (theSizeX, theSizeY); myD3DImage.SetBackBuffer (D3DResourceType.IDirect3DSurface9, myColorSurf); } myD3DImage.Unlock (); - - Viewer.View.ResizeBridgeFBO(mySize.cx, mySize.cy, myColorSurf, aColorSurfShare); } } diff --git a/samples/CSharp/WPF_D3D/MainWindow.xaml.cs b/samples/CSharp/WPF_D3D/MainWindow.xaml.cs index 913241709c..fab4967e0d 100644 --- a/samples/CSharp/WPF_D3D/MainWindow.xaml.cs +++ b/samples/CSharp/WPF_D3D/MainWindow.xaml.cs @@ -161,7 +161,7 @@ namespace IE_WPF_D3D ImageBrush anImage = new ImageBrush (aViwer.Image); - anImage.RelativeTransform = new ScaleTransform (1.0, -1.0, 0.5, 0.5); + //anImage.RelativeTransform = new ScaleTransform (1.0, -1.0, 0.5, 0.5); g.Background = anImage; g.MouseMove += new MouseEventHandler (g_MouseMove); diff --git a/samples/CSharp/WPF_D3D/OCCViewer.cs b/samples/CSharp/WPF_D3D/OCCViewer.cs index 07b940198a..64a6917f07 100644 --- a/samples/CSharp/WPF_D3D/OCCViewer.cs +++ b/samples/CSharp/WPF_D3D/OCCViewer.cs @@ -87,9 +87,9 @@ namespace IE_WPF_D3D DegenerateMode = true; } - public bool InitInterop (IntPtr theHWND, IntPtr theD3DDevice) + public bool InitViewer() { - return View.InitViewer (theHWND, theD3DDevice); + return View.InitViewer(); } public void ImportModel (ModelFormat theFormat) diff --git a/samples/CSharp/msvc_D3D.bat b/samples/CSharp/msvc_D3D.bat index 1e7d2a3247..96d6a2cd72 100644 --- a/samples/CSharp/msvc_D3D.bat +++ b/samples/CSharp/msvc_D3D.bat @@ -1,12 +1,18 @@ @echo off +call "%~dp0..\..\env.bat" %1 %2 %3 + if NOT DEFINED DXSDK_DIR ( - echo ERROR: DirectX SDK is required in order to build the sample but it is not found in your system. Please install DirectX SDK and retry. - exit /B + if "%VCVER%" == "vc9" ( + echo ERROR: DirectX SDK is required in order to build the sample but it is not found in your system. Please install DirectX SDK and retry. + exit /B + ) + if "%VCVER%" == "vc10" ( + echo ERROR: DirectX SDK is required in order to build the sample but it is not found in your system. Please install DirectX SDK and retry. + exit /B + ) ) -call "%~dp0..\..\env.bat" %1 %2 %3 - if ["%CASDEB%"] == [""] ( call "%~dp0..\..\msvc.bat" %VCVER% win%ARCH% Release %~dp0\CSharp_D3D.sln ) else ( diff --git a/src/D3DHost/D3DHost_FrameBuffer.cxx b/src/D3DHost/D3DHost_FrameBuffer.cxx new file mode 100644 index 0000000000..41415c8c1b --- /dev/null +++ b/src/D3DHost/D3DHost_FrameBuffer.cxx @@ -0,0 +1,286 @@ +// Created on: 2015-06-10 +// Created by: Kirill Gavrilov +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include + +#include +#include +#include +#include + +// ======================================================================= +// function : D3DHost_FrameBuffer +// purpose : +// ======================================================================= +D3DHost_FrameBuffer::D3DHost_FrameBuffer() +: OpenGl_FrameBuffer(), + myD3dSurf (NULL), + myD3dSurfShare (NULL), + myGlD3dDevice (NULL), + myGlD3dSurf (NULL) +{ + // +} + +// ======================================================================= +// function : ~D3DHost_FrameBuffer +// purpose : +// ======================================================================= +D3DHost_FrameBuffer::~D3DHost_FrameBuffer() +{ + Release (NULL); +} + +// ======================================================================= +// function : Release +// purpose : +// ======================================================================= +void D3DHost_FrameBuffer::Release (OpenGl_Context* theCtx) +{ + if (myGlD3dDevice != NULL) + { + const OpenGl_GlFunctions* aFuncs = (theCtx != NULL && theCtx->IsValid()) + ? (const OpenGl_GlFunctions* )theCtx->core11 + : NULL; + if (myGlD3dSurf != NULL) + { + if (aFuncs != NULL) + { + aFuncs->wglDXUnregisterObjectNV (myGlD3dDevice, myGlD3dSurf); + } + myGlD3dSurf = NULL; + } + + if (aFuncs != NULL) + { + aFuncs->wglDXCloseDeviceNV (myGlD3dDevice); + } + myGlD3dDevice = NULL; + } + + if (myD3dSurf != NULL) + { + myD3dSurf->Release(); + myD3dSurf = NULL; + myD3dSurfShare = NULL; + } + + OpenGl_FrameBuffer::Release (theCtx); +} + +// ======================================================================= +// function : Init +// purpose : +// ======================================================================= +Standard_Boolean D3DHost_FrameBuffer::Init (const Handle(OpenGl_Context)& theCtx, + IDirect3DDevice9* theD3DDevice, + const Standard_Boolean theIsD3dEx, + const Standard_Integer theSizeX, + const Standard_Integer theSizeY) +{ + myVPSizeX = theSizeX; + myVPSizeY = theSizeY; + const Standard_Integer aSizeX = theSizeX > 0 ? theSizeX : 2; + const Standard_Integer aSizeY = theSizeY > 0 ? theSizeY : 2; + + Release (theCtx.operator->()); + + // Render target surface should be lockable on + // Windows XP and non-lockable on Windows Vista or higher + if (theD3DDevice->CreateRenderTarget (aSizeX, aSizeY, + D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, theIsD3dEx ? TRUE : FALSE, + &myD3dSurf, theIsD3dEx ? &myD3dSurfShare : NULL) != D3D_OK) + { + TCollection_ExtendedString aMsg = TCollection_ExtendedString() + + "D3DHost_FrameBuffer, could not D3DFMT_X8R8G8B8 render target " + aSizeX + "x" + aSizeY; + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + aMsg); + return Standard_False; + } + + const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theCtx->core11; + if (aFuncs->wglDXOpenDeviceNV == NULL) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + "D3DHost_FrameBuffer, WGL_NV_DX_interop is unavailable!"); + return Standard_False; + } + + myGlD3dDevice = aFuncs->wglDXOpenDeviceNV (theD3DDevice); + if (myGlD3dDevice == NULL) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + "D3DHost_FrameBuffer, could not create the GL <-> DirectX Interop using wglDXOpenDeviceNV()"); + return Standard_False; + } + + if (!registerD3dBuffer (theCtx)) + { + return Standard_False; + } + + theCtx->arbFBO->glGenFramebuffers (1, &myGlFBufferId); + + if (!myDepthStencilTexture->Init (theCtx, GL_DEPTH24_STENCIL8, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, + aSizeX, aSizeY, Graphic3d_TOT_2D)) + { + TCollection_ExtendedString aMsg = TCollection_ExtendedString() + + "D3DHost_FrameBuffer, could not initialize GL_DEPTH24_STENCIL8 texture " + aSizeX + "x" + aSizeY; + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + aMsg); + return Standard_False; + } + + return Standard_True; +} + +// ======================================================================= +// function : registerD3dBuffer +// purpose : +// ======================================================================= +Standard_Boolean D3DHost_FrameBuffer::registerD3dBuffer (const Handle(OpenGl_Context)& theCtx) +{ + const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theCtx->core11; + if (myGlD3dSurf != NULL) + { + if (!aFuncs->wglDXUnregisterObjectNV (myGlD3dDevice, myGlD3dSurf)) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + "D3DHost_FrameBuffer, can not unregister color buffer"); + return Standard_False; + } + myGlD3dSurf = NULL; + } + + if (!aFuncs->wglDXSetResourceShareHandleNV (myD3dSurf, myD3dSurfShare)) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + "D3DHost_FrameBuffer, wglDXSetResourceShareHandleNV() has failed"); + return Standard_False; + } + + myColorTexture->Release (theCtx.operator->()); + myColorTexture->Create (theCtx); + + myGlD3dSurf = aFuncs->wglDXRegisterObjectNV (myGlD3dDevice, + myD3dSurf, + myColorTexture->TextureId(), + GL_TEXTURE_2D, + WGL_ACCESS_WRITE_DISCARD_NV); + + if (myGlD3dSurf == NULL) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + "D3DHost_FrameBuffer, can not register color buffer"); + return Standard_False; + } + + return Standard_True; +} + +// ======================================================================= +// function : BindBuffer +// purpose : +// ======================================================================= +void D3DHost_FrameBuffer::BindBuffer (const Handle(OpenGl_Context)& theCtx) +{ + Standard_ProgramError_Raise_if (myLockCount < 1, "D3DHost_FrameBuffer::BindBuffer(), resource should be locked beforehand!"); + + OpenGl_FrameBuffer::BindBuffer (theCtx); + theCtx->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, myColorTexture->TextureId(), 0); + theCtx->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0); + if (theCtx->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + "D3DHost_FrameBuffer, OpenGL FBO is incomplete!"); + Release (theCtx.operator->()); + } +} + +// ======================================================================= +// function : LockSurface +// purpose : +// ======================================================================= +void D3DHost_FrameBuffer::LockSurface (const Handle(OpenGl_Context)& theCtx) +{ + if (myGlD3dSurf == NULL) + { + return; + } + + if (++myLockCount > 1) + { + return; + } + + const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theCtx->core11; + if (!aFuncs->wglDXLockObjectsNV (myGlD3dDevice, 1, &myGlD3dSurf)) + { + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + "D3DHost_FrameBuffer::LockSurface(), lock failed!"); + } +} + +// ======================================================================= +// function : UnlockSurface +// purpose : +// ======================================================================= +void D3DHost_FrameBuffer::UnlockSurface (const Handle(OpenGl_Context)& theCtx) +{ + if (myGlD3dSurf == NULL) + { + return; + } + + if (--myLockCount != 0) + { + return; + } + + const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theCtx->core11; + aFuncs->wglDXUnlockObjectsNV (myGlD3dDevice, 1, &myGlD3dSurf); +} diff --git a/src/D3DHost/D3DHost_FrameBuffer.hxx b/src/D3DHost/D3DHost_FrameBuffer.hxx new file mode 100644 index 0000000000..22eed6e645 --- /dev/null +++ b/src/D3DHost/D3DHost_FrameBuffer.hxx @@ -0,0 +1,83 @@ +// Created on: 2015-06-10 +// Created by: Kirill Gavrilov +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _D3DHost_FrameBuffer_HeaderFile +#define _D3DHost_FrameBuffer_HeaderFile + +#include + +struct IDirect3DDevice9; + +//! Implements bridge FBO for direct rendering to Direct3D surfaces. +class D3DHost_FrameBuffer : public OpenGl_FrameBuffer +{ +public: + + //! Empty constructor. + Standard_EXPORT D3DHost_FrameBuffer(); + + //! Destructor, should be called after Release(). + Standard_EXPORT ~D3DHost_FrameBuffer(); + + //! Releases D3D and OpenGL resources. + Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE; + + //! Initializes OpenGL FBO for Direct3D interoperability. + Standard_EXPORT Standard_Boolean Init (const Handle(OpenGl_Context)& theCtx, + IDirect3DDevice9* theD3DDevice, + const Standard_Boolean theIsD3dEx, + const Standard_Integer theSizeX, + const Standard_Integer theSizeY); + + //! Binds Direct3D color buffer to OpenGL texture. + Standard_EXPORT Standard_Boolean registerD3dBuffer (const Handle(OpenGl_Context)& theCtx); + + //! Binds Direct3D objects for OpenGL drawing. + //! Should be called before LockSurface() and followed by UnlockSurface(); + Standard_EXPORT virtual void BindBuffer (const Handle(OpenGl_Context)& theCtx) Standard_OVERRIDE; + + //! Acquires D3D resource for OpenGL usage. + Standard_EXPORT virtual void LockSurface (const Handle(OpenGl_Context)& theCtx); + + //! Releases D3D resource. + Standard_EXPORT virtual void UnlockSurface (const Handle(OpenGl_Context)& theCtx); + + //! Returns D3D surface used as color buffer. + IDirect3DSurface9* D3dColorSurface() { return myD3dSurf; } + + //! Returns WDDM hande for D3D color surface. + HANDLE D3dColorSurfaceShare() { return myD3dSurfShare; } + +protected: + + using OpenGl_FrameBuffer::Init; + +protected: + + IDirect3DSurface9* myD3dSurf; //!< D3D surface + HANDLE myD3dSurfShare; //!< D3D surface share handle in WDDM + HANDLE myGlD3dDevice; //!< WGL/D3D device handle + HANDLE myGlD3dSurf; //!< WGL/D3D surface handle + Standard_Integer myLockCount; //!< locking counter + +public: + + DEFINE_STANDARD_RTTI(D3DHost_FrameBuffer, OpenGl_FrameBuffer) + +}; + +DEFINE_STANDARD_HANDLE(D3DHost_FrameBuffer, OpenGl_FrameBuffer) + +#endif // _D3DHost_FrameBuffer_HeaderFile diff --git a/src/D3DHost/D3DHost_GraphicDriver.cxx b/src/D3DHost/D3DHost_GraphicDriver.cxx new file mode 100644 index 0000000000..23ece91194 --- /dev/null +++ b/src/D3DHost/D3DHost_GraphicDriver.cxx @@ -0,0 +1,104 @@ +// Created on: 2015-06-10 +// Created by: Kirill Gavrilov +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include + +#include +#include +#include + +#ifdef _MSC_VER + #pragma comment (lib, "D3D9.lib") +#endif + +// ======================================================================= +// function : D3DHost_GraphicDriver +// purpose : +// ======================================================================= +D3DHost_GraphicDriver::D3DHost_GraphicDriver() +: OpenGl_GraphicDriver (Handle(Aspect_DisplayConnection)(), Standard_False) +{ + // +} + +// ======================================================================= +// function : ~D3DHost_GraphicDriver +// purpose : +// ======================================================================= +D3DHost_GraphicDriver::~D3DHost_GraphicDriver() +{ + // +} + +// ======================================================================= +// function : View +// purpose : +// ======================================================================= +Standard_Boolean D3DHost_GraphicDriver::View (Graphic3d_CView& theCView) +{ + Handle(OpenGl_Context) aShareCtx = GetSharedContext(); + OpenGl_CView* aCView = (OpenGl_CView* )theCView.ptrView; + if (aCView != NULL + && myMapOfView.Contains (aCView->View)) + { + Handle(D3DHost_Workspace) anOldWS = Handle(D3DHost_Workspace)::DownCast (aCView->WS); + Handle(D3DHost_Workspace) aWS = new D3DHost_Workspace (this, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx); + theCView.ptrFBO = aWS->D3dWglBuffer().operator->(); + aCView->WS = aWS; + aWS->SetActiveView (aCView->View, theCView.ViewId); + + myMapOfWS.Remove (anOldWS); + myMapOfWS.Add (aWS); + return Standard_True; + } + + Handle(D3DHost_Workspace) aWS = new D3DHost_Workspace (this, theCView.DefWindow, theCView.GContext, myCaps, aShareCtx); + Handle(OpenGl_View) aView = new OpenGl_View (theCView.Context, &myStateCounter); + myMapOfWS .Add (aWS); + myMapOfView.Add (aView); + + aCView = new OpenGl_CView(); + aCView->View = aView; + aCView->WS = aWS; + theCView.ptrFBO = aWS->D3dWglBuffer().operator->(); + theCView.ptrView = aCView; + aWS->SetActiveView (aCView->View, theCView.ViewId); + return Standard_True; +} + +// ======================================================================= +// function : D3dColorSurface +// purpose : +// ======================================================================= +IDirect3DSurface9* D3DHost_GraphicDriver::D3dColorSurface (const Handle(Visual3d_View)& theView) const +{ + Graphic3d_CView* aCView = (Graphic3d_CView* )(theView->CView()); + if (aCView == NULL + || aCView->ptrView == NULL) + { + return NULL; + } + + Handle(D3DHost_Workspace) aWS = Handle(D3DHost_Workspace)::DownCast (((OpenGl_CView* )aCView->ptrView)->WS); + if (aWS.IsNull() + || aWS->D3dWglBuffer().IsNull()) + { + return NULL; + } + + return aWS->D3dWglBuffer()->D3dColorSurface(); +} diff --git a/src/D3DHost/D3DHost_GraphicDriver.hxx b/src/D3DHost/D3DHost_GraphicDriver.hxx new file mode 100644 index 0000000000..092017c9c3 --- /dev/null +++ b/src/D3DHost/D3DHost_GraphicDriver.hxx @@ -0,0 +1,49 @@ +// Created on: 2015-06-10 +// Created by: Kirill Gavrilov +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _D3DHost_GraphicDriver_HeaderFile +#define _D3DHost_GraphicDriver_HeaderFile + +#include + +class Visual3d_View; +struct IDirect3DSurface9; + +//! This class defines D3D host for an OpenGl graphic driver +class D3DHost_GraphicDriver : public OpenGl_GraphicDriver +{ +public: + + //! Constructor. + Standard_EXPORT D3DHost_GraphicDriver(); + + //! Destructor. + Standard_EXPORT virtual ~D3DHost_GraphicDriver(); + + //! Create new view. + Standard_EXPORT virtual Standard_Boolean View (Graphic3d_CView& theCView); + + //! Return D3D surface for specified view. + Standard_EXPORT IDirect3DSurface9* D3dColorSurface (const Handle(Visual3d_View)& theCView) const; + +public: + + DEFINE_STANDARD_RTTI(D3DHost_GraphicDriver, OpenGl_GraphicDriver) + +}; + +DEFINE_STANDARD_HANDLE(D3DHost_GraphicDriver, OpenGl_GraphicDriver) + +#endif // _D3DHost_GraphicDriver_HeaderFile diff --git a/src/D3DHost/D3DHost_Workspace.cxx b/src/D3DHost/D3DHost_Workspace.cxx new file mode 100644 index 0000000000..8ad7c85f18 --- /dev/null +++ b/src/D3DHost/D3DHost_Workspace.cxx @@ -0,0 +1,364 @@ +// Created on: 2015-06-10 +// Created by: Kirill Gavrilov +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include + +#include + +// ======================================================================= +// function : d3dFormatError +// purpose : +// ======================================================================= +TCollection_AsciiString D3DHost_Workspace::d3dFormatError (HRESULT theErrCode) +{ + switch (theErrCode) + { + case D3D_OK: return "OK"; + case D3DERR_DEVICELOST: return "Device lost"; + case D3DERR_DEVICEREMOVED: return "Device removed"; + case D3DERR_DRIVERINTERNALERROR: return "Driver internal error"; + case D3DERR_OUTOFVIDEOMEMORY: return "Out of video memory"; + case D3DERR_INVALIDCALL: return "Invalid call"; + default: return TCollection_AsciiString ("Error #") + int(theErrCode) + ")"; + } +} + +// ======================================================================= +// function : D3DHost_Workspace +// purpose : +// ======================================================================= +D3DHost_Workspace::D3DHost_Workspace (const Handle(OpenGl_GraphicDriver)& theDriver, + const CALL_DEF_WINDOW& theCWindow, + Aspect_RenderingContext theGContext, + const Handle(OpenGl_Caps)& theCaps, + const Handle(OpenGl_Context)& theShareCtx) +: OpenGl_Workspace (theDriver, theCWindow, theGContext, theCaps, theShareCtx), + myD3dLib (NULL), + myD3dDevice (NULL), + myRefreshRate (D3DPRESENT_RATE_DEFAULT), + myIsD3dEx (false) +{ + myD3dParams = {}; + myCurrMode = {}; + myD3dParams.Windowed = TRUE; + myD3dParams.SwapEffect = D3DSWAPEFFECT_DISCARD; + myD3dParams.BackBufferFormat = D3DFMT_X8R8G8B8; + myD3dParams.BackBufferCount = 1; + myD3dParams.BackBufferHeight = 2; + myD3dParams.BackBufferWidth = 2; + myD3dParams.EnableAutoDepthStencil = FALSE; + myD3dParams.AutoDepthStencilFormat = D3DFMT_D16_LOCKABLE; + myD3dParams.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + myD3dParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + + d3dInit (theCWindow); + d3dCreateRenderTarget(); +} + +// ======================================================================= +// function : ~D3DHost_Workspace +// purpose : +// ======================================================================= +D3DHost_Workspace::~D3DHost_Workspace() +{ + if (!myD3dWglFbo.IsNull()) + { + myD3dWglFbo->Release (myGlContext.operator->()); + myD3dWglFbo.Nullify(); + } + if (myD3dDevice != NULL) + { + myD3dDevice->Release(); + myD3dDevice = NULL; + } + if (myD3dLib != NULL) + { + myD3dLib->Release(); + myD3dLib = NULL; + } +} + +// ======================================================================= +// function : d3dInitLib +// purpose : +// ======================================================================= +bool D3DHost_Workspace::d3dInitLib() +{ + if (myD3dLib == NULL) + { + IDirect3D9Ex* aD3dLibEx = NULL; + // we link against d3d (using Direct3DCreate9 symbol), thus it should be already loaded + HMODULE aLib = GetModuleHandleW (L"d3d9"); + if (aLib != NULL) + { + // retrieve D3D9Ex function dynamically (available only since Vista+) + typedef HRESULT (WINAPI* Direct3DCreate9Ex_t)(UINT , IDirect3D9Ex** ); + Direct3DCreate9Ex_t Direct3DCreate9ExProc = (Direct3DCreate9Ex_t )GetProcAddress (aLib, "Direct3DCreate9Ex"); + if (Direct3DCreate9ExProc != NULL) + { + Direct3DCreate9ExProc(D3D_SDK_VERSION, &aD3dLibEx); + } + } + myD3dLib = aD3dLibEx; + myIsD3dEx = aD3dLibEx != NULL; + if (myD3dLib == NULL) + { + myD3dLib = Direct3DCreate9 (D3D_SDK_VERSION); + } + } + return myD3dLib != NULL; +} + +// ======================================================================= +// function : d3dInit +// purpose : +// ======================================================================= +bool D3DHost_Workspace::d3dInit (const CALL_DEF_WINDOW& theCWindow) +{ + if (!d3dInitLib()) + { + myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + "Direct3DCreate9 failed!"); + return false; + } + + UINT anAdapterId = D3DADAPTER_DEFAULT; + + // setup the present parameters + if (myD3dLib->GetAdapterDisplayMode (anAdapterId, &myCurrMode) == D3D_OK) + { + myD3dParams.BackBufferFormat = myCurrMode.Format; + myRefreshRate = myCurrMode.RefreshRate; + } + myD3dParams.Windowed = TRUE; + myD3dParams.BackBufferWidth = theCWindow.dx; + myD3dParams.BackBufferHeight = theCWindow.dy; + myD3dParams.hDeviceWindow = (HWND )theCWindow.XWindow; + + // create the Video Device + HRESULT isOK = myD3dLib->CreateDevice (anAdapterId, D3DDEVTYPE_HAL, + (HWND )theCWindow.XWindow, + D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, + &myD3dParams, &myD3dDevice); + if (isOK < 0) + { + return false; + } + + return myD3dDevice != NULL; +} + +// ======================================================================= +// function : d3dReset +// purpose : +// ======================================================================= +bool D3DHost_Workspace::d3dReset (const CALL_DEF_WINDOW& theCWindow) +{ + if (myD3dDevice == NULL) + { + return false; + } + + myD3dParams.Windowed = TRUE; + myD3dParams.BackBufferWidth = theCWindow.dx; + myD3dParams.BackBufferHeight = theCWindow.dy; + myD3dParams.hDeviceWindow = (HWND )theCWindow.XWindow; + myD3dParams.FullScreen_RefreshRateInHz = !myD3dParams.Windowed ? myRefreshRate : 0; + + HRESULT isOK = myD3dDevice->Reset(&myD3dParams); + return isOK == D3D_OK; +} + +// ======================================================================= +// function : d3dCreateRenderTarget +// purpose : +// ======================================================================= +bool D3DHost_Workspace::d3dCreateRenderTarget() +{ + if (myD3dWglFbo.IsNull()) + { + myD3dWglFbo = new D3DHost_FrameBuffer(); + } + if (!myD3dWglFbo->Init (myGlContext, myD3dDevice, myIsD3dEx, myWidth, myHeight)) + { + return false; + } + + myD3dDevice->SetRenderTarget (0, myD3dWglFbo->D3dColorSurface()); + return true; +} + +// ======================================================================= +// function : d3dBeginRender +// purpose : +// ======================================================================= +void D3DHost_Workspace::d3dBeginRender() +{ + if (myD3dDevice == NULL) + { + return; + } + + // clear the back buffer + myD3dDevice->Clear (0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + myD3dDevice->BeginScene(); +} + +// ======================================================================= +// function : d3dEndRender +// purpose : +// ======================================================================= +void D3DHost_Workspace::d3dEndRender() +{ + if (myD3dDevice != NULL) + { + myD3dDevice->EndScene(); + } +} + +// ======================================================================= +// function : d3dSwap +// purpose : +// ======================================================================= +bool D3DHost_Workspace::d3dSwap() +{ + if (myD3dDevice == NULL) + { + return false; + } + + const HRESULT isOK = myD3dDevice->Present (NULL, NULL, NULL, NULL); + if (isOK != D3D_OK) + { + TCollection_ExtendedString aMsg = TCollection_ExtendedString() + + "Direct3D9, Present device failed, " + d3dFormatError (isOK); + myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + aMsg); + } + return isOK == D3D_OK; +} + +// ======================================================================= +// function : Redraw +// purpose : +// ======================================================================= +void D3DHost_Workspace::Redraw (const Graphic3d_CView& theCView, + const Aspect_CLayer2d& theCUnderLayer, + const Aspect_CLayer2d& theCOverLayer) +{ + if (!Activate() + || myD3dDevice == NULL) + { + return; + } + + myToFlipOutput = Standard_True; + myD3dWglFbo->LockSurface (myGlContext); + OpenGl_Workspace::Redraw (theCView, theCUnderLayer, theCOverLayer); + myD3dWglFbo->UnlockSurface (myGlContext); + myToFlipOutput = Standard_False; + if (myGlContext->caps->buffersNoSwap) + { + return; + } + + // blit result to the D3D back buffer and swap + d3dBeginRender(); + + IDirect3DSurface9* aBackbuffer = NULL; + myD3dDevice->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &aBackbuffer); + myD3dDevice->StretchRect (myD3dWglFbo->D3dColorSurface(), NULL, aBackbuffer, NULL, D3DTEXF_LINEAR); + aBackbuffer->Release(); + + d3dEndRender(); + d3dSwap(); +} + +// ======================================================================= +// function : RedrawImmediate +// purpose : +// ======================================================================= +void D3DHost_Workspace::RedrawImmediate (const Graphic3d_CView& theCView, + const Aspect_CLayer2d& theCUnderLayer, + const Aspect_CLayer2d& theCOverLayer) +{ + if (!myTransientDrawToFront + || !myBackBufferRestored + || (myGlContext->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid())) + { + Redraw (theCView, theCUnderLayer, theCOverLayer); + return; + } + else if (!Activate() + || myD3dDevice == NULL) + { + return; + } + + myToFlipOutput = Standard_True; + myD3dWglFbo->LockSurface (myGlContext); + OpenGl_Workspace::RedrawImmediate (theCView, theCUnderLayer, theCOverLayer); + myD3dWglFbo->UnlockSurface (myGlContext); + myToFlipOutput = Standard_False; + if (myGlContext->caps->buffersNoSwap) + { + return; + } + + // blit result to the D3D back buffer and swap + d3dBeginRender(); + + IDirect3DSurface9* aBackbuffer = NULL; + myD3dDevice->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &aBackbuffer); + myD3dDevice->StretchRect (myD3dWglFbo->D3dColorSurface(), NULL, aBackbuffer, NULL, D3DTEXF_LINEAR); + aBackbuffer->Release(); + + d3dEndRender(); + d3dSwap(); +} + +// ======================================================================= +// function : Resize +// purpose : +// ======================================================================= +void D3DHost_Workspace::Resize (const CALL_DEF_WINDOW& theCWindow) +{ + const Standard_Integer aWidthOld = myWidth; + const Standard_Integer aHeightOld = myHeight; + OpenGl_Workspace::Resize (theCWindow); + if (aWidthOld == myWidth + && aHeightOld == myHeight) + { + return; + } + + if (!myD3dWglFbo.IsNull()) + { + myD3dWglFbo->Release (myGlContext.operator->()); + } + if (!myGlContext->caps->buffersNoSwap) + { + d3dReset (theCWindow); + } + d3dCreateRenderTarget(); +} diff --git a/src/D3DHost/D3DHost_Workspace.hxx b/src/D3DHost/D3DHost_Workspace.hxx new file mode 100644 index 0000000000..fcec6b9db0 --- /dev/null +++ b/src/D3DHost/D3DHost_Workspace.hxx @@ -0,0 +1,110 @@ +// Created on: 2015-06-10 +// Created by: Kirill Gavrilov +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _D3DHost_Workspace_HeaderFile +#define _D3DHost_Workspace_HeaderFile + +#include + +#include +#include + +//! The D3D host containing OpenGL viewer. +class D3DHost_Workspace : public OpenGl_Workspace +{ + +public: + + //! Main constructor. + Standard_EXPORT D3DHost_Workspace (const Handle(OpenGl_GraphicDriver)& theDriver, + const CALL_DEF_WINDOW& theCWindow, + Aspect_RenderingContext theGContext, + const Handle(OpenGl_Caps)& theCaps, + const Handle(OpenGl_Context)& theShareCtx); + + //! Destroy D3D connection and OpenGL workspace. + Standard_EXPORT virtual ~D3DHost_Workspace(); + + //! Resizes the window. + Standard_EXPORT virtual void Resize (const CALL_DEF_WINDOW& theCWindow) Standard_OVERRIDE; + + //! Redraw the all content. + Standard_EXPORT virtual void Redraw (const Graphic3d_CView& theCView, + const Aspect_CLayer2d& theCUnderLayer, + const Aspect_CLayer2d& theCOverLayer) Standard_OVERRIDE; + + //! Redraw only immediate layer. + Standard_EXPORT virtual void RedrawImmediate (const Graphic3d_CView& theCView, + const Aspect_CLayer2d& theCUnderLayer, + const Aspect_CLayer2d& theCOverLayer) Standard_OVERRIDE; + +public: + + //! @return true if IDirect3DDevice9Ex device has been created + bool isD3dEx() const { return myIsD3dEx; } + + //! Access Direct3D device instance. + IDirect3DDevice9* D3dDevice() const { return myD3dDevice; } + + //! Return D3D/WGL FBO. + const Handle(D3DHost_FrameBuffer)& D3dWglBuffer() const { return myD3dWglFbo; } + +protected: + + //! Auxiliary method. + Standard_EXPORT static TCollection_AsciiString d3dFormatError (HRESULT theErrCode); + + //! Initialize the D3D library. + Standard_EXPORT bool d3dInitLib(); + + //! Initialize Direct3D output device. + Standard_EXPORT bool d3dInit (const CALL_DEF_WINDOW& theCWindow); + + //! Reset Direct3D output settings. Could be used to switch windowed/fullscreen modes. + //! Use very carefully! Most objects should be released before and recreated after! + Standard_EXPORT bool d3dReset (const CALL_DEF_WINDOW& theCWindow); + + //! (Re-)create D3D surface. + Standard_EXPORT bool d3dCreateRenderTarget(); + + //! Starts the scene render. + //! Clears the backbuffer and sets the device to start rendering to it. + Standard_EXPORT void d3dBeginRender(); + + //! Ends the scene render. + Standard_EXPORT void d3dEndRender(); + + //! Presents to the screen. + Standard_EXPORT bool d3dSwap(); + +protected: + + IDirect3D9* myD3dLib; //!< Direct3D library instance + IDirect3DDevice9* myD3dDevice; //!< Direct3D device object + D3DPRESENT_PARAMETERS myD3dParams; //!< parameters for created Direct3D device + D3DDISPLAYMODE myCurrMode; //!< temporary variable + UINT myRefreshRate; //!< refresh rate in fullscreen mode + bool myIsD3dEx; //!< D3dEx flag for WDDM + Handle(D3DHost_FrameBuffer) myD3dWglFbo; //!< D3D/WGL interop FBO + +public: + + DEFINE_STANDARD_RTTI(D3DHost_Workspace, OpenGl_Workspace) + +}; + +DEFINE_STANDARD_HANDLE(D3DHost_Workspace, OpenGl_Workspace) + +#endif // _D3DHost_Workspace_HeaderFile diff --git a/src/D3DHost/FILES b/src/D3DHost/FILES new file mode 100644 index 0000000000..fce5140e8a --- /dev/null +++ b/src/D3DHost/FILES @@ -0,0 +1,6 @@ +D3DHost_GraphicDriver.hxx +D3DHost_GraphicDriver.cxx +D3DHost_FrameBuffer.hxx +D3DHost_FrameBuffer.cxx +D3DHost_Workspace.hxx +D3DHost_Workspace.cxx diff --git a/src/Graphic3d/Graphic3d_GraphicDriver.hxx b/src/Graphic3d/Graphic3d_GraphicDriver.hxx index 6b2e99249d..d73b8198a7 100644 --- a/src/Graphic3d/Graphic3d_GraphicDriver.hxx +++ b/src/Graphic3d/Graphic3d_GraphicDriver.hxx @@ -127,7 +127,10 @@ public: //! Invalidates content of the view but does not redraw it Standard_EXPORT virtual void Invalidate (const Graphic3d_CView& theCView) = 0; - + + //! Returns true if cached view content has been invalidated. + Standard_EXPORT virtual Standard_Boolean IsInvalidated (const Graphic3d_CView& theCView) const = 0; + //! call_togl_removeview Standard_EXPORT virtual void RemoveView (const Graphic3d_CView& ACView) = 0; diff --git a/src/OS/Visualization.tcl b/src/OS/Visualization.tcl index 1ea17855e0..74fbe7f8d5 100644 --- a/src/OS/Visualization.tcl +++ b/src/OS/Visualization.tcl @@ -25,6 +25,14 @@ proc Visualization:toolkits { } { lappend aResult "TKIVtk" } + if { "$::tcl_platform(platform)" == "windows" } { + if { [info exists ::env(HAVE_D3D)] && "$::env(HAVE_D3D)" == "true" } { + lappend aResult "TKD3DHost" + } elseif { [info exists ::env(VCVER)] && "$::env(VCVER)" != "vc8" && "$::env(VCVER)" != "vc9" && "$::env(VCVER)" != "vc10" } { + lappend aResult "TKD3DHost" + } + } + return $aResult } ;# diff --git a/src/OpenGl/OpenGl_FrameBuffer.cxx b/src/OpenGl/OpenGl_FrameBuffer.cxx index ba844f6db7..37bb42c39f 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.cxx +++ b/src/OpenGl/OpenGl_FrameBuffer.cxx @@ -51,8 +51,8 @@ OpenGl_FrameBuffer::~OpenGl_FrameBuffer() // purpose : // ======================================================================= Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext, - const GLsizei theViewportSizeX, - const GLsizei theViewportSizeY) + const GLsizei theSizeX, + const GLsizei theSizeY) { if (theGlContext->arbFBO == NULL) { @@ -63,13 +63,15 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo Release (theGlContext.operator->()); // setup viewport sizes as is - myVPSizeX = theViewportSizeX; - myVPSizeY = theViewportSizeY; + myVPSizeX = theSizeX; + myVPSizeY = theSizeY; + const Standard_Integer aSizeX = theSizeX > 0 ? theSizeX : 2; + const Standard_Integer aSizeY = theSizeY > 0 ? theSizeY : 2; // Create the textures (will be used as color buffer and depth-stencil buffer) if (!myColorTexture->Init (theGlContext, myTextFormat, GL_RGBA, GL_UNSIGNED_BYTE, - myVPSizeX, myVPSizeY, Graphic3d_TOT_2D)) + aSizeX, aSizeY, Graphic3d_TOT_2D)) { Release (theGlContext.operator->()); return Standard_False; @@ -79,7 +81,7 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo // instead of just trying to create such texture if (!myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, - myVPSizeX, myVPSizeY, Graphic3d_TOT_2D)) + aSizeX, aSizeY, Graphic3d_TOT_2D)) { TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Warning! Depth textures are not supported by hardware!"; @@ -91,7 +93,7 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo theGlContext->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId); theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId); - theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, myVPSizeX, myVPSizeY); + theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, aSizeX, aSizeY); theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER); } @@ -150,8 +152,8 @@ Standard_Boolean OpenGl_FrameBuffer::InitLazy (const Handle(OpenGl_Context)& the // purpose : // ======================================================================= Standard_Boolean OpenGl_FrameBuffer::InitWithRB (const Handle(OpenGl_Context)& theGlCtx, - const GLsizei theViewportSizeX, - const GLsizei theViewportSizeY, + const GLsizei theSizeX, + const GLsizei theSizeY, const GLuint theColorRBufferFromWindow) { if (theGlCtx->arbFBO == NULL) @@ -163,8 +165,10 @@ Standard_Boolean OpenGl_FrameBuffer::InitWithRB (const Handle(OpenGl_Context)& t Release (theGlCtx.operator->()); // setup viewport sizes as is - myVPSizeX = theViewportSizeX; - myVPSizeY = theViewportSizeY; + myVPSizeX = theSizeX; + myVPSizeY = theSizeY; + const Standard_Integer aSizeX = theSizeX > 0 ? theSizeX : 2; + const Standard_Integer aSizeY = theSizeY > 0 ? theSizeY : 2; // Create the render-buffers if (theColorRBufferFromWindow != NO_RENDERBUFFER) @@ -175,12 +179,12 @@ Standard_Boolean OpenGl_FrameBuffer::InitWithRB (const Handle(OpenGl_Context)& t { theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlColorRBufferId); theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlColorRBufferId); - theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_RGBA8, myVPSizeX, myVPSizeY); + theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_RGBA8, aSizeX, aSizeY); } theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId); theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId); - theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, myVPSizeX, myVPSizeY); + theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, aSizeX, aSizeY); theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER); diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index c03c1a43f1..2321561689 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -651,3 +651,12 @@ void OpenGl_GraphicDriver::GraduatedTrihedronMinMaxValues (const Graphic3d_CView aCView->View->ChangeGraduatedTrihedron().SetMinMax (theMin, theMax); } } + +// ======================================================================= +// function : SetBuffersNoSwap +// purpose : +// ======================================================================= +void OpenGl_GraphicDriver::SetBuffersNoSwap (const Standard_Boolean theIsNoSwap) +{ + myCaps->buffersNoSwap = theIsNoSwap; +} diff --git a/src/OpenGl/OpenGl_GraphicDriver.hxx b/src/OpenGl/OpenGl_GraphicDriver.hxx index b610f89512..1269a39e96 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.hxx +++ b/src/OpenGl/OpenGl_GraphicDriver.hxx @@ -160,6 +160,7 @@ public: const Aspect_CLayer2d& theCUnderLayer, const Aspect_CLayer2d& theCOverLayer); Standard_EXPORT void Invalidate (const Graphic3d_CView& theCView); + Standard_EXPORT Standard_Boolean IsInvalidated (const Graphic3d_CView& theCView) const; Standard_EXPORT void RemoveView (const Graphic3d_CView& ACView); Standard_EXPORT void SetLight (const Graphic3d_CView& ACView); Standard_EXPORT void SetClipPlanes (const Graphic3d_CView& theCView); @@ -325,6 +326,9 @@ public: return *myCaps.operator->(); } + //! Specify swap buffer behavior. + Standard_EXPORT void SetBuffersNoSwap (const Standard_Boolean theIsNoSwap); + //! VBO usage can be forbidden by this method even if it is supported by GL driver. //! Notice that disabling of VBO will cause rendering performance degradation. //! Warning! This method should be called only before any primitives are displayed in GL scene! @@ -361,7 +365,7 @@ public: DEFINE_STANDARD_RTTI(OpenGl_GraphicDriver, Graphic3d_GraphicDriver) -private: +protected: Standard_Boolean myIsOwnContext; //!< indicates that shared context has been created within OpenGl_GraphicDriver #if defined(HAVE_EGL) || defined(__ANDROID__) @@ -386,7 +390,7 @@ public: //! Returns unique ID for primitive arrays. const Standard_Size GetNextPrimitiveArrayUID() const { return myUIDGenerator.Increment(); } -private: +protected: mutable OpenGl_StateCounter myStateCounter; //!< State counter for OpenGl structures. mutable OpenGl_StateCounter myUIDGenerator; //!< Unique ID counter for primitive arrays. diff --git a/src/OpenGl/OpenGl_GraphicDriver_7.cxx b/src/OpenGl/OpenGl_GraphicDriver_7.cxx index 5c224838b2..49093205e3 100644 --- a/src/OpenGl/OpenGl_GraphicDriver_7.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_7.cxx @@ -143,10 +143,17 @@ void OpenGl_GraphicDriver::Invalidate (const Graphic3d_CView& theCView) const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView; if (aCView != NULL) { - aCView->WS->Invalidate (theCView); + aCView->WS->Invalidate(); } } +Standard_Boolean OpenGl_GraphicDriver::IsInvalidated (const Graphic3d_CView& theCView) const +{ + const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView; + return aCView == NULL + || aCView->WS->IsInvalidated(); +} + Graphic3d_PtrFrameBuffer OpenGl_GraphicDriver::FBOCreate (const Graphic3d_CView& ACView, const Standard_Integer theWidth, const Standard_Integer theHeight) { const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView; diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 1bd43b4eac..86220b2b7b 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -79,10 +79,10 @@ DEFINE_STANDARD_HANDLE(OpenGl_View,MMgt_TShared) class OpenGl_View : public MMgt_TShared { public: - OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext, OpenGl_StateCounter* theCounter); - virtual ~OpenGl_View (); + Standard_EXPORT OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext, OpenGl_StateCounter* theCounter); + Standard_EXPORT virtual ~OpenGl_View (); - void ReleaseGlResources (const Handle(OpenGl_Context)& theCtx); + Standard_EXPORT void ReleaseGlResources (const Handle(OpenGl_Context)& theCtx); void SetTextureEnv (const Handle(OpenGl_Context)& theCtx, const Handle(Graphic3d_TextureEnv)& theTexture); diff --git a/src/OpenGl/OpenGl_Window.cxx b/src/OpenGl/OpenGl_Window.cxx index c4e9921fd7..668cd8f259 100644 --- a/src/OpenGl/OpenGl_Window.cxx +++ b/src/OpenGl/OpenGl_Window.cxx @@ -841,10 +841,7 @@ void OpenGl_Window::Init() eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_WIDTH, &myWidth); eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_HEIGHT, &myHeight); #elif defined(_WIN32) - RECT cr; - GetClientRect ((HWND )myGlContext->myWindow, &cr); - myWidth = cr.right - cr.left; - myHeight = cr.bottom - cr.top; + // #else Window aRootWin; int aDummy; diff --git a/src/OpenGl/OpenGl_Window.hxx b/src/OpenGl/OpenGl_Window.hxx index f4f53060fd..1b4616cb38 100644 --- a/src/OpenGl/OpenGl_Window.hxx +++ b/src/OpenGl/OpenGl_Window.hxx @@ -47,26 +47,26 @@ class OpenGl_Window : public MMgt_TShared public: //! Main constructor - prepare GL context for specified window. - OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver, - const CALL_DEF_WINDOW& theCWindow, - Aspect_RenderingContext theGContext, - const Handle(OpenGl_Caps)& theCaps, - const Handle(OpenGl_Context)& theShareCtx); + Standard_EXPORT OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver, + const CALL_DEF_WINDOW& theCWindow, + Aspect_RenderingContext theGContext, + const Handle(OpenGl_Caps)& theCaps, + const Handle(OpenGl_Context)& theShareCtx); //! Destructor - virtual ~OpenGl_Window(); + Standard_EXPORT virtual ~OpenGl_Window(); //! Resizes the window. - void Resize (const CALL_DEF_WINDOW& theCWindow); + Standard_EXPORT virtual void Resize (const CALL_DEF_WINDOW& theCWindow); //! Reads depth component for current scene into specified buffer. void ReadDepths (const Standard_Integer theX, const Standard_Integer theY, const Standard_Integer theWidth, const Standard_Integer theHeight, float* theDepths); - void SetBackgroundColor (const Standard_ShortReal theR, - const Standard_ShortReal theG, - const Standard_ShortReal theB); + Standard_EXPORT void SetBackgroundColor (const Standard_ShortReal theR, + const Standard_ShortReal theG, + const Standard_ShortReal theB); Standard_Integer Width() const { return myWidth; } Standard_Integer Height() const { return myHeight; } @@ -77,13 +77,13 @@ public: protected: //! Activates GL context and setup viewport. - void Init(); + Standard_EXPORT void Init(); //! Makes GL context for this window active in current thread - virtual Standard_Boolean Activate(); + Standard_EXPORT virtual Standard_Boolean Activate(); - void EnableFeatures() const; - void DisableFeatures() const; + Standard_EXPORT void EnableFeatures() const; + Standard_EXPORT void DisableFeatures() const; protected: diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index daaace8e6b..e6de8c2786 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -145,7 +145,8 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDrive NamedStatus (0), HighlightColor (&THE_WHITE_COLOR), // - myHasFboBlit (Standard_True), + myHasFboBlit (Standard_True), + myToFlipOutput (Standard_False), // myViewId (-1), myAntiAliasingMode (3), @@ -270,7 +271,8 @@ OpenGl_Workspace::~OpenGl_Workspace() nullifyGlResource (myImmediateSceneFbos[0], myGlContext); nullifyGlResource (myImmediateSceneFbos[1], myGlContext); - myFullScreenQuad.Release (myGlContext.operator->()); + myFullScreenQuad .Release (myGlContext.operator->()); + myFullScreenQuadFlip.Release (myGlContext.operator->()); } // ======================================================================= @@ -711,12 +713,53 @@ void OpenGl_Workspace::bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo) myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight); } +// ======================================================================= +// function : initBlitQuad +// purpose : +// ======================================================================= +OpenGl_VertexBuffer* OpenGl_Workspace::initBlitQuad (const Standard_Boolean theToFlip) +{ + OpenGl_VertexBuffer* aVerts = NULL; + if (!theToFlip) + { + aVerts = &myFullScreenQuad; + if (!aVerts->IsValid()) + { + OpenGl_Vec4 aQuad[4] = + { + OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f), + OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f), + OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f), + OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f) + }; + aVerts->Init (myGlContext, 4, 4, aQuad[0].GetData()); + } + } + else + { + aVerts = &myFullScreenQuadFlip; + if (!aVerts->IsValid()) + { + OpenGl_Vec4 aQuad[4] = + { + OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 1.0f), + OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 0.0f), + OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 1.0f), + OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 0.0f) + }; + aVerts->Init (myGlContext, 4, 4, aQuad[0].GetData()); + } + } + return aVerts; +} + // ======================================================================= // function : blitBuffers // purpose : // ======================================================================= -bool OpenGl_Workspace::blitBuffers (OpenGl_FrameBuffer* theReadFbo, - OpenGl_FrameBuffer* theDrawFbo) +bool OpenGl_Workspace::blitBuffers (OpenGl_FrameBuffer* theReadFbo, + OpenGl_FrameBuffer* theDrawFbo, + const Standard_Boolean theToFlip) { if (theReadFbo == NULL) { @@ -780,29 +823,19 @@ bool OpenGl_Workspace::blitBuffers (OpenGl_FrameBuffer* theReadFbo, myGlContext->core20fwd->glEnable (GL_DEPTH_TEST); DisableTexture(); - if (!myFullScreenQuad.IsValid()) - { - OpenGl_Vec4 aQuad[4] = - { - OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f), - OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f), - OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f), - OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f) - }; - myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData()); - } + OpenGl_VertexBuffer* aVerts = initBlitQuad (theToFlip); const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager(); - if (myFullScreenQuad.IsValid() + if (aVerts->IsValid() && aManager->BindFboBlitProgram()) { theReadFbo->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0); theReadFbo->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1); - myFullScreenQuad.BindVertexAttrib (myGlContext, Graphic3d_TOA_POS); + aVerts->BindVertexAttrib (myGlContext, Graphic3d_TOA_POS); myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); - myFullScreenQuad.UnbindVertexAttrib (myGlContext, Graphic3d_TOA_POS); + aVerts->UnbindVertexAttrib (myGlContext, Graphic3d_TOA_POS); theReadFbo->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1); theReadFbo->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0); } @@ -874,20 +907,10 @@ void OpenGl_Workspace::drawStereoPair (const Graphic3d_CView& theCView) myGlContext->core20fwd->glEnable (GL_DEPTH_TEST); DisableTexture(); - if (!myFullScreenQuad.IsValid()) - { - OpenGl_Vec4 aQuad[4] = - { - OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f), - OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f), - OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f), - OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f) - }; - myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData()); - } + OpenGl_VertexBuffer* aVerts = initBlitQuad (myToFlipOutput); const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager(); - if (myFullScreenQuad.IsValid() + if (aVerts->IsValid() && aManager->BindStereoProgram (theCView.RenderParams.StereoMode)) { if (theCView.RenderParams.StereoMode == Graphic3d_StereoMode_Anaglyph) @@ -955,11 +978,11 @@ void OpenGl_Workspace::drawStereoPair (const Graphic3d_CView& theCView) aPair[0]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 0); aPair[1]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 1); - myFullScreenQuad.BindVertexAttrib (myGlContext, 0); + aVerts->BindVertexAttrib (myGlContext, 0); myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); - myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0); + aVerts->UnbindVertexAttrib (myGlContext, 0); aPair[1]->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1); aPair[0]->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + 0); } @@ -1033,6 +1056,11 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView, { myMainSceneFbos[0]->Init (myGlContext, aSizeX, aSizeY); } + if (myToFlipOutput + && myMainSceneFbos[0]->IsValid()) + { + myImmediateSceneFbos[0]->InitLazy (myGlContext, aSizeX, aSizeY); + } } } else @@ -1139,6 +1167,13 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView, else { OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL; + OpenGl_FrameBuffer* anImmFbo = aFrameBuffer; + if (myToFlipOutput + && myImmediateSceneFbos[0]->IsValid()) + { + anImmFbo = myImmediateSceneFbos[0].operator->(); + } + #if !defined(GL_ES_VERSION_2_0) if (aMainFbo == NULL && aFrameBuffer == NULL) @@ -1150,10 +1185,16 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView, aMainFbo != NULL ? aMainFbo : aFrameBuffer, aProjectType); myBackBufferRestored = Standard_True; myIsImmediateDrawn = Standard_False; - if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbo, aProjectType, aFrameBuffer)) + if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbo, aProjectType, anImmFbo)) { toSwap = false; } + + if (anImmFbo != NULL + && anImmFbo != aFrameBuffer) + { + blitBuffers (anImmFbo, aFrameBuffer, myToFlipOutput); + } } #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) @@ -1342,6 +1383,18 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView, const Aspect_CLayer2d& theCUnderLayer, const Aspect_CLayer2d& theCOverLayer) { + if (!myTransientDrawToFront + || !myBackBufferRestored + || (myGlContext->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid())) + { + Redraw (theCView, theCUnderLayer, theCOverLayer); + return; + } + else if (!Activate()) + { + return; + } + const Handle(Graphic3d_Camera)& aCamera = myView->Camera(); Graphic3d_Camera::Projection aProjectType = aCamera->ProjectionType(); OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO; @@ -1367,18 +1420,6 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView, } } - if (!myTransientDrawToFront - || !myBackBufferRestored - || (myGlContext->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid())) - { - Redraw (theCView, theCUnderLayer, theCOverLayer); - return; - } - else if (!Activate()) - { - return; - } - bool toSwap = false; if (aProjectType == Graphic3d_Camera::Projection_Stereo) { @@ -1445,6 +1486,12 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView, else { OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL; + OpenGl_FrameBuffer* anImmFbo = aFrameBuffer; + if (myToFlipOutput + && myImmediateSceneFbos[0]->IsValid()) + { + anImmFbo = myImmediateSceneFbos[0].operator->(); + } #if !defined(GL_ES_VERSION_2_0) if (aMainFbo == NULL) { @@ -1454,8 +1501,13 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView, toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer, aMainFbo, aProjectType, - aFrameBuffer, + anImmFbo, Standard_True) || toSwap; + if (anImmFbo != NULL + && anImmFbo != aFrameBuffer) + { + blitBuffers (anImmFbo, aFrameBuffer, myToFlipOutput); + } } // bind default FBO diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index 2de1dfeebd..b20597767e 100644 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -139,36 +139,37 @@ class OpenGl_Workspace : public OpenGl_Window public: //! Main constructor - prepare GL context for specified window. - OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDriver, - const CALL_DEF_WINDOW& theCWindow, - Aspect_RenderingContext theGContext, - const Handle(OpenGl_Caps)& theCaps, - const Handle(OpenGl_Context)& theShareCtx); + Standard_EXPORT OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDriver, + const CALL_DEF_WINDOW& theCWindow, + Aspect_RenderingContext theGContext, + const Handle(OpenGl_Caps)& theCaps, + const Handle(OpenGl_Context)& theShareCtx); //! Destructor - virtual ~OpenGl_Workspace(); + Standard_EXPORT virtual ~OpenGl_Workspace(); - void SetActiveView (const Handle(OpenGl_View)& theView, - const Standard_Integer theViewId); + Standard_EXPORT void SetActiveView (const Handle(OpenGl_View)& theView, + const Standard_Integer theViewId); const Handle(OpenGl_View)& ActiveView() const { return myView; } Standard_Integer ActiveViewId() const { return myViewId; } //! Redraw the window. - void Redraw (const Graphic3d_CView& theCView, - const Aspect_CLayer2d& theCUnderLayer, - const Aspect_CLayer2d& theCOverLayer); + Standard_EXPORT virtual void Redraw (const Graphic3d_CView& theCView, + const Aspect_CLayer2d& theCUnderLayer, + const Aspect_CLayer2d& theCOverLayer); Standard_Boolean SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer); - void RedrawImmediate (const Graphic3d_CView& theCView, - const Aspect_CLayer2d& theCUnderLayer, - const Aspect_CLayer2d& theCOverLayer); + Standard_EXPORT virtual void RedrawImmediate (const Graphic3d_CView& theCView, + const Aspect_CLayer2d& theCUnderLayer, + const Aspect_CLayer2d& theCOverLayer); - void Invalidate (const Graphic3d_CView& /*theCView*/) - { - myBackBufferRestored = Standard_False; - } + //! Mark cached view content invalid (e.g. complete view redraw should be performed on next frame). + void Invalidate() { myBackBufferRestored = Standard_False; } + + //! Return true if view content cache has been invalidated. + Standard_Boolean IsInvalidated() const { return !myBackBufferRestored; } //! Special method to perform printing. //! System-specific and currently only Win platform implemented. @@ -295,11 +296,15 @@ protected: //! Copy content of Back buffer to the Front buffer void copyBackToFront(); + //! Initialize blit quad. + Standard_EXPORT OpenGl_VertexBuffer* initBlitQuad (const Standard_Boolean theToFlip); + //! Blit image from/to specified buffers. - bool blitBuffers (OpenGl_FrameBuffer* theReadFbo, - OpenGl_FrameBuffer* theDrawFbo); + Standard_EXPORT bool blitBuffers (OpenGl_FrameBuffer* theReadFbo, + OpenGl_FrameBuffer* theDrawFbo, + const Standard_Boolean theToFlip = Standard_False); - virtual Standard_Boolean Activate(); + Standard_EXPORT virtual Standard_Boolean Activate(); void redraw1 (const Graphic3d_CView& theCView, const Aspect_CLayer2d& theCUnderLayer, @@ -344,8 +349,12 @@ protected: //! @name protected fields //! Special flag which is invalidated when myMainSceneFbos can not be blitted for some reason (e.g. driver bugs). Standard_Boolean myHasFboBlit; + //! Flag to draw result image upside-down + Standard_Boolean myToFlipOutput; + //! Vertices for full-screen quad rendering. OpenGl_VertexBuffer myFullScreenQuad; + OpenGl_VertexBuffer myFullScreenQuadFlip; Handle(OpenGl_PrinterContext) myPrintContext; Handle(OpenGl_View) myView; diff --git a/src/TKD3DHost/EXTERNLIB b/src/TKD3DHost/EXTERNLIB new file mode 100644 index 0000000000..c369ad6a61 --- /dev/null +++ b/src/TKD3DHost/EXTERNLIB @@ -0,0 +1,8 @@ +TKernel +TKService +TKMath +TKV3d +TKOpenGl +CSF_OpenGlLibs +CSF_user32 +CSF_gdi32 diff --git a/src/TKD3DHost/FILES b/src/TKD3DHost/FILES new file mode 100644 index 0000000000..ca4f0e567b --- /dev/null +++ b/src/TKD3DHost/FILES @@ -0,0 +1,2 @@ +EXTERNLIB +PACKAGES diff --git a/src/TKD3DHost/PACKAGES b/src/TKD3DHost/PACKAGES new file mode 100644 index 0000000000..a45b8c7df7 --- /dev/null +++ b/src/TKD3DHost/PACKAGES @@ -0,0 +1 @@ +D3DHost diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx index 04642ccb0e..53a1184183 100644 --- a/src/V3d/V3d_View.cxx +++ b/src/V3d/V3d_View.cxx @@ -384,6 +384,16 @@ void V3d_View::Invalidate() const } } +//============================================================================= +//function : IsInvalidated +//purpose : +//============================================================================= +Standard_Boolean V3d_View::IsInvalidated() const +{ + return !MyView->IsDefined() + || MyView->IsInvalidated(); +} + //============================================================================= //function : AutoZFit //purpose : diff --git a/src/V3d/V3d_View.hxx b/src/V3d/V3d_View.hxx index 14fe6203d4..a72cc4888e 100644 --- a/src/V3d/V3d_View.hxx +++ b/src/V3d/V3d_View.hxx @@ -167,7 +167,10 @@ public: //! Invalidates view content but does not redraw it. Standard_EXPORT void Invalidate() const; - + + //! Returns true if cached view content has been invalidated. + Standard_EXPORT Standard_Boolean IsInvalidated() const; + //! Redisplays the view area after esxposure. //! [x,y] define the min xy area position //! [width,height] the size of the area in pixel unit. diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index d616d20415..315ee0bc99 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -660,7 +660,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft #if defined(_WIN32) VT_GetWindow() = new WNT_Window (aTitle.ToCString(), Handle(WNT_WClass)::DownCast (WClass()), - Draw_VirtualWindows ? WS_POPUPWINDOW : WS_OVERLAPPEDWINDOW, + Draw_VirtualWindows ? WS_POPUP : WS_OVERLAPPEDWINDOW, aPxLeft, aPxTop, aPxWidth, aPxHeight, Quantity_NOC_BLACK); diff --git a/src/Visual3d/Visual3d_View.cxx b/src/Visual3d/Visual3d_View.cxx index 8fcf7808ab..1f6a8d41ac 100644 --- a/src/Visual3d/Visual3d_View.cxx +++ b/src/Visual3d/Visual3d_View.cxx @@ -1031,6 +1031,15 @@ void Visual3d_View::Invalidate() myGraphicDriver->Invalidate (MyCView); } +// ======================================================================= +// function : IsInvalidated +// purpose : +// ======================================================================= +Standard_Boolean Visual3d_View::IsInvalidated() const +{ + return myGraphicDriver->IsInvalidated (MyCView); +} + // ======================================================================= // function : Update // purpose : diff --git a/src/Visual3d/Visual3d_View.hxx b/src/Visual3d/Visual3d_View.hxx index 34fec8bb35..f1f356ea00 100644 --- a/src/Visual3d/Visual3d_View.hxx +++ b/src/Visual3d/Visual3d_View.hxx @@ -139,7 +139,10 @@ public: //! Invalidates view content but does not redraw it. Standard_EXPORT void Invalidate(); - + + //! Returns true if cached view content has been invalidated. + Standard_EXPORT Standard_Boolean IsInvalidated() const; + //! Updates screen area in all cases. //! area is given by his xy min corner and size in pixel coordinates Standard_EXPORT void Redraw (const Handle(Visual3d_Layer)& AnUnderLayer, const Handle(Visual3d_Layer)& AnOverLayer, const Standard_Integer x, const Standard_Integer y, const Standard_Integer width, const Standard_Integer height); diff --git a/src/WNT/WNT_Window.cxx b/src/WNT/WNT_Window.cxx index 2badbf77f1..0a415f747c 100644 --- a/src/WNT/WNT_Window.cxx +++ b/src/WNT/WNT_Window.cxx @@ -204,6 +204,11 @@ void WNT_Window::Unmap() const // ======================================================================= Aspect_TypeOfResize WNT_Window::DoResize() const { + if (IsVirtual()) + { + return Aspect_TOR_UNKNOWN; + } + int mask = 0; Aspect_TypeOfResize mode = Aspect_TOR_UNKNOWN; WINDOWPLACEMENT wp; @@ -266,9 +271,14 @@ Aspect_TypeOfResize WNT_Window::DoResize() const // ======================================================================= Quantity_Ratio WNT_Window::Ratio() const { - RECT r; - GetClientRect ((HWND )myHWindow, &r); - return (Quantity_Ratio )((Quantity_Ratio )r.right / (Quantity_Ratio )r.bottom); + if (IsVirtual()) + { + return Quantity_Ratio(aXRight - aXLeft)/ Quantity_Ratio(aYBottom - aYTop); + } + + RECT aRect; + GetClientRect ((HWND )myHWindow, &aRect); + return Quantity_Ratio(aRect.right - aRect.left) / Quantity_Ratio(aRect.bottom - aRect.top); } // ======================================================================= @@ -278,6 +288,15 @@ Quantity_Ratio WNT_Window::Ratio() const void WNT_Window::Position (Standard_Integer& theX1, Standard_Integer& theY1, Standard_Integer& theX2, Standard_Integer& theY2) const { + if (IsVirtual()) + { + theX1 = aXLeft; + theX2 = aXRight; + theY1 = aYTop; + theY2 = aYBottom; + return; + } + RECT aRect; ::GetClientRect ((HWND )myHWindow, &aRect); @@ -307,6 +326,13 @@ void WNT_Window::Position (Standard_Integer& theX1, Standard_Integer& theY1, void WNT_Window::Size (Standard_Integer& theWidth, Standard_Integer& theHeight) const { + if (IsVirtual()) + { + theWidth = aXRight - aXLeft; + theHeight = aYBottom - aYTop; + return; + } + RECT aRect; ::GetClientRect ((HWND )myHWindow, &aRect); theWidth = aRect.right; -- 2.20.1