0026392: Visualization, TKD3DHost - provide straight-forward base for integration...
authorkgv <kgv@opencascade.com>
Mon, 20 Jul 2015 08:08:12 +0000 (11:08 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 28 Jul 2015 14:59:10 +0000 (17:59 +0300)
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.

38 files changed:
adm/UDLIST
samples/CSharp/OCCTProxy_D3D/BridgeFBO.cxx [deleted file]
samples/CSharp/OCCTProxy_D3D/BridgeFBO.hxx [deleted file]
samples/CSharp/OCCTProxy_D3D/Direct3DProxy.cpp [deleted file]
samples/CSharp/OCCTProxy_D3D/OCCTProxyD3D.cpp
samples/CSharp/OCCTProxy_D3D/OCCTProxy_D3D.vcproj
samples/CSharp/OCCTProxy_D3D/OCCTProxy_D3D.vcxproj
samples/CSharp/WPF_D3D/D3DViewer.cs
samples/CSharp/WPF_D3D/MainWindow.xaml.cs
samples/CSharp/WPF_D3D/OCCViewer.cs
samples/CSharp/msvc_D3D.bat
src/D3DHost/D3DHost_FrameBuffer.cxx [new file with mode: 0644]
src/D3DHost/D3DHost_FrameBuffer.hxx [new file with mode: 0644]
src/D3DHost/D3DHost_GraphicDriver.cxx [new file with mode: 0644]
src/D3DHost/D3DHost_GraphicDriver.hxx [new file with mode: 0644]
src/D3DHost/D3DHost_Workspace.cxx [new file with mode: 0644]
src/D3DHost/D3DHost_Workspace.hxx [new file with mode: 0644]
src/D3DHost/FILES [new file with mode: 0644]
src/Graphic3d/Graphic3d_GraphicDriver.hxx
src/OS/Visualization.tcl
src/OpenGl/OpenGl_FrameBuffer.cxx
src/OpenGl/OpenGl_GraphicDriver.cxx
src/OpenGl/OpenGl_GraphicDriver.hxx
src/OpenGl/OpenGl_GraphicDriver_7.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_Window.cxx
src/OpenGl/OpenGl_Window.hxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/TKD3DHost/EXTERNLIB [new file with mode: 0644]
src/TKD3DHost/FILES [new file with mode: 0644]
src/TKD3DHost/PACKAGES [new file with mode: 0644]
src/V3d/V3d_View.cxx
src/V3d/V3d_View.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/Visual3d/Visual3d_View.cxx
src/Visual3d/Visual3d_View.hxx
src/WNT/WNT_Window.cxx

index 31d9078..2a97d10 100644 (file)
@@ -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 (file)
index 12fa944..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-#include "BridgeFBO.hxx"
-
-#include <OpenGl_ArbFBO.hxx>
-
-#include <Graphic3d_TextureParams.hxx>
-
-#include <d3dx9.h>
-
-// 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 (file)
index 9860015..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef BRIDGE_FBO_HEADER
-#define BRIDGE_FBO_HEADER
-
-#include <OpenGl_GlCore20.hxx>
-#include <OpenGl_FrameBuffer.hxx>
-
-//! 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 (file)
index 407d93f..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-#include <iostream>
-#include <windows.h>
-#include <d3dx9.h>
-
-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<void**> (&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<void**> (&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<D3DRender*> (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<D3DRender*> (theRender.ToPointer());
-    delete aRender;
-  }
-};
\ No newline at end of file
index aeb5f7c..6ca5c9e 100644 (file)
@@ -1,16 +1,15 @@
-#include "BridgeFBO.hxx"
+#include <windows.h>
 
 // include required OCCT headers
 #include <Standard_Version.hxx>
 #include <Message_ProgressIndicator.hxx>
 //for OCC graphic
-#include <Aspect_DisplayConnection.hxx>
 #include <WNT_Window.hxx>
+#include <WNT_WClass.hxx>
 #include <Graphic3d_CView.hxx>
 #include <Graphic3d_Camera.hxx>
 #include <Graphic3d_TextureParams.hxx>
-#include <OpenGl_GraphicDriver.hxx>
-#include <OpenGl_CView.hxx>
+#include <D3DHost_GraphicDriver.hxx>
 //for object display
 #include <V3d_Viewer.hxx>
 #include <V3d_View.hxx>
 #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")
+
 /// <summary>
 /// 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
   /// </summary>
   /// <param name="theWnd">System.IntPtr that contains the window handle (HWND) of the control</param>
-  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<HWND> (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;
   }
 
-  /// <summary> Initializes OCCT viewer for OpenGL-Direct3D interoperability. </summary>
-  bool InitViewer (System::IntPtr theHWND,
-                   System::IntPtr theD3DDevice)
-  {
-    if (!InitViewer (theHWND))
-    {
-      return false;
-    }
-
-    Graphic3d_CView*       aCView     = reinterpret_cast<Graphic3d_CView*> (myView()->View()->CView());
-    OpenGl_CView*          aCViewGl   = reinterpret_cast<OpenGl_CView*>    (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;
-  }
-
   /// <summary> Resizes custom FBO for Direct3D output. </summary>
-  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<OpenGl_CView*> (reinterpret_cast<Graphic3d_CView*> (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()));
   }
 
   /// <summary>
@@ -730,33 +680,6 @@ public:
   }
 
   /// <summary>
-  ///Create new view
-  /// </summary>
-  /// <param name="theWnd">System.IntPtr that contains the window handle (HWND) of the control</param>
-  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<HWND> (theWnd.ToPointer()));
-    myView()->SetWindow (aWNTWindow);
-    Standard_Integer aWidth = 100, aHeight = 100;
-    aWNTWindow->Size (aWidth, aHeight);
-    if (!aWNTWindow->IsMapped())
-    {
-      aWNTWindow->Map();
-    }
-  }
-
-  /// <summary>
   ///Set AISContext
   /// </summary>
   bool SetAISContext (OCCTProxyD3D^ theViewer)
@@ -1047,7 +970,6 @@ private:
   NCollection_Haft<Handle_V3d_Viewer>             myViewer;
   NCollection_Haft<Handle_V3d_View>               myView;
   NCollection_Haft<Handle_AIS_InteractiveContext> myAISContext;
-  NCollection_Haft<Handle_OpenGl_GraphicDriver>   myGraphicDriver;
-  BridgeFBO*                                      myBridgeFBO;     //!< Provides output to Direct3D buffers
+  NCollection_Haft<Handle_D3DHost_GraphicDriver>  myGraphicDriver;
 
 };
index db2b50a..c4dcc5e 100644 (file)
                        UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
                        >
                        <File
-                               RelativePath=".\BridgeFBO.cxx"
-                               >
-                       </File>
-                       <File
                                RelativePath=".\OCCTProxyD3D.cpp"
                                >
                        </File>
                        Filter="h;hpp;hxx;hm;inl;inc;xsd"
                        UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
                        >
-                       <File
-                               RelativePath=".\BridgeFBO.hxx"
-                               >
-                       </File>
                </Filter>
                <Filter
                        Name="Resource Files"
index e5176b4..a8a9cb5 100644 (file)
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClCompile Include="BridgeFBO.cxx" />
-    <ClCompile Include="Direct3DProxy.cpp" />
     <ClCompile Include="OCCTProxyD3D.cpp" />
   </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="BridgeFBO.hxx" />
-  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
index 4eb2635..a888079 100644 (file)
@@ -11,9 +11,6 @@ namespace IE_WPF_D3D
   /// </summary>
   class D3DViewer
   {
-    /// <summary> Direct3D renderer. </summary>
-    private IntPtr myD3DRender;
-
     /// <summary> Direct3D output image. </summary>
     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
       }
     }
 
-    /// <summary> Initializes Direct3D-OCCT rendering. </summary>
+    /// <summary> Releases Direct3D-OCCT rendering. </summary>
     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;
     }
 
-    /// <summary> Initializes Direct3D-OCCT rendering. </summary>
+    /// <summary> Performs Direct3D-OCCT rendering. </summary>
     private void OnRendering (object sender, EventArgs e)
     {
       UpdateScene ();
     }
 
-    /// <summary> Current size of rendering window. </summary>
-    private WndSize mySize = new WndSize(1, 1);
-
-    /// <summary> Initializes Direct3D-OCCT rendering. </summary>
+    /// <summary> Performs Direct3D-OCCT rendering. </summary>
     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
     /// <summary> Resizes Direct3D surfaces and OpenGL FBO. </summary>
     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);
       }
     }
 
index 9132417..fab4967 100644 (file)
@@ -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);
index 07b9401..64a6917 100644 (file)
@@ -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)
index 1e7d2a3..96d6a2c 100644 (file)
@@ -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 (file)
index 0000000..41415c8
--- /dev/null
@@ -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 <d3d9.h>
+
+#include <D3DHost_FrameBuffer.hxx>
+
+#include <OpenGl_GlCore20.hxx>
+#include <OpenGl_ArbFBO.hxx>
+#include <Standard_ProgramError.hxx>
+#include <TCollection_ExtendedString.hxx>
+
+// =======================================================================
+// 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 (file)
index 0000000..22eed6e
--- /dev/null
@@ -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 <OpenGl_FrameBuffer.hxx>
+
+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 (file)
index 0000000..23ece91
--- /dev/null
@@ -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 <d3d9.h>
+
+#include <D3DHost_GraphicDriver.hxx>
+
+#include <D3DHost_Workspace.hxx>
+#include <OpenGl_CView.hxx>
+#include <Visual3d_View.hxx>
+
+#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 (file)
index 0000000..092017c
--- /dev/null
@@ -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 <OpenGl_GraphicDriver.hxx>
+
+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 (file)
index 0000000..8ad7c85
--- /dev/null
@@ -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 <d3d9.h>
+
+#include <D3DHost_Workspace.hxx>
+
+#include <TCollection_ExtendedString.hxx>
+
+// =======================================================================
+// 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 (file)
index 0000000..fcec6b9
--- /dev/null
@@ -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 <d3d9.h>
+
+#include <OpenGl_Workspace.hxx>
+#include <D3DHost_FrameBuffer.hxx>
+
+//! 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 (file)
index 0000000..fce5140
--- /dev/null
@@ -0,0 +1,6 @@
+D3DHost_GraphicDriver.hxx
+D3DHost_GraphicDriver.cxx
+D3DHost_FrameBuffer.hxx
+D3DHost_FrameBuffer.cxx
+D3DHost_Workspace.hxx
+D3DHost_Workspace.cxx
index 6b2e992..d73b819 100644 (file)
@@ -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;
   
index 1ea1785..74fbe7f 100644 (file)
@@ -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
 }
 ;#
index ba844f6..37bb42c 100644 (file)
@@ -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);
 
index c03c1a4..2321561 100644 (file)
@@ -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;
+}
index b610f89..1269a39 100644 (file)
@@ -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.
index 5c22483..4909320 100644 (file)
@@ -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;
index 1bd43b4..86220b2 100644 (file)
@@ -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);
index c4e9921..668cd8f 100644 (file)
@@ -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;
index f4f5306..1b4616c 100644 (file)
@@ -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:
 
index daaace8..e6de8c2 100644 (file)
@@ -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->());
 }
 
 // =======================================================================
@@ -712,11 +714,52 @@ void OpenGl_Workspace::bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo)
 }
 
 // =======================================================================
+// 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
index 2de1dfe..b205977 100644 (file)
@@ -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 (file)
index 0000000..c369ad6
--- /dev/null
@@ -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 (file)
index 0000000..ca4f0e5
--- /dev/null
@@ -0,0 +1,2 @@
+EXTERNLIB
+PACKAGES
diff --git a/src/TKD3DHost/PACKAGES b/src/TKD3DHost/PACKAGES
new file mode 100644 (file)
index 0000000..a45b8c7
--- /dev/null
@@ -0,0 +1 @@
+D3DHost
index 04642cc..53a1184 100644 (file)
@@ -385,6 +385,16 @@ void V3d_View::Invalidate() const
 }
 
 //=============================================================================
+//function : IsInvalidated
+//purpose  :
+//=============================================================================
+Standard_Boolean V3d_View::IsInvalidated() const
+{
+  return !MyView->IsDefined()
+       || MyView->IsInvalidated();
+}
+
+//=============================================================================
 //function : AutoZFit
 //purpose  :
 //=============================================================================
index 14fe620..a72cc48 100644 (file)
@@ -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.
index d616d20..315ee0b 100644 (file)
@@ -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);
index 8fcf780..1f6a8d4 100644 (file)
@@ -1032,6 +1032,15 @@ void Visual3d_View::Invalidate()
 }
 
 // =======================================================================
+// function : IsInvalidated
+// purpose  :
+// =======================================================================
+Standard_Boolean Visual3d_View::IsInvalidated() const
+{
+  return myGraphicDriver->IsInvalidated (MyCView);
+}
+
+// =======================================================================
 // function : Update
 // purpose  :
 // =======================================================================
index 34fec8b..f1f356e 100644 (file)
@@ -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);
index 2badbf7..0a415f7 100644 (file)
@@ -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;