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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "ddraw_private.h"
35 #include "d3d_private.h"
36 #include "mesa_private.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
46 GL_IDirect3DImpl_3_2T_1T_EnumDevices(LPDIRECT3D3 iface
,
47 LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback
,
50 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D3
, iface
);
51 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpEnumDevicesCallback
, lpUserArg
);
53 /* Call functions defined in d3ddevices.c */
54 if (d3ddevice_enumerate(lpEnumDevicesCallback
, lpUserArg
) != D3DENUMRET_OK
)
61 GL_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface
,
62 LPDIRECT3DLIGHT
* lplpDirect3DLight
,
65 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D3
, iface
);
66 IDirect3DGLImpl
*glThis
= (IDirect3DGLImpl
*) This
;
68 IDirect3DLightImpl
*d3dlimpl
;
71 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lplpDirect3DLight
, pUnkOuter
);
72 for (fl
= 0; fl
< MAX_LIGHTS
; fl
++) {
73 if ((glThis
->free_lights
& (0x01 << fl
)) != 0) {
74 glThis
->free_lights
&= ~(0x01 << fl
);
78 if (fl
== MAX_LIGHTS
) {
79 return DDERR_INVALIDPARAMS
; /* No way to say 'max lights reached' ... */
81 ret_value
= d3dlight_create(&d3dlimpl
, This
, GL_LIGHT0
+ fl
);
82 *lplpDirect3DLight
= ICOM_INTERFACE(d3dlimpl
, IDirect3DLight
);
88 GL_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface
,
89 LPDIRECT3DMATERIAL3
* lplpDirect3DMaterial3
,
92 IDirect3DMaterialImpl
*D3Dmat_impl
;
94 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D3
, iface
);
96 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lplpDirect3DMaterial3
, pUnkOuter
);
97 ret_value
= d3dmaterial_create(&D3Dmat_impl
, This
);
99 *lplpDirect3DMaterial3
= ICOM_INTERFACE(D3Dmat_impl
, IDirect3DMaterial3
);
105 GL_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface
,
106 LPDIRECT3DVIEWPORT3
* lplpD3DViewport3
,
109 IDirect3DViewportImpl
*D3Dvp_impl
;
111 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D3
, iface
);
113 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lplpD3DViewport3
, pUnkOuter
);
114 ret_value
= d3dviewport_create(&D3Dvp_impl
, This
);
116 *lplpD3DViewport3
= ICOM_INTERFACE(D3Dvp_impl
, IDirect3DViewport3
);
122 create_device_helper(IDirect3DImpl
*This
,
124 IDirectDrawSurfaceImpl
*lpDDS
,
127 IDirect3DDeviceImpl
*lpd3ddev
;
130 ret_value
= d3ddevice_create(&lpd3ddev
, This
, lpDDS
);
131 if (FAILED(ret_value
)) return ret_value
;
134 (IsEqualGUID(&IID_D3DDEVICE_OpenGL
, iid
)) ||
135 (IsEqualGUID(&IID_IDirect3DHALDevice
, iid
)) ||
136 (IsEqualGUID(&IID_IDirect3DTnLHalDevice
, iid
))) {
139 *obj
= ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice
);
140 TRACE(" returning OpenGL D3DDevice %p.\n", *obj
);
144 *obj
= ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice2
);
145 TRACE(" returning OpenGL D3DDevice2 %p.\n", *obj
);
149 *obj
= ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice3
);
150 TRACE(" returning OpenGL D3DDevice3 %p.\n", *obj
);
154 *obj
= ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice7
);
155 TRACE(" returning OpenGL D3DDevice7 %p.\n", *obj
);
161 ERR(" Interface unknown when creating D3DDevice (%s)\n", debugstr_guid(iid
));
162 IDirect3DDevice7_Release(ICOM_INTERFACE(lpd3ddev
, IDirect3DDevice7
));
163 return DDERR_INVALIDPARAMS
;
168 GL_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface
,
170 LPDIRECTDRAWSURFACE lpDDS
,
171 LPDIRECT3DDEVICE2
* lplpD3DDevice2
)
173 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D2
, iface
);
174 IDirectDrawSurfaceImpl
*ddsurfaceimpl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface3
, lpDDS
);
175 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_guid(rclsid
), lpDDS
, lplpD3DDevice2
);
176 return create_device_helper(This
, rclsid
, ddsurfaceimpl
, (void **) lplpD3DDevice2
, 2);
180 GL_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface
,
182 LPDIRECTDRAWSURFACE4 lpDDS
,
183 LPDIRECT3DDEVICE3
* lplpD3DDevice3
,
186 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D3
, iface
);
187 IDirectDrawSurfaceImpl
*ddsurfaceimpl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, lpDDS
);
188 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_guid(rclsid
), lpDDS
, lplpD3DDevice3
);
189 return create_device_helper(This
, rclsid
, ddsurfaceimpl
, (void **) lplpD3DDevice3
, 3);
193 GL_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface
,
194 LPD3DFINDDEVICESEARCH lpD3DDFS
,
195 LPD3DFINDDEVICERESULT lpD3DFDR
)
197 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D3
, iface
);
198 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpD3DDFS
, lpD3DFDR
);
199 return d3ddevice_find(This
, lpD3DDFS
, lpD3DFDR
);
203 GL_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface
,
205 LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback
,
208 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D7
, iface
);
209 DDPIXELFORMAT pformat
;
211 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_guid(riidDevice
), lpEnumCallback
, lpContext
);
213 memset(&pformat
, 0, sizeof(pformat
));
214 pformat
.dwSize
= sizeof(DDPIXELFORMAT
);
215 pformat
.dwFourCC
= 0;
216 TRACE("Enumerating dummy ZBuffer format (16 bits)\n");
217 pformat
.dwFlags
= DDPF_ZBUFFER
;
218 pformat
.u1
.dwZBufferBitDepth
= 16;
219 pformat
.u3
.dwZBitMask
= 0x0000FFFF;
220 pformat
.u5
.dwRGBZBitMask
= 0x0000FFFF;
222 /* Whatever the return value, stop here.. */
223 lpEnumCallback(&pformat
, lpContext
);
229 GL_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface
,
230 LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback
,
233 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D7
, iface
);
234 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpEnumDevicesCallback
, lpUserArg
);
236 if (d3ddevice_enumerate7(lpEnumDevicesCallback
, lpUserArg
) != D3DENUMRET_OK
)
243 GL_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface
,
245 LPDIRECTDRAWSURFACE7 lpDDS
,
246 LPDIRECT3DDEVICE7
* lplpD3DDevice
)
248 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D7
, iface
);
249 IDirectDrawSurfaceImpl
*ddsurfaceimpl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, lpDDS
);
250 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_guid(rclsid
), lpDDS
, lplpD3DDevice
);
251 return create_device_helper(This
, rclsid
, ddsurfaceimpl
, (void **) lplpD3DDevice
, 7);
255 GL_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface
,
256 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc
,
257 LPDIRECT3DVERTEXBUFFER7
* lplpD3DVertBuf
,
260 ICOM_THIS_FROM(IDirect3DImpl
, IDirect3D7
, iface
);
261 IDirect3DVertexBufferImpl
*vbimpl
;
264 TRACE("(%p/%p)->(%p,%p,%08lx)\n", This
, iface
, lpD3DVertBufDesc
, lplpD3DVertBuf
, dwFlags
);
266 res
= d3dvertexbuffer_create(&vbimpl
, This
, lpD3DVertBufDesc
, dwFlags
);
268 *lplpD3DVertBuf
= ICOM_INTERFACE(vbimpl
, IDirect3DVertexBuffer7
);
273 static void light_released(IDirect3DImpl
*This
, GLenum light_num
)
275 IDirect3DGLImpl
*glThis
= (IDirect3DGLImpl
*) This
;
276 glThis
->free_lights
|= (light_num
- GL_LIGHT0
);
279 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
280 # define XCAST(fun) (typeof(VTABLE_IDirect3D7.fun))
282 # define XCAST(fun) (void*)
285 ICOM_VTABLE(IDirect3D7
) VTABLE_IDirect3D7
=
287 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
288 XCAST(QueryInterface
) Main_IDirect3DImpl_7_3T_2T_1T_QueryInterface
,
289 XCAST(AddRef
) Main_IDirect3DImpl_7_3T_2T_1T_AddRef
,
290 XCAST(Release
) Main_IDirect3DImpl_7_3T_2T_1T_Release
,
291 XCAST(EnumDevices
) GL_IDirect3DImpl_7_EnumDevices
,
292 XCAST(CreateDevice
) GL_IDirect3DImpl_7_CreateDevice
,
293 XCAST(CreateVertexBuffer
) GL_IDirect3DImpl_7_3T_CreateVertexBuffer
,
294 XCAST(EnumZBufferFormats
) GL_IDirect3DImpl_7_3T_EnumZBufferFormats
,
295 XCAST(EvictManagedTextures
) Main_IDirect3DImpl_7_3T_EvictManagedTextures
,
298 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
303 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
304 # define XCAST(fun) (typeof(VTABLE_IDirect3D3.fun))
306 # define XCAST(fun) (void*)
309 ICOM_VTABLE(IDirect3D3
) VTABLE_IDirect3D3
=
311 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
312 XCAST(QueryInterface
) Thunk_IDirect3DImpl_3_QueryInterface
,
313 XCAST(AddRef
) Thunk_IDirect3DImpl_3_AddRef
,
314 XCAST(Release
) Thunk_IDirect3DImpl_3_Release
,
315 XCAST(EnumDevices
) GL_IDirect3DImpl_3_2T_1T_EnumDevices
,
316 XCAST(CreateLight
) GL_IDirect3DImpl_3_2T_1T_CreateLight
,
317 XCAST(CreateMaterial
) GL_IDirect3DImpl_3_2T_1T_CreateMaterial
,
318 XCAST(CreateViewport
) GL_IDirect3DImpl_3_2T_1T_CreateViewport
,
319 XCAST(FindDevice
) GL_IDirect3DImpl_3_2T_1T_FindDevice
,
320 XCAST(CreateDevice
) GL_IDirect3DImpl_3_CreateDevice
,
321 XCAST(CreateVertexBuffer
) Thunk_IDirect3DImpl_3_CreateVertexBuffer
,
322 XCAST(EnumZBufferFormats
) Thunk_IDirect3DImpl_3_EnumZBufferFormats
,
323 XCAST(EvictManagedTextures
) Thunk_IDirect3DImpl_3_EvictManagedTextures
,
326 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
331 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
332 # define XCAST(fun) (typeof(VTABLE_IDirect3D2.fun))
334 # define XCAST(fun) (void*)
337 ICOM_VTABLE(IDirect3D2
) VTABLE_IDirect3D2
=
339 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
340 XCAST(QueryInterface
) Thunk_IDirect3DImpl_2_QueryInterface
,
341 XCAST(AddRef
) Thunk_IDirect3DImpl_2_AddRef
,
342 XCAST(Release
) Thunk_IDirect3DImpl_2_Release
,
343 XCAST(EnumDevices
) Thunk_IDirect3DImpl_2_EnumDevices
,
344 XCAST(CreateLight
) Thunk_IDirect3DImpl_2_CreateLight
,
345 XCAST(CreateMaterial
) Thunk_IDirect3DImpl_2_CreateMaterial
,
346 XCAST(CreateViewport
) Thunk_IDirect3DImpl_2_CreateViewport
,
347 XCAST(FindDevice
) Thunk_IDirect3DImpl_2_FindDevice
,
348 XCAST(CreateDevice
) GL_IDirect3DImpl_2_CreateDevice
,
351 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
356 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
357 # define XCAST(fun) (typeof(VTABLE_IDirect3D.fun))
359 # define XCAST(fun) (void*)
362 ICOM_VTABLE(IDirect3D
) VTABLE_IDirect3D
=
364 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
365 XCAST(QueryInterface
) Thunk_IDirect3DImpl_1_QueryInterface
,
366 XCAST(AddRef
) Thunk_IDirect3DImpl_1_AddRef
,
367 XCAST(Release
) Thunk_IDirect3DImpl_1_Release
,
368 XCAST(Initialize
) Main_IDirect3DImpl_1_Initialize
,
369 XCAST(EnumDevices
) Thunk_IDirect3DImpl_1_EnumDevices
,
370 XCAST(CreateLight
) Thunk_IDirect3DImpl_1_CreateLight
,
371 XCAST(CreateMaterial
) Thunk_IDirect3DImpl_1_CreateMaterial
,
372 XCAST(CreateViewport
) Thunk_IDirect3DImpl_1_CreateViewport
,
373 XCAST(FindDevice
) Thunk_IDirect3DImpl_1_FindDevice
,
376 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
380 static HRESULT
d3d_add_device(IDirect3DImpl
*This
, IDirect3DDeviceImpl
*device
)
382 if (This
->current_device
== NULL
) {
383 /* Create delayed textures now that we have an OpenGL context...
384 For that, go through all surface attached to our DDraw object and create
385 OpenGL textures for all textures.. */
386 IDirectDrawSurfaceImpl
*surf
= This
->ddraw
->surfaces
;
388 while (surf
!= NULL
) {
389 if (surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
) {
390 /* Found a texture.. Now create the OpenGL part */
391 d3dtexture_create(This
, surf
, FALSE
, surf
->mip_main
);
393 surf
= surf
->next_ddraw
;
396 /* For the moment, only one device 'supported'... */
397 This
->current_device
= device
;
402 static HRESULT
d3d_remove_device(IDirect3DImpl
*This
, IDirect3DDeviceImpl
*device
)
404 This
->current_device
= NULL
;
408 HRESULT
direct3d_create(IDirect3DImpl
**obj
, IDirectDrawImpl
*ddraw
)
410 IDirect3DImpl
*object
;
411 IDirect3DGLImpl
*globject
;
413 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DGLImpl
));
414 if (object
== NULL
) return DDERR_OUTOFMEMORY
;
417 object
->ddraw
= ddraw
;
418 object
->create_texture
= d3dtexture_create
;
419 object
->added_device
= d3d_add_device
;
420 object
->removed_device
= d3d_remove_device
;
422 ICOM_INIT_INTERFACE(object
, IDirect3D
, VTABLE_IDirect3D
);
423 ICOM_INIT_INTERFACE(object
, IDirect3D2
, VTABLE_IDirect3D2
);
424 ICOM_INIT_INTERFACE(object
, IDirect3D3
, VTABLE_IDirect3D3
);
425 ICOM_INIT_INTERFACE(object
, IDirect3D7
, VTABLE_IDirect3D7
);
427 globject
= (IDirect3DGLImpl
*) object
;
428 globject
->free_lights
= (0x01 << MAX_LIGHTS
) - 1; /* There are, in total, 8 lights in OpenGL */
429 globject
->light_released
= light_released
;
433 TRACE(" creating implementation at %p.\n", *obj
);