- Clean up all the D3D COM handling (but the underlaying code is still
[wine/multimedia.git] / dlls / ddraw / d3dviewport.c
blob3f4c47a42832debfbf3196f4c64107e7dc262100
1 /* Direct3D Viewport
2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the implementation of Direct3DViewport2.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
22 #include "windef.h"
23 #include "winerror.h"
24 #include "wine/obj_base.h"
25 #include "ddraw.h"
26 #include "d3d.h"
27 #include "wine/debug.h"
29 #include "d3d_private.h"
30 #include "mesa_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
34 static void activate(IDirect3DViewportImpl* This) {
35 IDirect3DLightImpl* light;
37 /* Activate all the lights associated with this context */
38 light = This->lights;
40 while (light != NULL) {
41 light->activate(light);
42 light = light->next;
47 static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp)
49 TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
50 lpvp->dwSize, lpvp->dwX, lpvp->dwY);
51 TRACE(" - dwWidth = %ld dwHeight = %ld\n",
52 lpvp->dwWidth, lpvp->dwHeight);
53 TRACE(" - dvScaleX = %f dvScaleY = %f\n",
54 lpvp->dvScaleX, lpvp->dvScaleY);
55 TRACE(" - dvMaxX = %f dvMaxY = %f\n",
56 lpvp->dvMaxX, lpvp->dvMaxY);
57 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
58 lpvp->dvMinZ, lpvp->dvMaxZ);
61 static void _dump_D3DVIEWPORT2(D3DVIEWPORT2 *lpvp)
63 TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n",
64 lpvp->dwSize, lpvp->dwX, lpvp->dwY);
65 TRACE(" - dwWidth = %ld dwHeight = %ld\n",
66 lpvp->dwWidth, lpvp->dwHeight);
67 TRACE(" - dvClipX = %f dvClipY = %f\n",
68 lpvp->dvClipX, lpvp->dvClipY);
69 TRACE(" - dvClipWidth = %f dvClipHeight = %f\n",
70 lpvp->dvClipWidth, lpvp->dvClipHeight);
71 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
72 lpvp->dvMinZ, lpvp->dvMaxZ);
75 HRESULT WINAPI
76 Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface,
77 REFIID riid,
78 LPVOID* obp)
80 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
81 TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
83 *obp = NULL;
85 if ( IsEqualGUID(&IID_IUnknown, riid) ||
86 IsEqualGUID(&IID_IDirect3DViewport, riid) ||
87 IsEqualGUID(&IID_IDirect3DViewport2, riid) ||
88 IsEqualGUID(&IID_IDirect3DViewport3, riid) ) {
89 IDirect3DViewport3_AddRef(ICOM_INTERFACE(This, IDirect3DViewport3));
90 *obp = ICOM_INTERFACE(This, IDirect3DViewport3);
91 TRACE(" Creating IDirect3DViewport1/2/3 interface %p\n", *obp);
92 return S_OK;
94 FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
95 return OLE_E_ENUM_NOMORE;
98 ULONG WINAPI
99 Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface)
101 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
102 FIXME("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
103 return ++(This->ref);
106 ULONG WINAPI
107 Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface)
109 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
110 FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
111 if (!--(This->ref)) {
112 HeapFree(GetProcessHeap(), 0, This);
113 return 0;
115 return This->ref;
119 HRESULT WINAPI
120 Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface,
121 LPDIRECT3D lpDirect3D)
123 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
124 TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
125 return DD_OK;
128 HRESULT WINAPI
129 Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface,
130 LPD3DVIEWPORT lpData)
132 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
133 DWORD dwSize;
134 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
135 if (This->use_vp2 != 0) {
136 ERR(" Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
137 return DDERR_INVALIDPARAMS;
139 dwSize = lpData->dwSize;
140 memset(lpData, 0, dwSize);
141 memcpy(lpData, &(This->viewports.vp1), dwSize);
143 if (TRACE_ON(ddraw)) {
144 TRACE(" returning D3DVIEWPORT :");
145 _dump_D3DVIEWPORT(lpData);
148 return DD_OK;
151 HRESULT WINAPI
152 Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
153 LPD3DVIEWPORT lpData)
155 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
156 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
158 if (TRACE_ON(ddraw)) {
159 TRACE(" getting D3DVIEWPORT :\n");
160 _dump_D3DVIEWPORT(lpData);
163 This->use_vp2 = 0;
164 memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
165 memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
166 return DD_OK;
169 HRESULT WINAPI
170 Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface,
171 DWORD dwVertexCount,
172 LPD3DTRANSFORMDATA lpData,
173 DWORD dwFlags,
174 LPDWORD lpOffScreen)
176 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
177 FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This, iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
178 return DD_OK;
181 HRESULT WINAPI
182 Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface,
183 DWORD dwElementCount,
184 LPD3DLIGHTDATA lpData)
186 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
187 FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData);
188 return DD_OK;
191 HRESULT WINAPI
192 Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface,
193 D3DMATERIALHANDLE hMat)
195 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
196 FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, (DWORD) hMat);
197 return DD_OK;
200 HRESULT WINAPI
201 Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface,
202 LPD3DMATERIALHANDLE lphMat,
203 LPBOOL lpValid)
205 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
206 FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lphMat, lpValid);
207 return DD_OK;
210 HRESULT WINAPI
211 Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
212 LPDIRECTDRAWSURFACE lpDDSurface)
214 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
215 FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDSurface);
216 return DD_OK;
219 HRESULT WINAPI
220 Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
221 LPDIRECTDRAWSURFACE* lplpDDSurface,
222 LPBOOL lpValid)
224 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
225 FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDSurface, lpValid);
226 return DD_OK;
229 HRESULT WINAPI
230 Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
231 DWORD dwCount,
232 LPD3DRECT lpRects,
233 DWORD dwFlags)
235 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
236 FIXME("(%p/%p)->(%08lx,%p,%08lx): stub!\n", This, iface, dwCount, lpRects, dwFlags);
237 return DD_OK;
240 HRESULT WINAPI
241 Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface,
242 LPDIRECT3DLIGHT lpDirect3DLight)
244 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
245 IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
247 TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
249 /* Add the light in the 'linked' chain */
250 lpDirect3DLightImpl->next = This->lights;
251 This->lights = lpDirect3DLightImpl;
253 /* If active, activate the light */
254 if (This->active_device != NULL) {
255 lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
258 return DD_OK;
261 HRESULT WINAPI
262 Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
263 LPDIRECT3DLIGHT lpDirect3DLight)
265 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
266 IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
267 IDirect3DLightImpl *cur_light, *prev_light = NULL;
269 TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
270 cur_light = This->lights;
271 while (cur_light != NULL) {
272 if (cur_light == lpDirect3DLightImpl) {
273 lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl);
274 if (prev_light == NULL) This->lights = cur_light->next;
275 else prev_light->next = cur_light->next;
276 return DD_OK;
278 prev_light = cur_light;
279 cur_light = cur_light->next;
281 return DDERR_INVALIDPARAMS;
284 HRESULT WINAPI
285 Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface,
286 LPDIRECT3DLIGHT lpDirect3DLight,
287 LPDIRECT3DLIGHT* lplpDirect3DLight,
288 DWORD dwFlags)
290 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
291 FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
292 return DD_OK;
295 HRESULT WINAPI
296 Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface,
297 LPD3DVIEWPORT2 lpData)
299 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
300 DWORD dwSize;
301 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
302 if (This->use_vp2 != 1) {
303 ERR(" Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
304 return DDERR_INVALIDPARAMS;
306 dwSize = lpData->dwSize;
307 memset(lpData, 0, dwSize);
308 memcpy(lpData, &(This->viewports.vp2), dwSize);
310 if (TRACE_ON(ddraw)) {
311 TRACE(" returning D3DVIEWPORT2 :");
312 _dump_D3DVIEWPORT2(lpData);
315 return DD_OK;
318 HRESULT WINAPI
319 Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
320 LPD3DVIEWPORT2 lpData)
322 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
323 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
325 if (TRACE_ON(ddraw)) {
326 TRACE(" getting D3DVIEWPORT2 :\n");
327 _dump_D3DVIEWPORT2(lpData);
330 This->use_vp2 = 1;
331 memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
332 memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
333 return DD_OK;
336 HRESULT WINAPI
337 Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
338 LPDIRECTDRAWSURFACE4 lpDDS)
340 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
341 FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS);
342 return DD_OK;
345 HRESULT WINAPI
346 Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
347 LPDIRECTDRAWSURFACE4* lplpDDS,
348 LPBOOL lpValid)
350 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
351 FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
352 return DD_OK;
355 HRESULT WINAPI
356 Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
357 DWORD dwCount,
358 LPD3DRECT lpRects,
359 DWORD dwFlags,
360 DWORD dwColor,
361 D3DVALUE dvZ,
362 DWORD dwStencil)
364 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
365 FIXME("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx): stub!\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
366 return DD_OK;
369 HRESULT WINAPI
370 GL_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
371 DWORD dwCount,
372 LPD3DRECT lpRects,
373 DWORD dwFlags)
375 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
376 GLboolean ztest;
378 TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
380 if (dwCount != 1) {
381 WARN(" Warning, this function only for now clears the whole screen...\n");
384 /* Clears the screen */
385 ENTER_GL();
386 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
387 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
388 glClear(((dwFlags & D3DCLEAR_TARGET) ? GL_COLOR_BUFFER_BIT : 0) |
389 ((dwFlags & D3DCLEAR_ZBUFFER) ? GL_DEPTH_BUFFER_BIT : 0));
390 glDepthMask(ztest);
391 LEAVE_GL();
393 return DD_OK;
396 HRESULT WINAPI
397 GL_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
398 DWORD dwCount,
399 LPD3DRECT lpRects,
400 DWORD dwFlags,
401 DWORD dwColor,
402 D3DVALUE dvZ,
403 DWORD dwStencil)
405 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
406 GLboolean ztest;
407 GLfloat old_z_clear_value;
408 GLbitfield bitfield = 0;
409 GLint old_stencil_clear_value;
410 GLfloat old_color_clear_value[4];
412 TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
414 if (dwCount != 1) {
415 WARN(" Warning, this function only for now clears the whole screen...\n");
418 /* Clears the screen */
419 ENTER_GL();
420 if (dwFlags & D3DCLEAR_ZBUFFER) {
421 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
422 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
423 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
424 glClearDepth(dvZ);
425 TRACE(" Depth value : %f\n", dvZ);
426 bitfield |= GL_DEPTH_BUFFER_BIT;
428 if (dwFlags & D3DCLEAR_STENCIL) {
429 bitfield |= GL_STENCIL_BUFFER_BIT;
430 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
431 glClearStencil(dwStencil);
432 TRACE(" Stencil value : %ld\n", dwStencil);
434 if (dwFlags & D3DCLEAR_TARGET) {
435 bitfield |= GL_COLOR_BUFFER_BIT;
436 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
437 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
438 ((dwColor >> 8) & 0xFF) / 255.0,
439 ((dwColor >> 0) & 0xFF) / 255.0,
440 ((dwColor >> 24) & 0xFF) / 255.0);
441 TRACE("Color value (ARGB) : %08lx", dwColor);
444 glClear(bitfield);
446 if (dwFlags & D3DCLEAR_ZBUFFER) {
447 glDepthMask(ztest);
448 glClearDepth(old_z_clear_value);
450 if (dwFlags & D3DCLEAR_STENCIL) {
451 bitfield |= GL_STENCIL_BUFFER_BIT;
452 glClearStencil(old_stencil_clear_value);
454 if (dwFlags & D3DCLEAR_TARGET) {
455 bitfield |= GL_COLOR_BUFFER_BIT;
456 glClearColor(old_color_clear_value[0],
457 old_color_clear_value[1],
458 old_color_clear_value[2],
459 old_color_clear_value[3]);
462 LEAVE_GL();
464 return DD_OK;
467 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
468 # define XCAST(fun) (typeof(VTABLE_IDirect3DViewport3.fun))
469 #else
470 # define XCAST(fun) (void*)
471 #endif
473 ICOM_VTABLE(IDirect3DViewport3) VTABLE_IDirect3DViewport3 =
475 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
476 XCAST(QueryInterface) Main_IDirect3DViewportImpl_3_2_1_QueryInterface,
477 XCAST(AddRef) Main_IDirect3DViewportImpl_3_2_1_AddRef,
478 XCAST(Release) Main_IDirect3DViewportImpl_3_2_1_Release,
479 XCAST(Initialize) Main_IDirect3DViewportImpl_3_2_1_Initialize,
480 XCAST(GetViewport) Main_IDirect3DViewportImpl_3_2_1_GetViewport,
481 XCAST(SetViewport) Main_IDirect3DViewportImpl_3_2_1_SetViewport,
482 XCAST(TransformVertices) Main_IDirect3DViewportImpl_3_2_1_TransformVertices,
483 XCAST(LightElements) Main_IDirect3DViewportImpl_3_2_1_LightElements,
484 XCAST(SetBackground) Main_IDirect3DViewportImpl_3_2_1_SetBackground,
485 XCAST(GetBackground) Main_IDirect3DViewportImpl_3_2_1_GetBackground,
486 XCAST(SetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth,
487 XCAST(GetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth,
488 XCAST(Clear) GL_IDirect3DViewportImpl_3_2_1_Clear,
489 XCAST(AddLight) Main_IDirect3DViewportImpl_3_2_1_AddLight,
490 XCAST(DeleteLight) Main_IDirect3DViewportImpl_3_2_1_DeleteLight,
491 XCAST(NextLight) Main_IDirect3DViewportImpl_3_2_1_NextLight,
492 XCAST(GetViewport2) Main_IDirect3DViewportImpl_3_2_GetViewport2,
493 XCAST(SetViewport2) Main_IDirect3DViewportImpl_3_2_SetViewport2,
494 XCAST(SetBackgroundDepth2) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2,
495 XCAST(GetBackgroundDepth2) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2,
496 XCAST(Clear2) GL_IDirect3DViewportImpl_3_Clear2,
499 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
500 #undef XCAST
501 #endif
506 HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirect3DImpl *d3d)
508 IDirect3DViewportImpl *object;
510 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
511 if (object == NULL) return DDERR_OUTOFMEMORY;
513 object->ref = 1;
514 object->d3d = d3d;
515 object->activate = activate;
516 object->use_vp2 = 0xFF;
517 object->next = NULL;
518 object->lights = NULL;
520 ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);
522 *obj = object;
524 TRACE(" creating implementation at %p.\n", *obj);
526 return D3D_OK;