Commit 8cd26095 authored by Lionel Ulmer's avatar Lionel Ulmer Committed by Alexandre Julliard

Enable the application to create first textures and then the D3D

device.
parent 5a23a001
...@@ -54,7 +54,11 @@ struct IDirect3DImpl ...@@ -54,7 +54,11 @@ struct IDirect3DImpl
IDirectDrawImpl* ddraw; IDirectDrawImpl* ddraw;
/* Used as a callback function to create a texture */ /* Used as a callback function to create a texture */
HRESULT (*create_texture)(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *tex, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main, DWORD mipmap_level); HRESULT (*create_texture)(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *tex, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main);
/* Used as a callback for Devices to tell to the D3D object it's been created */
HRESULT (*added_device)(IDirect3DImpl *d3d, IDirect3DDeviceImpl *device);
HRESULT (*removed_device)(IDirect3DImpl *d3d, IDirect3DDeviceImpl *device);
}; };
/***************************************************************************** /*****************************************************************************
......
...@@ -302,6 +302,9 @@ GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface) ...@@ -302,6 +302,9 @@ GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
if (This->current_texture[0] != NULL) if (This->current_texture[0] != NULL)
IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2)); IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2));
/* And warn the D3D object that this device is no longer active... */
This->d3d->removed_device(This->d3d, This);
ENTER_GL(); ENTER_GL();
glXDestroyContext(glThis->display, glThis->gl_context); glXDestroyContext(glThis->display, glThis->gl_context);
LEAVE_GL(); LEAVE_GL();
...@@ -1880,6 +1883,9 @@ d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfa ...@@ -1880,6 +1883,9 @@ d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfa
*obj = object; *obj = object;
TRACE(" creating implementation at %p.\n", *obj); TRACE(" creating implementation at %p.\n", *obj);
/* And finally warn D3D that this device is now present */
object->d3d->added_device(object->d3d, object);
return DD_OK; return DD_OK;
} }
...@@ -359,7 +359,7 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD, ...@@ -359,7 +359,7 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
if (This->d3d) This->d3d->create_texture(This->d3d, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE, if (This->d3d) This->d3d->create_texture(This->d3d, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE,
ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), mipmap_level); ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf));
/* Create attached mipmaps if required. */ /* Create attached mipmaps if required. */
if (more_mipmaps(&ddsd)) if (more_mipmaps(&ddsd))
...@@ -375,8 +375,9 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD, ...@@ -375,8 +375,9 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
while (more_mipmaps(&mipmap_surface_desc)) while (more_mipmaps(&mipmap_surface_desc))
{ {
IDirectDrawSurfaceImpl *mipmap_impl;
mipmap_level++; mipmap_level++;
mipmap_surface_desc.u2.dwMipMapCount--; mipmap_surface_desc.u2.dwMipMapCount--;
if (mipmap_surface_desc.dwWidth > 1) if (mipmap_surface_desc.dwWidth > 1)
...@@ -397,8 +398,14 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD, ...@@ -397,8 +398,14 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
IDirectDrawSurface7_Release(*ppSurf); IDirectDrawSurface7_Release(*ppSurf);
return hr; return hr;
} }
/* This is needed for delayed mipmap creation */
mipmap_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap);
mipmap_impl->mip_main = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf);
mipmap_impl->mipmap_level = mipmap_level;
if (This->d3d) This->d3d->create_texture(This->d3d, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap), TRUE, if (This->d3d) This->d3d->create_texture(This->d3d, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap), TRUE,
ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), mipmap_level); ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf));
IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap); IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap);
IDirectDrawSurface7_Release(prev_mipmap); IDirectDrawSurface7_Release(prev_mipmap);
......
...@@ -297,6 +297,9 @@ struct IDirectDrawSurfaceImpl ...@@ -297,6 +297,9 @@ struct IDirectDrawSurfaceImpl
HRESULT (WINAPI *SetColorKey_cb)(struct IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ; HRESULT (WINAPI *SetColorKey_cb)(struct IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
/* This is to get the D3DDevice object associated to this surface */ /* This is to get the D3DDevice object associated to this surface */
struct IDirect3DDeviceImpl *d3ddevice; struct IDirect3DDeviceImpl *d3ddevice;
/* This is for texture */
IDirectDrawSurfaceImpl *mip_main;
int mipmap_level;
LPVOID tex_private; LPVOID tex_private;
}; };
......
...@@ -377,6 +377,38 @@ ICOM_VTABLE(IDirect3D) VTABLE_IDirect3D = ...@@ -377,6 +377,38 @@ ICOM_VTABLE(IDirect3D) VTABLE_IDirect3D =
#undef XCAST #undef XCAST
#endif #endif
static HRESULT d3d_add_device(IDirect3DImpl *This, IDirect3DDeviceImpl *device)
{
IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This;
if (glThis->current_device == NULL) {
/* Create delayed textures now that we have an OpenGL context...
For that, go through all surface attached to our DDraw object and create
OpenGL textures for all textures.. */
IDirectDrawSurfaceImpl *surf = This->ddraw->surfaces;
while (surf != NULL) {
if (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
/* Found a texture.. Now create the OpenGL part */
d3dtexture_create(This, surf, FALSE, surf->mip_main);
}
surf = surf->next_ddraw;
}
}
/* For the moment, only one device 'supported'... */
glThis->current_device = device;
return DD_OK;
}
static HRESULT d3d_remove_device(IDirect3DImpl *This, IDirect3DDeviceImpl *device)
{
IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This;
glThis->current_device = NULL;
return DD_OK;
}
HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw) HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw)
{ {
IDirect3DImpl *object; IDirect3DImpl *object;
...@@ -388,7 +420,9 @@ HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw) ...@@ -388,7 +420,9 @@ HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw)
object->ref = 1; object->ref = 1;
object->ddraw = ddraw; object->ddraw = ddraw;
object->create_texture = d3dtexture_create; object->create_texture = d3dtexture_create;
object->added_device = d3d_add_device;
object->removed_device = d3d_remove_device;
ICOM_INIT_INTERFACE(object, IDirect3D, VTABLE_IDirect3D); ICOM_INIT_INTERFACE(object, IDirect3D, VTABLE_IDirect3D);
ICOM_INIT_INTERFACE(object, IDirect3D2, VTABLE_IDirect3D2); ICOM_INIT_INTERFACE(object, IDirect3D2, VTABLE_IDirect3D2);
ICOM_INIT_INTERFACE(object, IDirect3D3, VTABLE_IDirect3D3); ICOM_INIT_INTERFACE(object, IDirect3D3, VTABLE_IDirect3D3);
......
...@@ -193,22 +193,16 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid, ...@@ -193,22 +193,16 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
{ {
HRESULT ret_value = S_OK; HRESULT ret_value = S_OK;
/* In case the texture surface was created before the D3D creation */
if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) == 0) return E_NOINTERFACE; if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) == 0) return E_NOINTERFACE;
/* Create a 'delayed' private field only if it is not an offscreen texture... */
/* In case the texture surface was created before the D3D creation */
if (This->tex_private == NULL) { if (This->tex_private == NULL) {
if (This->ddraw_owner->d3d == NULL) { if (This->ddraw_owner->d3d == NULL) {
ERR("Texture created with no D3D object yet.. Not supported !\n"); ERR("Texture created with no D3D object yet.. Not supported !\n");
return E_NOINTERFACE; return E_NOINTERFACE;
} }
if (((This->surface_desc.dwFlags & DDSD_MIPMAPCOUNT) && ret_value = This->ddraw_owner->d3d->create_texture(This->ddraw_owner->d3d, This, FALSE, This->mip_main);
(This->surface_desc.u2.dwMipMapCount > 1)) ||
(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)) {
ERR(" need to fix mipmaping in this case !!\n");
}
ret_value = This->ddraw_owner->d3d->create_texture(This->ddraw_owner->d3d, This, FALSE, NULL, 0);
if (FAILED(ret_value)) return ret_value; if (FAILED(ret_value)) return ret_value;
} }
if (IsEqualGUID( &IID_IDirect3DTexture, riid )) { if (IsEqualGUID( &IID_IDirect3DTexture, riid )) {
......
...@@ -78,6 +78,9 @@ typedef struct IDirect3DGLImpl ...@@ -78,6 +78,9 @@ typedef struct IDirect3DGLImpl
struct IDirect3DImpl parent; struct IDirect3DImpl parent;
int free_lights; int free_lights;
void (*light_released)(IDirect3DImpl *, GLenum light_num); void (*light_released)(IDirect3DImpl *, GLenum light_num);
/* This is needed for delayed texture creation */
struct IDirect3DDeviceImpl *current_device;
} IDirect3DGLImpl; } IDirect3DGLImpl;
typedef struct IDirect3DLightGLImpl typedef struct IDirect3DLightGLImpl
...@@ -92,7 +95,6 @@ typedef struct IDirect3DTextureGLImpl ...@@ -92,7 +95,6 @@ typedef struct IDirect3DTextureGLImpl
GLuint tex_name; GLuint tex_name;
BOOLEAN loaded; /* For the moment, this is here.. Should be part of surface management though */ BOOLEAN loaded; /* For the moment, this is here.. Should be part of surface management though */
BOOLEAN first_unlock; BOOLEAN first_unlock;
DWORD mipmap_level;
/* This is for now used to override 'standard' surface stuff to be as transparent as possible */ /* This is for now used to override 'standard' surface stuff to be as transparent as possible */
void (*final_release)(struct IDirectDrawSurfaceImpl *This); void (*final_release)(struct IDirectDrawSurfaceImpl *This);
void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags); void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
...@@ -123,7 +125,7 @@ typedef struct IDirect3DDeviceGLImpl ...@@ -123,7 +125,7 @@ typedef struct IDirect3DDeviceGLImpl
/* All non-static functions 'exported' by various sub-objects */ /* All non-static functions 'exported' by various sub-objects */
extern HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw); extern HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw);
extern HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf, DWORD mipmap_level); extern HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf);
extern HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirect3DImpl *d3d, GLenum light_num); extern HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirect3DImpl *d3d, GLenum light_num);
extern HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirect3DImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc); extern HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirect3DImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
extern HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirect3DImpl *d3d); extern HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirect3DImpl *d3d);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment