0024699: Visualization - prototype interoperation of TKOpenGl viewer with Direct3D...
[occt.git] / samples / CSharp / OCCTProxy_D3D / BridgeFBO.cxx
1 #include "BridgeFBO.hxx"
2
3 #include <OpenGl_ArbFBO.hxx>
4
5 #include <Graphic3d_TextureParams.hxx>
6
7 #include <d3dx9.h>
8
9 // list of required libraries
10 #pragma comment(lib, "TKOpenGl.lib")
11 #pragma comment(lib, "opengl32.lib")
12
13 // =======================================================================
14 // function : Init
15 // purpose  :
16 // =======================================================================
17 Standard_Boolean BridgeFBO::Init (const Handle(OpenGl_Context)& theGlContext,
18                                   void*                         theD3DDevice)
19 {
20   const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11;
21   if (aFuncs->wglDXOpenDeviceNV == NULL)
22   {
23     return Standard_False;
24   }
25
26   myGlD3DHandle = aFuncs->wglDXOpenDeviceNV (theD3DDevice);
27   if (myGlD3DHandle == NULL)
28   {
29     std::cerr << "Could not create the GL <-> DirectX Interop" << std::endl;
30     return Standard_False;
31   }
32
33   theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
34   return Standard_True;
35 }
36
37 // =======================================================================
38 // function : Release
39 // purpose  :
40 // =======================================================================
41 void BridgeFBO::Release (OpenGl_Context* theGlContext)
42 {
43   if (myGlD3DHandle != NULL)
44   {
45     const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11;
46     if (myGlD3DSharedColorHandle != NULL)
47     {
48       aFuncs->wglDXUnregisterObjectNV (myGlD3DHandle, myGlD3DSharedColorHandle);
49       myGlD3DSharedColorHandle = NULL;
50     }
51
52     aFuncs->wglDXCloseDeviceNV (myGlD3DHandle);
53     myGlD3DHandle = NULL;
54   }
55
56   OpenGl_FrameBuffer::Release (theGlContext);
57 }
58
59 // =======================================================================
60 // function : RegisterD3DColorBuffer
61 // purpose  :
62 // =======================================================================
63 Standard_Boolean BridgeFBO::RegisterD3DColorBuffer (const Handle(OpenGl_Context)& theGlContext,
64                                                     void*                         theD3DBuffer,
65                                                     void*                         theBufferShare)
66 {
67   const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11;
68   if (myGlD3DSharedColorHandle != NULL)
69   {
70     if (!aFuncs->wglDXUnregisterObjectNV (myGlD3DHandle, myGlD3DSharedColorHandle))
71     {
72       return Standard_False;
73     }
74     myGlD3DSharedColorHandle = NULL;
75   }
76
77   if (!aFuncs->wglDXSetResourceShareHandleNV (theD3DBuffer, theBufferShare))
78   {
79     return Standard_False;
80   }
81
82   myColorTexture->Release (theGlContext.operator->());
83   myColorTexture->Create  (theGlContext);
84
85   myGlD3DSharedColorHandle = aFuncs->wglDXRegisterObjectNV (myGlD3DHandle,
86     theD3DBuffer, myColorTexture->TextureId(), GL_TEXTURE_2D, WGL_ACCESS_WRITE_DISCARD_NV);
87
88   if (myGlD3DSharedColorHandle == NULL)
89   {
90     std::cerr << "Could not register color buffer" << std::endl;
91     return Standard_False;
92   }
93
94   return Standard_True;
95 }
96
97 // =======================================================================
98 // function : Resize
99 // purpose  :
100 // =======================================================================
101 void BridgeFBO::Resize (const Handle(OpenGl_Context)& theGlContext,
102                         int theSizeX,
103                         int theSizeY)
104 {
105   myVPSizeX = theSizeX;
106   myVPSizeY = theSizeY;
107
108   myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8,
109                                GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
110                                myVPSizeX, myVPSizeY, Graphic3d_TOT_2D);
111 }
112
113 // =======================================================================
114 // function : BindBuffer
115 // purpose  :
116 // =======================================================================
117 void BridgeFBO::BindBuffer (const Handle(OpenGl_Context)& theGlContext)
118 {
119   if (myGlD3DSharedColorHandle != NULL)
120   {
121     // Lock for OpenGL
122     const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11;
123     aFuncs->wglDXLockObjectsNV (myGlD3DHandle, 1, &myGlD3DSharedColorHandle);
124   }
125   
126   OpenGl_FrameBuffer::BindBuffer (theGlContext);
127   theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
128                                                 GL_TEXTURE_2D, myColorTexture->TextureId(), 0);
129   theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
130                                                 GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
131   if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
132   {
133     std::cerr << "Invalid FBO can not be bound!\n";
134     Release (theGlContext.operator->());
135   }
136 }
137
138 // =======================================================================
139 // function : UnbindBuffer
140 // purpose  :
141 // =======================================================================
142 void BridgeFBO::UnbindBuffer (const Handle(OpenGl_Context)& theGlContext)
143 {
144   // Unbind the frame buffer
145   OpenGl_FrameBuffer::UnbindBuffer (theGlContext);
146   if (myGlD3DSharedColorHandle != NULL)
147   {
148     // Unlock for Direct3D
149     const OpenGl_GlFunctions* aFuncs = (const OpenGl_GlFunctions* )theGlContext->core11;
150     aFuncs->wglDXUnlockObjectsNV (myGlD3DHandle, 1, &myGlD3DSharedColorHandle);
151   }
152 }