Adjusting test cases at new structure of OCCT
[occt.git] / samples / CSharp / OCCTProxy_D3D / Direct3DProxy.cpp
1 #include <iostream>
2 #include <windows.h>
3 #include <d3dx9.h>
4
5 using namespace System::Runtime::InteropServices;
6
7 typedef HRESULT (WINAPI *DIRECT3DCREATE9EX)(UINT SDKVersion, IDirect3D9Ex**);
8
9 LRESULT WINAPI MsgProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
10 {
11   return DefWindowProcW (hWnd, msg, wParam, lParam);
12 }
13
14 WNDCLASSEXW THE_WNDCLASS_D3D =
15 {
16   sizeof (WNDCLASSEXW),
17   CS_CLASSDC, MsgProc, NULL, NULL,
18   GetModuleHandle (NULL),
19   NULL, NULL, NULL, NULL, L"D3D", NULL
20 };
21
22 // =======================================================================
23 // function : GetVertexProcessingCaps
24 // purpose  :
25 // =======================================================================
26 DWORD GetVertexProcessingCaps (LPDIRECT3D9 theD3D)
27 {
28   D3DCAPS9 aCaps;
29   return !SUCCEEDED (theD3D->GetDeviceCaps (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &aCaps))
30       || !(aCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
31        ? D3DCREATE_SOFTWARE_VERTEXPROCESSING
32        : D3DCREATE_HARDWARE_VERTEXPROCESSING;
33 }
34
35 //! Encapsulates state of Direct3D renderer.
36 class D3DRender
37 {
38 public:
39
40   D3DRender (int theSizeX = 512,
41              int theSizeY = 512)
42   : D3D (NULL),
43     D3DEx (NULL),
44     D3DDevice (NULL),
45     D3DDeviceEx (NULL),
46     D3DColorSurf (NULL),
47     D3DColorSurfShare (NULL),
48     FuncCreate9Ex (NULL),
49     WinSizeX (theSizeX),
50     WinSizeY (theSizeY)
51   {
52     CheckRegisterClass();
53     WinHandle = CreateWindowW (L"D3D", L"D3D",
54                                WS_OVERLAPPEDWINDOW, 0, 0, 1, 1,
55                                NULL, NULL, THE_WNDCLASS_D3D.hInstance, NULL);
56     Init();
57   }
58
59   ~D3DRender()
60   {
61     // do not release class instance shared between all renderers
62     //UnregisterClass (NULL, THE_WNDCLASS_D3D.hInstance);
63     if (D3DDevice != NULL)
64     {
65       D3DDevice->Release();
66     }
67     if (D3DDeviceEx != NULL)
68     {
69       D3DDeviceEx->Release();
70     }
71     if (D3D != NULL)
72     {
73       D3D->Release();
74     }
75     if (D3DEx != NULL)
76     {
77       D3DEx->Release();
78     }
79     if (D3DColorSurf != NULL)
80     {
81       D3DColorSurf->Release();
82       D3DColorSurfShare = NULL;
83     }
84   }
85
86   //! Creates Direct3D render target.
87   bool CreateRenderTarget()
88   {
89     if (!SetWindowPos (WinHandle, 0, 0, 0, WinSizeX, WinSizeY, 0))
90     {
91       return false;
92     }
93
94     if (D3DColorSurf != NULL)
95     {
96       D3DColorSurf->Release();
97       D3DColorSurfShare = NULL;
98     }
99
100     // Note: Render target surface should be lockable on
101     // Windows XP and non-lockable on Windows Vista or higher
102     if (FAILED (D3DDevice->CreateRenderTarget (WinSizeX, WinSizeY,
103                                                D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FuncCreate9Ex != NULL,
104                                                &D3DColorSurf, FuncCreate9Ex == NULL ? NULL : &D3DColorSurfShare)))
105     {
106       return false;
107     }
108
109     D3DDevice->SetRenderTarget (0, D3DColorSurf);
110     return true;
111   }
112
113 private:
114
115   void Init()
116   {
117     // Vista requires the D3D "Ex" functions for optimal performance.
118     // The Ex functions are only supported with WDDM drivers, so they will not be available on XP.
119     HMODULE aD3D9 = GetModuleHandleW (L"d3d9");
120     FuncCreate9Ex = (DIRECT3DCREATE9EX )GetProcAddress (aD3D9, "Direct3DCreate9Ex");
121     
122     // Set up the structure used to create the D3DDevice
123     D3DPRESENT_PARAMETERS aParams;
124     ZeroMemory (&aParams, sizeof(aParams));
125     aParams.Windowed         = TRUE;
126     aParams.BackBufferHeight = 1;
127     aParams.BackBufferWidth  = 1;
128     aParams.SwapEffect       = D3DSWAPEFFECT_DISCARD;
129     aParams.BackBufferFormat = D3DFMT_X8R8G8B8;
130     (FuncCreate9Ex != NULL) ? InitializeD3DEx (aParams) : InitializeD3D (aParams);
131   }
132   
133   bool InitializeD3D (D3DPRESENT_PARAMETERS theParams)
134   {
135     D3D = Direct3DCreate9 (D3D_SDK_VERSION);
136     if (D3D == NULL)
137       return false;
138
139     DWORD aVertProcessCaps = GetVertexProcessingCaps (D3D);
140     HRESULT aResult = D3D->CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, WinHandle,
141                                          aVertProcessCaps | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
142                                          &theParams, &D3DDevice);
143     return SUCCEEDED (aResult);
144   }
145   
146   bool InitializeD3DEx (D3DPRESENT_PARAMETERS theParams)
147   {
148     if (FAILED (FuncCreate9Ex (D3D_SDK_VERSION, &D3DEx))
149      || FAILED (D3DEx->QueryInterface (__uuidof (IDirect3D9), reinterpret_cast<void**> (&D3D))))
150     {
151       return false;
152     }
153
154     DWORD aVertProcessCaps = GetVertexProcessingCaps (D3D);
155     if (FAILED (D3DEx->CreateDeviceEx (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, WinHandle,
156                                        aVertProcessCaps | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
157                                        &theParams, NULL, &D3DDeviceEx)))
158       return false;
159
160     return SUCCEEDED (D3DDeviceEx->QueryInterface (__uuidof (IDirect3DDevice9), reinterpret_cast<void**> (&D3DDevice)));
161   }
162
163   static void CheckRegisterClass()
164   {
165     static bool isRegistered = false;
166     if (!isRegistered)
167     {
168       RegisterClassExW (&THE_WNDCLASS_D3D);
169       isRegistered = true;
170     }
171   }
172
173 public:
174
175   LPDIRECT3D9         D3D;
176   LPDIRECT3D9EX       D3DEx;
177   LPDIRECT3DDEVICE9   D3DDevice;
178   LPDIRECT3DDEVICE9EX D3DDeviceEx;
179
180   LPDIRECT3DSURFACE9  D3DColorSurf;
181   HANDLE              D3DColorSurfShare;
182
183   DIRECT3DCREATE9EX   FuncCreate9Ex;
184
185   HWND                WinHandle;
186   INT                 WinSizeX;
187   INT                 WinSizeY;
188
189 };
190
191 public ref struct WndSize
192 {
193 public:
194
195   WndSize(int theSizeX, int theSizeY)
196   {
197     mySize = new SIZE();
198     mySize->cx = theSizeX;
199     mySize->cy = theSizeY;
200   }
201
202   ~WndSize()
203   {
204     delete mySize;
205   }
206
207   property int cx
208   {
209     int get() { return mySize->cx; }
210   }
211
212   property int cy
213   {
214     int get() { return mySize->cy; }
215   }
216
217   LPSIZE GetPointer()
218   {
219     return mySize;
220   }
221
222 private:
223
224   LPSIZE mySize;
225 };
226
227 public ref class Direct3DProxy
228 {
229 public :
230
231   Direct3DProxy()
232   {
233     //
234   }
235
236   // =======================================================================
237   // function : InitializeScene
238   // purpose  :
239   // =======================================================================
240   static System::IntPtr InitRender ([Out] System::IntPtr% theWinHandle,
241                                     [Out] System::IntPtr% theD3DDevice)
242   {
243     D3DRender* aRender = new D3DRender();
244     theWinHandle = System::IntPtr(aRender->WinHandle);
245     theD3DDevice = System::IntPtr(aRender->D3DDevice);
246
247     return System::IntPtr(aRender);
248   }
249
250   // =======================================================================
251   // function : ResizeWindow
252   // purpose  :
253   // =======================================================================
254   static void ResizeWindow ([In]  System::IntPtr% theRender,
255                             [In]  WndSize^%       theWndSize,
256                             [Out] System::IntPtr% theColorSurf,
257                             [Out] System::IntPtr% theColorSurfShare)
258   {
259     D3DRender* aRender = reinterpret_cast<D3DRender*> (theRender.ToPointer());
260     LPSIZE aSize = theWndSize->GetPointer();
261     aRender->WinSizeX = aSize->cx;
262     aRender->WinSizeY = aSize->cy;
263     aRender->CreateRenderTarget();
264
265     theColorSurf      = System::IntPtr(aRender->D3DColorSurf);
266     theColorSurfShare = System::IntPtr(aRender->D3DColorSurfShare);
267   }
268
269   // =======================================================================
270   // function : ReleaseRender
271   // purpose  :
272   // =======================================================================
273   static void ReleaseRender ([In] System::IntPtr% theRender)
274   {
275     D3DRender* aRender = reinterpret_cast<D3DRender*> (theRender.ToPointer());
276     delete aRender;
277   }
278 };