2 * Copyright 2000 Marcus Meissner
3 * Copyright 2000 Peter Hunnisett
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
41 #include "ddraw_private.h"
42 #include "d3d_private.h"
43 #include "opengl_private.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
50 GL_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface
,
51 LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback
,
54 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D
, iface
);
55 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpEnumDevicesCallback
, lpUserArg
);
57 /* Call functions defined in d3ddevices.c */
58 if (d3ddevice_enumerate(lpEnumDevicesCallback
, lpUserArg
, 1) != D3DENUMRET_OK
)
65 GL_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface
,
66 LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback
,
69 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D2
, iface
);
70 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpEnumDevicesCallback
, lpUserArg
);
72 /* Call functions defined in d3ddevices.c */
73 if (d3ddevice_enumerate(lpEnumDevicesCallback
, lpUserArg
, 2) != D3DENUMRET_OK
)
80 GL_IDirect3DImpl_3_EnumDevices(LPDIRECT3D3 iface
,
81 LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback
,
84 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D3
, iface
);
85 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpEnumDevicesCallback
, lpUserArg
);
87 /* Call functions defined in d3ddevices.c */
88 if (d3ddevice_enumerate(lpEnumDevicesCallback
, lpUserArg
, 3) != D3DENUMRET_OK
)
95 GL_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface
,
96 LPDIRECT3DLIGHT
* lplpDirect3DLight
,
99 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D3
, iface
);
100 IDirect3DLightImpl
*d3dlimpl
;
103 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lplpDirect3DLight
, pUnkOuter
);
105 ret_value
= d3dlight_create(&d3dlimpl
, This
);
106 *lplpDirect3DLight
= ICOM_INTERFACE(d3dlimpl
, IDirect3DLight
);
112 GL_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface
,
113 LPDIRECT3DMATERIAL3
* lplpDirect3DMaterial3
,
116 IDirect3DMaterialImpl
*D3Dmat_impl
;
118 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D3
, iface
);
120 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lplpDirect3DMaterial3
, pUnkOuter
);
121 ret_value
= d3dmaterial_create(&D3Dmat_impl
, This
);
123 *lplpDirect3DMaterial3
= ICOM_INTERFACE(D3Dmat_impl
, IDirect3DMaterial3
);
129 GL_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface
,
130 LPDIRECT3DVIEWPORT3
* lplpD3DViewport3
,
133 IDirect3DViewportImpl
*D3Dvp_impl
;
135 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D3
, iface
);
137 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lplpD3DViewport3
, pUnkOuter
);
138 ret_value
= d3dviewport_create(&D3Dvp_impl
, This
);
140 *lplpD3DViewport3
= ICOM_INTERFACE(D3Dvp_impl
, IDirect3DViewport3
);
146 create_device_helper(IDirectDrawImpl
*This
,
148 IDirectDrawSurfaceImpl
*lpDDS
,
151 IDirect3DDeviceImpl
*lpd3ddev
;
154 ret_value
= d3ddevice_create(&lpd3ddev
, This
, lpDDS
, version
);
155 if (FAILED(ret_value
)) return ret_value
;
158 (IsEqualGUID(&IID_D3DDEVICE_OpenGL
, iid
)) ||
159 (IsEqualGUID(&IID_IDirect3DHALDevice
, iid
)) ||
160 (IsEqualGUID(&IID_IDirect3DTnLHalDevice
, iid
)) ||
161 (IsEqualGUID(&IID_IDirect3DRGBDevice
, iid
)) ||
162 (IsEqualGUID(&IID_IDirect3DRefDevice
, iid
))) {
165 *obj
= ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice
);
166 TRACE(" returning OpenGL D3DDevice %p.\n", *obj
);
170 *obj
= ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice2
);
171 TRACE(" returning OpenGL D3DDevice2 %p.\n", *obj
);
175 *obj
= ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice3
);
176 TRACE(" returning OpenGL D3DDevice3 %p.\n", *obj
);
180 *obj
= ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice7
);
181 TRACE(" returning OpenGL D3DDevice7 %p.\n", *obj
);
187 ERR(" Interface unknown when creating D3DDevice (%s)\n", debugstr_guid(iid
));
188 IDirect3DDevice7_Release(ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice7
));
189 return DDERR_INVALIDPARAMS
;
194 GL_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface
,
196 LPDIRECTDRAWSURFACE lpDDS
,
197 LPDIRECT3DDEVICE2
* lplpD3DDevice2
)
199 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D2
, iface
);
200 IDirectDrawSurfaceImpl
*ddsurfaceimpl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface3
, lpDDS
);
201 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_guid(rclsid
), lpDDS
, lplpD3DDevice2
);
202 return create_device_helper(This
, rclsid
, ddsurfaceimpl
, (void **) lplpD3DDevice2
, 2);
206 GL_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface
,
208 LPDIRECTDRAWSURFACE4 lpDDS
,
209 LPDIRECT3DDEVICE3
* lplpD3DDevice3
,
212 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D3
, iface
);
213 IDirectDrawSurfaceImpl
*ddsurfaceimpl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, lpDDS
);
214 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_guid(rclsid
), lpDDS
, lplpD3DDevice3
);
215 return create_device_helper(This
, rclsid
, ddsurfaceimpl
, (void **) lplpD3DDevice3
, 3);
219 GL_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface
,
220 LPD3DFINDDEVICESEARCH lpD3DDFS
,
221 LPD3DFINDDEVICERESULT lpD3DFDR
)
223 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D3
, iface
);
224 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpD3DDFS
, lpD3DFDR
);
225 return d3ddevice_find(This
, lpD3DDFS
, lpD3DFDR
);
229 GL_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface
,
231 LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback
,
234 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D7
, iface
);
235 DDPIXELFORMAT pformat
;
237 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_guid(riidDevice
), lpEnumCallback
, lpContext
);
239 memset(&pformat
, 0, sizeof(pformat
));
240 pformat
.dwSize
= sizeof(DDPIXELFORMAT
);
241 pformat
.dwFourCC
= 0;
242 TRACE("Enumerating dummy ZBuffer format (16 bits)\n");
243 pformat
.dwFlags
= DDPF_ZBUFFER
;
244 pformat
.u1
.dwZBufferBitDepth
= 16;
245 pformat
.u3
.dwZBitMask
= 0x0000FFFF;
246 pformat
.u5
.dwRGBZBitMask
= 0x0000FFFF;
248 /* Whatever the return value, stop here.. */
249 lpEnumCallback(&pformat
, lpContext
);
255 GL_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface
,
256 LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback
,
259 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D7
, iface
);
260 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpEnumDevicesCallback
, lpUserArg
);
262 if (d3ddevice_enumerate7(lpEnumDevicesCallback
, lpUserArg
) != D3DENUMRET_OK
)
269 GL_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface
,
271 LPDIRECTDRAWSURFACE7 lpDDS
,
272 LPDIRECT3DDEVICE7
* lplpD3DDevice
)
274 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D7
, iface
);
275 IDirectDrawSurfaceImpl
*ddsurfaceimpl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, lpDDS
);
276 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_guid(rclsid
), lpDDS
, lplpD3DDevice
);
277 return create_device_helper(This
, rclsid
, ddsurfaceimpl
, (void **) lplpD3DDevice
, 7);
281 GL_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface
,
282 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc
,
283 LPDIRECT3DVERTEXBUFFER7
* lplpD3DVertBuf
,
286 ICOM_THIS_FROM(IDirectDrawImpl
, IDirect3D7
, iface
);
287 IDirect3DVertexBufferImpl
*vbimpl
;
290 TRACE("(%p/%p)->(%p,%p,%08lx)\n", This
, iface
, lpD3DVertBufDesc
, lplpD3DVertBuf
, dwFlags
);
292 res
= d3dvertexbuffer_create(&vbimpl
, This
, lpD3DVertBufDesc
, dwFlags
);
294 *lplpD3DVertBuf
= ICOM_INTERFACE(vbimpl
, IDirect3DVertexBuffer7
);
299 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
300 # define XCAST(fun) (typeof(VTABLE_IDirect3D7.fun))
302 # define XCAST(fun) (void*)
305 static const IDirect3D7Vtbl VTABLE_IDirect3D7
=
307 XCAST(QueryInterface
) Thunk_IDirect3DImpl_7_QueryInterface
,
308 XCAST(AddRef
) Thunk_IDirect3DImpl_7_AddRef
,
309 XCAST(Release
) Thunk_IDirect3DImpl_7_Release
,
310 XCAST(EnumDevices
) GL_IDirect3DImpl_7_EnumDevices
,
311 XCAST(CreateDevice
) GL_IDirect3DImpl_7_CreateDevice
,
312 XCAST(CreateVertexBuffer
) GL_IDirect3DImpl_7_3T_CreateVertexBuffer
,
313 XCAST(EnumZBufferFormats
) GL_IDirect3DImpl_7_3T_EnumZBufferFormats
,
314 XCAST(EvictManagedTextures
) Main_IDirect3DImpl_7_3T_EvictManagedTextures
,
317 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
322 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
323 # define XCAST(fun) (typeof(VTABLE_IDirect3D3.fun))
325 # define XCAST(fun) (void*)
328 static const IDirect3D3Vtbl VTABLE_IDirect3D3
=
330 XCAST(QueryInterface
) Thunk_IDirect3DImpl_3_QueryInterface
,
331 XCAST(AddRef
) Thunk_IDirect3DImpl_3_AddRef
,
332 XCAST(Release
) Thunk_IDirect3DImpl_3_Release
,
333 XCAST(EnumDevices
) GL_IDirect3DImpl_3_EnumDevices
,
334 XCAST(CreateLight
) GL_IDirect3DImpl_3_2T_1T_CreateLight
,
335 XCAST(CreateMaterial
) GL_IDirect3DImpl_3_2T_1T_CreateMaterial
,
336 XCAST(CreateViewport
) GL_IDirect3DImpl_3_2T_1T_CreateViewport
,
337 XCAST(FindDevice
) GL_IDirect3DImpl_3_2T_1T_FindDevice
,
338 XCAST(CreateDevice
) GL_IDirect3DImpl_3_CreateDevice
,
339 XCAST(CreateVertexBuffer
) Thunk_IDirect3DImpl_3_CreateVertexBuffer
,
340 XCAST(EnumZBufferFormats
) Thunk_IDirect3DImpl_3_EnumZBufferFormats
,
341 XCAST(EvictManagedTextures
) Thunk_IDirect3DImpl_3_EvictManagedTextures
,
344 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
349 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
350 # define XCAST(fun) (typeof(VTABLE_IDirect3D2.fun))
352 # define XCAST(fun) (void*)
355 static const IDirect3D2Vtbl VTABLE_IDirect3D2
=
357 XCAST(QueryInterface
) Thunk_IDirect3DImpl_2_QueryInterface
,
358 XCAST(AddRef
) Thunk_IDirect3DImpl_2_AddRef
,
359 XCAST(Release
) Thunk_IDirect3DImpl_2_Release
,
360 XCAST(EnumDevices
) GL_IDirect3DImpl_2_EnumDevices
,
361 XCAST(CreateLight
) Thunk_IDirect3DImpl_2_CreateLight
,
362 XCAST(CreateMaterial
) Thunk_IDirect3DImpl_2_CreateMaterial
,
363 XCAST(CreateViewport
) Thunk_IDirect3DImpl_2_CreateViewport
,
364 XCAST(FindDevice
) Thunk_IDirect3DImpl_2_FindDevice
,
365 XCAST(CreateDevice
) GL_IDirect3DImpl_2_CreateDevice
,
368 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
373 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
374 # define XCAST(fun) (typeof(VTABLE_IDirect3D.fun))
376 # define XCAST(fun) (void*)
379 static const IDirect3DVtbl VTABLE_IDirect3D
=
381 XCAST(QueryInterface
) Thunk_IDirect3DImpl_1_QueryInterface
,
382 XCAST(AddRef
) Thunk_IDirect3DImpl_1_AddRef
,
383 XCAST(Release
) Thunk_IDirect3DImpl_1_Release
,
384 XCAST(Initialize
) Main_IDirect3DImpl_1_Initialize
,
385 XCAST(EnumDevices
) GL_IDirect3DImpl_1_EnumDevices
,
386 XCAST(CreateLight
) Thunk_IDirect3DImpl_1_CreateLight
,
387 XCAST(CreateMaterial
) Thunk_IDirect3DImpl_1_CreateMaterial
,
388 XCAST(CreateViewport
) Thunk_IDirect3DImpl_1_CreateViewport
,
389 XCAST(FindDevice
) Thunk_IDirect3DImpl_1_FindDevice
,
392 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
396 static HRESULT
d3d_add_device(IDirectDrawImpl
*This
, IDirect3DDeviceImpl
*device
)
398 if (This
->current_device
== NULL
) {
399 /* Create delayed textures now that we have an OpenGL context...
400 For that, go through all surface attached to our DDraw object and create
401 OpenGL textures for all textures.. */
402 IDirectDrawSurfaceImpl
*surf
= This
->surfaces
;
404 while (surf
!= NULL
) {
405 if (surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
) {
406 /* Found a texture.. Now create the OpenGL part */
407 d3dtexture_create(This
, surf
, FALSE
, surf
->mip_main
);
409 surf
= surf
->next_ddraw
;
412 /* For the moment, only one device 'supported'... */
413 This
->current_device
= device
;
418 static HRESULT
d3d_remove_device(IDirectDrawImpl
*This
, IDirect3DDeviceImpl
*device
)
420 This
->current_device
= NULL
;
424 HRESULT
direct3d_create(IDirectDrawImpl
*This
)
426 IDirect3DGLImpl
*globject
;
428 globject
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DGLImpl
));
429 if (globject
== NULL
) return DDERR_OUTOFMEMORY
;
431 This
->d3d_create_texture
= d3dtexture_create
;
432 This
->d3d_added_device
= d3d_add_device
;
433 This
->d3d_removed_device
= d3d_remove_device
;
435 ICOM_INIT_INTERFACE(This
, IDirect3D
, VTABLE_IDirect3D
);
436 ICOM_INIT_INTERFACE(This
, IDirect3D2
, VTABLE_IDirect3D2
);
437 ICOM_INIT_INTERFACE(This
, IDirect3D3
, VTABLE_IDirect3D3
);
438 ICOM_INIT_INTERFACE(This
, IDirect3D7
, VTABLE_IDirect3D7
);
440 This
->d3d_private
= globject
;
442 TRACE(" creating OpenGL private storage at %p.\n", globject
);