Commit 91c6f817 authored by Lionel Ulmer's avatar Lionel Ulmer Committed by Alexandre Julliard

- rework how texturing is done in the D3D driver

- added the generic path for DrawPrimitive API in D3D 3 / 7
parent cc1577cd
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
typedef struct IDirect3DImpl IDirect3DImpl; typedef struct IDirect3DImpl IDirect3DImpl;
typedef struct IDirect3DLightImpl IDirect3DLightImpl; typedef struct IDirect3DLightImpl IDirect3DLightImpl;
typedef struct IDirect3DMaterialImpl IDirect3DMaterialImpl; typedef struct IDirect3DMaterialImpl IDirect3DMaterialImpl;
typedef struct IDirect3DTextureImpl IDirect3DTextureImpl;
typedef struct IDirect3DViewportImpl IDirect3DViewportImpl; typedef struct IDirect3DViewportImpl IDirect3DViewportImpl;
typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl; typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl;
typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl; typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl;
...@@ -53,6 +52,9 @@ struct IDirect3DImpl ...@@ -53,6 +52,9 @@ struct IDirect3DImpl
DWORD ref; DWORD ref;
/* IDirect3D fields */ /* IDirect3D fields */
IDirectDrawImpl* ddraw; IDirectDrawImpl* ddraw;
/* Used as a callback function to create a texture */
HRESULT (*create_texture)(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *tex, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main, DWORD mipmap_level);
}; };
/***************************************************************************** /*****************************************************************************
...@@ -95,21 +97,6 @@ struct IDirect3DMaterialImpl ...@@ -95,21 +97,6 @@ struct IDirect3DMaterialImpl
}; };
/***************************************************************************** /*****************************************************************************
* IDirect3DTexture implementation structure
*/
struct IDirect3DTextureImpl
{
ICOM_VFIELD_MULTI(IDirect3DTexture2);
ICOM_VFIELD_MULTI(IDirect3DTexture);
DWORD ref;
/* IDirect3DTexture fields */
IDirect3DImpl *d3d;
IDirect3DDeviceImpl *d3ddevice;
IDirectDrawSurfaceImpl *surface;
BOOL loaded;
};
/*****************************************************************************
* IDirect3DViewport implementation structure * IDirect3DViewport implementation structure
*/ */
struct IDirect3DViewportImpl struct IDirect3DViewportImpl
...@@ -183,7 +170,7 @@ struct IDirect3DDeviceImpl ...@@ -183,7 +170,7 @@ struct IDirect3DDeviceImpl
IDirect3DViewportImpl *viewport_list; IDirect3DViewportImpl *viewport_list;
IDirect3DViewportImpl *current_viewport; IDirect3DViewportImpl *current_viewport;
IDirect3DTextureImpl *current_texture[MAX_TEXTURES]; IDirectDrawSurfaceImpl *current_texture[MAX_TEXTURES];
void (*set_context)(IDirect3DDeviceImpl*); void (*set_context)(IDirect3DDeviceImpl*);
}; };
......
...@@ -160,7 +160,7 @@ static void fill_opengl_caps(D3DDEVICEDESC *d1) ...@@ -160,7 +160,7 @@ static void fill_opengl_caps(D3DDEVICEDESC *d1)
fill_opengl_primcaps(&(d1->dpcLineCaps)); fill_opengl_primcaps(&(d1->dpcLineCaps));
fill_opengl_primcaps(&(d1->dpcTriCaps)); fill_opengl_primcaps(&(d1->dpcTriCaps));
d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32; d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
d1->dwDeviceZBufferBitDepth = DDBD_16; d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
d1->dwMaxBufferSize = 0; d1->dwMaxBufferSize = 0;
d1->dwMaxVertexCount = 65536; d1->dwMaxVertexCount = 65536;
d1->dwMinTextureWidth = 1; d1->dwMinTextureWidth = 1;
...@@ -842,19 +842,23 @@ GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface, ...@@ -842,19 +842,23 @@ GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
return ret_value; return ret_value;
} }
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
{ {
DWORD size = 0; DWORD size = 0;
DWORD elts = 0;
if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE); if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD); if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD); if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
switch (d3dvtVertexType & D3DFVF_POSITION_MASK) { switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break; case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break; case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
default: TRACE(" matrix weighting not handled yet...\n"); default: TRACE(" matrix weighting not handled yet...\n");
} }
size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
if (elements) *elements = elts;
return size; return size;
} }
...@@ -908,6 +912,48 @@ typedef struct { ...@@ -908,6 +912,48 @@ typedef struct {
float tu1, tv1; float tu1, tv1;
} D3DFVF_TLVERTEX_1; } D3DFVF_TLVERTEX_1;
typedef struct {
int offset;
int extra;
void (*handler)(char *vertex, int offset, int extra);
} D3DFVF_GENERIC;
/* These are the various handler used in the generic path */
static void handle_xyz(char *vertex, int offset, int extra) {
glVertex3fv((float *) (vertex + offset));
}
static void handle_xyzrhw(char *vertex, int offset, int extra) {
float *coords = (float *) (vertex + offset);
if (coords[3] < 0.00001)
glVertex3f(coords[0], coords[1], coords[2]);
else
glVertex4f(coords[0] / coords[3],
coords[1] / coords[3],
coords[2] / coords[3],
1.0 / coords[3]);
}
static void handle_normal(char *vertex, int offset, int extra) {
glNormal3fv((float *) (vertex + offset));
}
static void handle_specular(char *vertex, int offset, int extra) {
/* Specular not handled yet properly... */
}
static void handle_diffuse(char *vertex, int offset, int extra) {
DWORD color = *((DWORD *) (vertex + offset));
glColor4ub((color >> 24) & 0xFF,
(color >> 16) & 0xFF,
(color >> 8) & 0xFF,
(color >> 0) & 0xFF);
}
static void handle_texture(char *vertex, int offset, int extra) {
if (extra == 0xFF) {
/* Special case for single texture... */
glTexCoord2fv((float *) (vertex + offset));
} else {
/* Multitexturing not handled yet */
}
}
static void draw_primitive_7(IDirect3DDeviceImpl *This, static void draw_primitive_7(IDirect3DDeviceImpl *This,
D3DPRIMITIVETYPE d3dptPrimitiveType, D3DPRIMITIVETYPE d3dptPrimitiveType,
DWORD d3dvtVertexType, DWORD d3dvtVertexType,
...@@ -936,9 +982,9 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This, ...@@ -936,9 +982,9 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This,
for (index = 0; index < dwIndexCount; index++) { for (index = 0; index < dwIndexCount; index++) {
int i = (dwIndices == NULL) ? index : dwIndices[index]; int i = (dwIndices == NULL) ? index : dwIndices[index];
glNormal3f(vertices[i].nx, vertices[i].ny, vertices[i].nz); glNormal3fv(&(vertices[i].nx));
glTexCoord2f(vertices[i].tu1, vertices[i].tv1); glTexCoord2fv(&(vertices[i].tu1));
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z); glVertex3fv(&(vertices[i].x));
TRACE(" %f %f %f / %f %f %f (%f %f)\n", TRACE(" %f %f %f / %f %f %f (%f %f)\n",
vertices[i].x, vertices[i].y, vertices[i].z, vertices[i].x, vertices[i].y, vertices[i].z,
vertices[i].nx, vertices[i].ny, vertices[i].nz, vertices[i].nx, vertices[i].ny, vertices[i].nz,
...@@ -956,7 +1002,7 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This, ...@@ -956,7 +1002,7 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This,
(vertices[i].diffuse >> 8) & 0xFF, (vertices[i].diffuse >> 8) & 0xFF,
(vertices[i].diffuse >> 0) & 0xFF); (vertices[i].diffuse >> 0) & 0xFF);
/* Todo : handle specular... */ /* Todo : handle specular... */
glTexCoord2f(vertices[i].tu1, vertices[i].tv1); glTexCoord2fv(&(vertices[i].tu1));
if (vertices[i].rhw < 0.00001) if (vertices[i].rhw < 0.00001)
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z); glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
else else
...@@ -976,6 +1022,76 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This, ...@@ -976,6 +1022,76 @@ static void draw_primitive_7(IDirect3DDeviceImpl *This,
(vertices[i].specular >> 0) & 0xFF, (vertices[i].specular >> 0) & 0xFF,
vertices[i].tu1, vertices[i].tv1); vertices[i].tu1, vertices[i].tv1);
} }
} else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
/* This is the 'slow path' but that should support all possible vertex formats out there...
Note that people should write a fast path for all vertex formats out there...
*/
DWORD elements;
DWORD size = get_flexible_vertex_size(d3dvtVertexType, &elements);
char *vertices = (char *) lpvVertices;
int index;
int current_offset = 0;
int current_position = 0;
D3DFVF_GENERIC *handler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, elements * sizeof(D3DFVF_GENERIC));
WARN(" using draw_primitive generic path - for better performance, add a fast path for your vertex case !\n");
if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
handler[elements - 1].handler = handle_xyz;
handler[elements - 1].offset = current_offset;
current_offset += 3 * sizeof(D3DVALUE);
} else {
handler[elements - 1].handler = handle_xyzrhw;
handler[elements - 1].offset = current_offset;
current_offset += 4 * sizeof(D3DVALUE);
}
if (d3dvtVertexType & D3DFVF_NORMAL) {
handler[current_position].handler = handle_normal;
handler[current_position].offset = current_offset;
current_position += 1;
current_offset += 3 * sizeof(D3DVALUE);
}
if (d3dvtVertexType & D3DFVF_DIFFUSE) {
handler[current_position].handler = handle_diffuse;
handler[current_position].offset = current_offset;
current_position += 1;
current_offset += sizeof(DWORD);
}
if (d3dvtVertexType & D3DFVF_SPECULAR) {
handler[current_position].handler = handle_specular;
handler[current_position].offset = current_offset;
current_position += 1;
current_offset += sizeof(DWORD);
}
if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
handler[current_position].handler = handle_texture;
handler[current_position].offset = current_offset;
handler[current_position].extra = 0xFF;
current_position += 1;
current_offset += 2 * sizeof(D3DVALUE);
} else {
int tex_index;
for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
handler[current_position].handler = handle_texture;
handler[current_position].offset = current_offset;
handler[current_position].extra = tex_index;
current_position += 1;
current_offset += 2 * sizeof(D3DVALUE);
}
}
for (index = 0; index < dwIndexCount; index++) {
int i = (dwIndices == NULL) ? index : dwIndices[index];
int elt;
char *vertex = vertices + (i * size);
for (elt = 0; elt < elements; elt++) {
handler[elt].handler(vertex, handler[elt].offset, handler[elt].extra);
}
}
} else {
ERR(" matrix weighting not handled yet....\n");
} }
glEnd(); glEnd();
...@@ -1130,11 +1246,11 @@ GL_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface, ...@@ -1130,11 +1246,11 @@ GL_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface,
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} else { } else {
IDirect3DTextureImpl *tex_impl = ICOM_OBJECT(IDirect3DTextureImpl, IDirect3DTexture2, lpTexture2); IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpTexture2);
IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl; IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
This->current_texture[dwStage] = tex_impl; This->current_texture[dwStage] = tex_impl;
IDirect3DTexture2_AddRef(lpTexture2); IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7));
TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name); TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
...@@ -1453,7 +1569,6 @@ static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect) ...@@ -1453,7 +1569,6 @@ static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
LEAVE_GL(); LEAVE_GL();
return; return;
} }
glRasterPos2f(0.0, 0.0); glRasterPos2f(0.0, 0.0);
glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight, glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
GL_RGB, buffer_type, This->surface_desc.lpSurface); GL_RGB, buffer_type, This->surface_desc.lpSurface);
......
...@@ -130,27 +130,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); ...@@ -130,27 +130,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
/******************************************************************************* /*******************************************************************************
* IDirectSurface callback methods * IDirectSurface callback methods
*/ */
HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) HRESULT WINAPI gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
{ {
DDSURFACEDESC *tex_d; DDSURFACEDESC *tex_d;
GLuint current_texture; GLuint current_texture;
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) texture; IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) texture->tex_private;
TRACE("(%p) : colorkey callback\n", texture); TRACE("(%p) : colorkey callback\n", texture);
/* Get the texture description */ /* Get the texture description */
tex_d = (DDSURFACEDESC *)&(texture->surface->surface_desc); tex_d = (DDSURFACEDESC *)&(texture->surface_desc);
/* Now, save the current texture */ /* Now, save the current texture */
ENTER_GL(); ENTER_GL();
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture); glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
if (glThis->tex_name == 0) ERR("Unbound GL texture !!!\n");
/* If the GetHandle was not done yet, it's an error */
if (glThis->tex_name == 0) {
ERR("Unloaded texture !\n");
LEAVE_GL();
return DD_OK;
}
glBindTexture(GL_TEXTURE_2D, glThis->tex_name); glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
...@@ -180,14 +174,13 @@ HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDD ...@@ -180,14 +174,13 @@ HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDD
} }
} }
glTexImage2D(GL_TEXTURE_2D, glTexSubImage2D(GL_TEXTURE_2D,
0, glThis->mipmap_level,
GL_RGBA, 0, 0,
tex_d->dwWidth, tex_d->dwHeight, tex_d->dwWidth, tex_d->dwHeight,
0, GL_RGBA,
GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,
GL_UNSIGNED_SHORT_5_5_5_1, dest);
dest);
/* Frees the temporary surface */ /* Frees the temporary surface */
HeapFree(GetProcessHeap(),0,dest); HeapFree(GetProcessHeap(),0,dest);
...@@ -208,66 +201,280 @@ HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDD ...@@ -208,66 +201,280 @@ HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDD
} else { } else {
ERR("Unhandled texture format (neither RGB nor INDEX)\n"); ERR("Unhandled texture format (neither RGB nor INDEX)\n");
} }
glBindTexture(GL_TEXTURE_2D, current_texture);
LEAVE_GL(); LEAVE_GL();
return DD_OK; return DD_OK;
} }
HRESULT WINAPI static void
Main_IDirect3DTextureImpl_2_1T_QueryInterface(LPDIRECT3DTEXTURE2 iface, gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) {
REFIID riid, IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
LPVOID* obp) GLuint current_texture;
{ #if 0
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface); static BOOL color_table_queried = FALSE;
TRACE("(%p/%p)->(%s,%p): stub!\n", This, iface, debugstr_guid(riid), obp); #endif
void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
*obp = NULL; DDSURFACEDESC *src_d = (DDSURFACEDESC *)&(This->surface_desc);
if ( IsEqualGUID( &IID_IUnknown, riid ) ) { TRACE(" uploading texture to GL id %d (initial = %d).\n", glThis->tex_name, init_upload);
IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
*obp = iface;
TRACE(" Creating IUnknown interface at %p.\n", *obp);
return S_OK;
}
if ( IsEqualGUID( &IID_IDirect3DTexture, riid ) ) {
IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
*obp = ICOM_INTERFACE(This, IDirect3DTexture);
TRACE(" Creating IDirect3DTexture interface %p\n", *obp);
return S_OK;
}
if ( IsEqualGUID( &IID_IDirect3DTexture2, riid ) ) {
IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
*obp = ICOM_INTERFACE(This, IDirect3DTexture2);
TRACE(" Creating IDirect3DTexture2 interface %p\n", *obp);
return S_OK;
}
FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
return OLE_E_ENUM_NOMORE;
}
ULONG WINAPI glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
Main_IDirect3DTextureImpl_2_1T_AddRef(LPDIRECT3DTEXTURE2 iface) glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
{
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
return ++(This->ref);
}
ULONG WINAPI if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
Main_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface) /* ****************
{ Paletted Texture
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface); **************** */
FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref); IDirectDrawPaletteImpl* pal = This->palette;
BYTE table[256][4];
if (!--(This->ref)) { int i;
/* Release surface */
IDirectDrawSurface3_Release(ICOM_INTERFACE(This->surface, IDirectDrawSurface3));
HeapFree(GetProcessHeap(),0,This); #if 0
return 0; if (color_table_queried == FALSE) {
} ptr_ColorTableEXT =
((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
}
#endif
if (pal == NULL) {
ERR("Palettized texture Loading with a NULL palette !\n");
LEAVE_GL();
return;
}
/* Get the surface's palette */
for (i = 0; i < 256; i++) {
table[i][0] = pal->palents[i].peRed;
table[i][1] = pal->palents[i].peGreen;
table[i][2] = pal->palents[i].peBlue;
if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
(i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
(i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
table[i][3] = 0x00;
else
table[i][3] = 0xFF;
}
/* Texture snooping */
SNOOP_PALETTED();
if (ptr_ColorTableEXT != NULL) {
/* use Paletted Texture Extension */
ptr_ColorTableEXT(GL_TEXTURE_2D, /* target */
GL_RGBA, /* internal format */
256, /* table size */
GL_RGBA, /* table format */
GL_UNSIGNED_BYTE, /* table type */
table); /* the color table */
glTexImage2D(GL_TEXTURE_2D, /* target */
glThis->mipmap_level, /* level */
GL_COLOR_INDEX8_EXT, /* internal format */
src_d->dwWidth, src_d->dwHeight, /* width, height */
0, /* border */
GL_COLOR_INDEX, /* texture format */
GL_UNSIGNED_BYTE, /* texture type */
src_d->lpSurface); /* the texture */
} else {
DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
DWORD i;
BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
BYTE color = *src++;
*dst++ = table[color][0];
*dst++ = table[color][1];
*dst++ = table[color][2];
*dst++ = table[color][3];
}
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
surface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_BYTE,
surface);
HeapFree(GetProcessHeap(), 0, surface);
}
} else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
/* ************
RGB Textures
************ */
if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
/* **********************
GL_UNSIGNED_BYTE_3_3_2
********************** */
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE_3_3_2,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGB,
GL_UNSIGNED_BYTE_3_3_2,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
/* Texture snooping */
SNOOP_5650();
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_SHORT_5_6_5,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGB,
GL_UNSIGNED_SHORT_5_6_5,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
/* Texture snooping */
SNOOP_5551();
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
/* Converting the 1555 format in 5551 packed */
WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
*dst++ = (((*src & 0x8000) >> 15) |
((*src & 0x7FFF) << 1));
src++;
}
SNOOP_1555();
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
surface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
surface);
return This->ref; HeapFree(GetProcessHeap(), 0, surface);
} else {
ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
}
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGB,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
if (init_upload)
glTexImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
else
glTexSubImage2D(GL_TEXTURE_2D,
glThis->mipmap_level,
0, 0,
src_d->dwWidth, src_d->dwHeight,
GL_RGBA,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
} else {
ERR("Unhandled texture format (bad RGB count)\n");
}
} else {
ERR("Unhandled texture format (neither RGB nor INDEX)\n");
}
glBindTexture(GL_TEXTURE_2D, current_texture);
} }
HRESULT WINAPI HRESULT WINAPI
...@@ -275,7 +482,7 @@ Main_IDirect3DTextureImpl_1_Initialize(LPDIRECT3DTEXTURE iface, ...@@ -275,7 +482,7 @@ Main_IDirect3DTextureImpl_1_Initialize(LPDIRECT3DTEXTURE iface,
LPDIRECT3DDEVICE lpDirect3DDevice, LPDIRECT3DDEVICE lpDirect3DDevice,
LPDIRECTDRAWSURFACE lpDDSurface) LPDIRECTDRAWSURFACE lpDDSurface)
{ {
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture, iface); ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
FIXME("(%p/%p)->(%p,%p) no-op...\n", This, iface, lpDirect3DDevice, lpDDSurface); FIXME("(%p/%p)->(%p,%p) no-op...\n", This, iface, lpDirect3DDevice, lpDDSurface);
return DD_OK; return DD_OK;
} }
...@@ -285,7 +492,7 @@ Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface, ...@@ -285,7 +492,7 @@ Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
DWORD dwStart, DWORD dwStart,
DWORD dwCount) DWORD dwCount)
{ {
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface); ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This, iface, dwStart, dwCount); FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This, iface, dwStart, dwCount);
return DD_OK; return DD_OK;
} }
...@@ -293,7 +500,7 @@ Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface, ...@@ -293,7 +500,7 @@ Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
HRESULT WINAPI HRESULT WINAPI
Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface) Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface)
{ {
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture, iface); ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
FIXME("(%p/%p)->(): stub!\n", This, iface); FIXME("(%p/%p)->(): stub!\n", This, iface);
return DD_OK; return DD_OK;
} }
...@@ -303,7 +510,7 @@ Main_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface, ...@@ -303,7 +510,7 @@ Main_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
LPDIRECT3DDEVICE2 lpDirect3DDevice2, LPDIRECT3DDEVICE2 lpDirect3DDevice2,
LPD3DTEXTUREHANDLE lpHandle) LPD3DTEXTUREHANDLE lpHandle)
{ {
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface); ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpDirect3DDevice2, lpHandle); FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpDirect3DDevice2, lpHandle);
return DD_OK; return DD_OK;
} }
...@@ -312,45 +519,60 @@ HRESULT WINAPI ...@@ -312,45 +519,60 @@ HRESULT WINAPI
Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
LPDIRECT3DTEXTURE2 lpD3DTexture2) LPDIRECT3DTEXTURE2 lpD3DTexture2)
{ {
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface); ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2); FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2);
return DD_OK; return DD_OK;
} }
ULONG WINAPI static void
GL_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface) gltex_final_release(IDirectDrawSurfaceImpl *This)
{ {
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface); IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This; DWORD mem_used;
FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
if (!--(This->ref)) {
DWORD mem_used;
/* Release surface */
IDirectDrawSurface3_Release(ICOM_INTERFACE(This->surface, IDirectDrawSurface3));
/* And delete texture handle */ TRACE(" deleting texture with GL id %d.\n", glThis->tex_name);
ENTER_GL();
glDeleteTextures(1, &(glThis->tex_name)); /* And delete texture handle */
LEAVE_GL(); ENTER_GL();
if (glThis->tex_name != 0)
/* And if this texture was the current one, remove it at the device level */ glDeleteTextures(1, &(glThis->tex_name));
if (This->d3ddevice != NULL) LEAVE_GL();
if (This->d3ddevice->current_texture[0] == This)
This->d3ddevice->current_texture[0] = NULL; /* And if this texture was the current one, remove it at the device level */
if (This->d3ddevice != NULL)
if (This->loaded) { if (This->d3ddevice->current_texture[0] == This)
mem_used = This->surface->surface_desc.dwHeight * This->d3ddevice->current_texture[0] = NULL;
This->surface->surface_desc.dwHeight *
This->surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount; /* All this should be part of main surface management not just a hack for texture.. */
This->surface->ddraw_owner->free_memory(This->surface->ddraw_owner, mem_used); if (glThis->loaded) {
} mem_used = This->surface_desc.dwHeight *
HeapFree(GetProcessHeap(),0,This); This->surface_desc.dwHeight *
return 0; This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
This->ddraw_owner->free_memory(This->ddraw_owner, mem_used);
} }
return This->ref; glThis->final_release(This);
}
static void
gltex_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
{
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
glThis->lock_update(This, pRect, dwFlags);
}
static void
gltex_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
{
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
ENTER_GL();
gltex_upload_texture(This, glThis->first_unlock);
LEAVE_GL();
glThis->first_unlock = FALSE;
glThis->unlock_update(This, pRect);
} }
HRESULT WINAPI HRESULT WINAPI
...@@ -358,8 +580,8 @@ GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface, ...@@ -358,8 +580,8 @@ GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
LPDIRECT3DDEVICE2 lpDirect3DDevice2, LPDIRECT3DDEVICE2 lpDirect3DDevice2,
LPD3DTEXTUREHANDLE lpHandle) LPD3DTEXTUREHANDLE lpHandle)
{ {
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface); ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This; IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
IDirect3DDeviceImpl *lpDeviceImpl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, lpDirect3DDevice2); IDirect3DDeviceImpl *lpDeviceImpl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, lpDirect3DDevice2);
TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice2, lpHandle); TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice2, lpHandle);
...@@ -371,16 +593,12 @@ GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface, ...@@ -371,16 +593,12 @@ GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
/* Now, bind a new texture */ /* Now, bind a new texture */
This->d3ddevice = lpDeviceImpl; This->d3ddevice = lpDeviceImpl;
ENTER_GL();
if (glThis->tex_name == 0)
glGenTextures(1, &(glThis->tex_name));
LEAVE_GL();
/* Associate the texture with the device and perform the appropriate AddRef/Release */ /* Associate the texture with the device and perform the appropriate AddRef/Release */
/* FIXME: Is there only one or several textures associated with the device ? */ /* FIXME: Is there only one or several textures associated with the device ? */
if (lpDeviceImpl->current_texture[0] != NULL) if (lpDeviceImpl->current_texture[0] != NULL)
IDirect3DTexture2_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture[0], IDirect3DTexture2)); IDirectDrawSurface7_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture[0], IDirectDrawSurface7));
IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2)); IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This, IDirectDrawSurface7));
lpDeviceImpl->current_texture[0] = This; lpDeviceImpl->current_texture[0] = This;
TRACE("OpenGL texture handle is : %d\n", glThis->tex_name); TRACE("OpenGL texture handle is : %d\n", glThis->tex_name);
...@@ -394,49 +612,43 @@ HRESULT WINAPI ...@@ -394,49 +612,43 @@ HRESULT WINAPI
GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
LPDIRECT3DTEXTURE2 lpD3DTexture2) LPDIRECT3DTEXTURE2 lpD3DTexture2)
{ {
ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface); ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This; IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
IDirect3DTextureImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirect3DTextureImpl, IDirect3DTexture2, lpD3DTexture2); IDirectDrawSurfaceImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpD3DTexture2);
DWORD mem_used; DWORD mem_used;
DDSURFACEDESC *src_d, *dst_d; DDSURFACEDESC *src_d, *dst_d;
static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
#if 0
static BOOL color_table_queried = FALSE;
#endif
TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2); TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2);
if (This->loaded == FALSE) { if (glThis->loaded == FALSE) {
/* Only check memory for not already loaded texture... */ /* Only check memory for not already loaded texture... */
mem_used = This->surface->surface_desc.dwHeight * mem_used = This->surface_desc.dwHeight *
This->surface->surface_desc.dwHeight * This->surface_desc.dwHeight *
This->surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount; This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
if (This->surface->ddraw_owner->allocate_memory(This->surface->ddraw_owner, mem_used) < 0) { if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) {
TRACE(" out of virtual memory... Warning application.\n"); TRACE(" out of virtual memory... Warning application.\n");
return D3DERR_TEXTURE_LOAD_FAILED; return D3DERR_TEXTURE_LOAD_FAILED;
} }
} }
This->loaded = TRUE; glThis->loaded = TRUE;
TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl->surface, This->surface); TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl, This);
if ( This->surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD ) if ( This->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
/* If the surface is not allocated and its location is not yet specified, /* If the surface is not allocated and its location is not yet specified,
force it to video memory */ force it to video memory */
if ( !(This->surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) ) if ( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) ) {
This->surface->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
WARN("This case is not properly handled yet.. Expect errors !\n");
}
/* Suppress the ALLOCONLOAD flag */ /* Suppress the ALLOCONLOAD flag */
This->surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
This->palette = lpD3DTextureImpl->palette;
/* Copy one surface on the other */ /* Copy one surface on the other */
dst_d = (DDSURFACEDESC *)&(This->surface->surface_desc); dst_d = (DDSURFACEDESC *)&(This->surface_desc);
src_d = (DDSURFACEDESC *)&(lpD3DTextureImpl->surface->surface_desc); src_d = (DDSURFACEDESC *)&(lpD3DTextureImpl->surface_desc);
/* Install the callbacks to the destination surface */
This->surface->texture = This;
This->surface->SetColorKey_cb = SetColorKey_cb;
if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) { if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
/* Should also check for same pixel format, u1.lPitch, ... */ /* Should also check for same pixel format, u1.lPitch, ... */
...@@ -445,204 +657,27 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, ...@@ -445,204 +657,27 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
} else { } else {
/* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */ /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
/* I should put a macro for the calculus of bpp */ /* I should put a macro for the calculus of bpp */
GLuint current_texture;
/* Copy also the ColorKeying stuff */
if (src_d->dwFlags & DDSD_CKSRCBLT) {
dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
}
/* Copy the main memry texture into the surface that corresponds to the OpenGL /* Copy the main memry texture into the surface that corresponds to the OpenGL
texture object. */ texture object. */
memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight); memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
/* If the GetHandle was not done, it is an error... */
if (glThis->tex_name == 0) ERR("Unbound GL texture !!!\n");
ENTER_GL(); ENTER_GL();
/* Now, load the texture */ /* Now, load the texture */
/* d3dd->set_context(d3dd); We need to set the context somehow.... */ /* d3dd->set_context(d3dd); We need to set the context somehow.... */
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
/* If the GetHandle was not done, get the texture name here */ gltex_upload_texture(This, glThis->first_unlock);
if (glThis->tex_name == 0) glThis->first_unlock = FALSE;
glGenTextures(1, &(glThis->tex_name));
glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
/* ****************
Paletted Texture
**************** */
IDirectDrawPaletteImpl* pal = lpD3DTextureImpl->surface->palette;
BYTE table[256][4];
int i;
#if 0
if (color_table_queried == FALSE) {
ptr_ColorTableEXT =
((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
}
#endif
if (pal == NULL) {
ERR("Palettized texture Loading with a NULL palette !\n");
LEAVE_GL();
return D3DERR_TEXTURE_LOAD_FAILED;
}
/* Get the surface's palette */
for (i = 0; i < 256; i++) {
table[i][0] = pal->palents[i].peRed;
table[i][1] = pal->palents[i].peGreen;
table[i][2] = pal->palents[i].peBlue;
if ((This->surface->surface_desc.dwFlags & DDSD_CKSRCBLT) &&
(i >= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) &&
(i <= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
table[i][3] = 0x00;
else
table[i][3] = 0xFF;
}
/* Texture snooping */
SNOOP_PALETTED();
if (ptr_ColorTableEXT != NULL) {
/* use Paletted Texture Extension */
ptr_ColorTableEXT(GL_TEXTURE_2D, /* target */
GL_RGBA, /* internal format */
256, /* table size */
GL_RGBA, /* table format */
GL_UNSIGNED_BYTE, /* table type */
table); /* the color table */
glTexImage2D(GL_TEXTURE_2D, /* target */
0, /* level */
GL_COLOR_INDEX8_EXT, /* internal format */
src_d->dwWidth, src_d->dwHeight, /* width, height */
0, /* border */
GL_COLOR_INDEX, /* texture format */
GL_UNSIGNED_BYTE, /* texture type */
src_d->lpSurface); /* the texture */
} else {
DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
DWORD i;
BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
BYTE color = *src++;
*dst++ = table[color][0];
*dst++ = table[color][1];
*dst++ = table[color][2];
*dst++ = table[color][3];
}
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
surface);
HeapFree(GetProcessHeap(), 0, surface);
}
} else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
/* ************
RGB Textures
************ */
if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
/* **********************
GL_UNSIGNED_BYTE_3_3_2
********************** */
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE_3_3_2,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
/* Texture snooping */
SNOOP_5650();
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_SHORT_5_6_5,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
/* Texture snooping */
SNOOP_5551();
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
/* Converting the 1555 format in 5551 packed */
WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
DWORD i;
WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
*dst++ = (((*src & 0x8000) >> 15) |
((*src & 0x7FFF) << 1));
src++;
}
SNOOP_1555();
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_SHORT_5_5_5_1,
surface);
HeapFree(GetProcessHeap(), 0, surface);
} else {
ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
}
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
src_d->dwWidth, src_d->dwHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
src_d->lpSurface);
} else {
ERR("Unhandled texture format (bad RGB count)\n");
}
} else {
ERR("Unhandled texture format (neither RGB nor INDEX)\n");
}
glBindTexture(GL_TEXTURE_2D, current_texture);
LEAVE_GL(); LEAVE_GL();
} }
...@@ -651,28 +686,53 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, ...@@ -651,28 +686,53 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
} }
HRESULT WINAPI HRESULT WINAPI
Thunk_IDirect3DTextureImpl_2_QueryInterface(LPDIRECT3DTEXTURE2 iface,
REFIID riid,
LPVOID* obp)
{
TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface),
riid,
obp);
}
ULONG WINAPI
Thunk_IDirect3DTextureImpl_2_AddRef(LPDIRECT3DTEXTURE2 iface)
{
TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
}
ULONG WINAPI
Thunk_IDirect3DTextureImpl_2_Release(LPDIRECT3DTEXTURE2 iface)
{
TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
}
HRESULT WINAPI
Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface, Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface,
REFIID riid, REFIID riid,
LPVOID* obp) LPVOID* obp)
{ {
TRACE("(%p)->(%s,%p) thunking to IDirect3DTexture2 interface.\n", iface, debugstr_guid(riid), obp); TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
return IDirect3DTexture2_QueryInterface(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface), return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface),
riid, riid,
obp); obp);
} }
ULONG WINAPI ULONG WINAPI
Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface) Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface)
{ {
TRACE("(%p)->() thunking to IDirect3DTexture2 interface.\n", iface); TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
return IDirect3DTexture2_AddRef(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface)); return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
} }
ULONG WINAPI ULONG WINAPI
Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface) Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface)
{ {
TRACE("(%p)->() thunking to IDirect3DTexture2 interface.\n", iface); TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
return IDirect3DTexture2_Release(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface)); return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
} }
HRESULT WINAPI HRESULT WINAPI
...@@ -681,7 +741,7 @@ Thunk_IDirect3DTextureImpl_1_PaletteChanged(LPDIRECT3DTEXTURE iface, ...@@ -681,7 +741,7 @@ Thunk_IDirect3DTextureImpl_1_PaletteChanged(LPDIRECT3DTEXTURE iface,
DWORD dwCount) DWORD dwCount)
{ {
TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface, dwStart, dwCount); TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface, dwStart, dwCount);
return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface), return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
dwStart, dwStart,
dwCount); dwCount);
} }
...@@ -692,7 +752,7 @@ Thunk_IDirect3DTextureImpl_1_GetHandle(LPDIRECT3DTEXTURE iface, ...@@ -692,7 +752,7 @@ Thunk_IDirect3DTextureImpl_1_GetHandle(LPDIRECT3DTEXTURE iface,
LPD3DTEXTUREHANDLE lpHandle) LPD3DTEXTUREHANDLE lpHandle)
{ {
TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface, lpDirect3DDevice, lpHandle); TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface, lpDirect3DDevice, lpHandle);
return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface), return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice), COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice),
lpHandle); lpHandle);
} }
...@@ -702,8 +762,8 @@ Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface, ...@@ -702,8 +762,8 @@ Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface,
LPDIRECT3DTEXTURE lpD3DTexture) LPDIRECT3DTEXTURE lpD3DTexture)
{ {
TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface, lpD3DTexture); TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface, lpD3DTexture);
return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface), return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture)); COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture));
} }
#if !defined(__STRICT_ANSI__) && defined(__GNUC__) #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
...@@ -715,9 +775,9 @@ Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface, ...@@ -715,9 +775,9 @@ Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface,
ICOM_VTABLE(IDirect3DTexture2) VTABLE_IDirect3DTexture2 = ICOM_VTABLE(IDirect3DTexture2) VTABLE_IDirect3DTexture2 =
{ {
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
XCAST(QueryInterface) Main_IDirect3DTextureImpl_2_1T_QueryInterface, XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_2_QueryInterface,
XCAST(AddRef) Main_IDirect3DTextureImpl_2_1T_AddRef, XCAST(AddRef) Thunk_IDirect3DTextureImpl_2_AddRef,
XCAST(Release) GL_IDirect3DTextureImpl_2_1T_Release, XCAST(Release) Thunk_IDirect3DTextureImpl_2_Release,
XCAST(GetHandle) GL_IDirect3DTextureImpl_2_1T_GetHandle, XCAST(GetHandle) GL_IDirect3DTextureImpl_2_1T_GetHandle,
XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged, XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged,
XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load, XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load,
...@@ -751,26 +811,50 @@ ICOM_VTABLE(IDirect3DTexture) VTABLE_IDirect3DTexture = ...@@ -751,26 +811,50 @@ ICOM_VTABLE(IDirect3DTexture) VTABLE_IDirect3DTexture =
#undef XCAST #undef XCAST
#endif #endif
HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation,
IDirectDrawSurfaceImpl *main, DWORD mipmap_level)
HRESULT d3dtexture_create(IDirect3DTextureImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf)
{ {
IDirect3DTextureImpl *object; IDirect3DTextureGLImpl *private;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl)); private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
if (object == NULL) return DDERR_OUTOFMEMORY; if (private == NULL) return DDERR_OUTOFMEMORY;
object->ref = 1; private->final_release = surf->final_release;
object->d3d = d3d; private->lock_update = surf->lock_update;
object->surface = surf; private->unlock_update = surf->unlock_update;
private->mipmap_level = mipmap_level;
ICOM_INIT_INTERFACE(object, IDirect3DTexture, VTABLE_IDirect3DTexture); /* If at creation, we can optimize stuff and wait the first 'unlock' to upload a valid stuff to OpenGL.
ICOM_INIT_INTERFACE(object, IDirect3DTexture2, VTABLE_IDirect3DTexture2); Otherwise, it will be uploaded here (and may be invalid). */
if (at_creation == TRUE)
private->first_unlock = TRUE;
else
private->first_unlock = FALSE;
surf->final_release = gltex_final_release;
surf->lock_update = gltex_lock_update;
surf->unlock_update = gltex_unlock_update;
surf->tex_private = private;
surf->SetColorKey_cb = gltex_setcolorkey_cb;
ICOM_INIT_INTERFACE(surf, IDirect3DTexture, VTABLE_IDirect3DTexture);
ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
if (mipmap_level == 0) {
ENTER_GL();
glGenTextures(1, &(private->tex_name));
if (private->tex_name == 0) ERR("Error at creation of OpenGL texture ID !\n");
TRACE(" GL texture created (private data at %p and GL id %d).\n", private, private->tex_name);
} else {
private->tex_name = ((IDirect3DTextureGLImpl *) main->tex_private)->tex_name;
TRACE(" GL texture created (private data at %p and GL id reusing id %d).\n", private, private->tex_name);
}
*obj = object; if ((at_creation == FALSE) &&
((surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) == 0))
{
gltex_upload_texture(surf, TRUE);
}
LEAVE_GL();
TRACE(" creating implementation at %p.\n", *obj);
return D3D_OK; return D3D_OK;
} }
...@@ -303,7 +303,7 @@ HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirect3DImpl *d ...@@ -303,7 +303,7 @@ HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirect3DImpl *d
object->ref = 1; object->ref = 1;
object->d3d = d3d; object->d3d = d3d;
object->desc = *lpD3DVertBufDesc; object->desc = *lpD3DVertBufDesc;
object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices; object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF, NULL) * lpD3DVertBufDesc->dwNumVertices;
object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size); object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer); ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
......
...@@ -177,7 +177,10 @@ HRESULT WINAPI Main_DirectDraw_QueryInterface( ...@@ -177,7 +177,10 @@ HRESULT WINAPI Main_DirectDraw_QueryInterface(
*obj = ICOM_INTERFACE(This, IDirectDraw4); *obj = ICOM_INTERFACE(This, IDirectDraw4);
} }
#ifdef HAVE_OPENGL #ifdef HAVE_OPENGL
else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ) else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ||
IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
IsEqualGUID( &IID_IDirect3D7 , refiid ) )
{ {
IDirect3DImpl *d3d_impl; IDirect3DImpl *d3d_impl;
HRESULT ret_value; HRESULT ret_value;
...@@ -185,48 +188,22 @@ HRESULT WINAPI Main_DirectDraw_QueryInterface( ...@@ -185,48 +188,22 @@ HRESULT WINAPI Main_DirectDraw_QueryInterface(
ret_value = direct3d_create(&d3d_impl, This); ret_value = direct3d_create(&d3d_impl, This);
if (FAILED(ret_value)) return ret_value; if (FAILED(ret_value)) return ret_value;
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D); if ( IsEqualGUID( &IID_IDirect3D , refiid ) ) {
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D);
TRACE(" returning Direct3D interface at %p.\n", *obj);
} else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) ) {
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D2);
TRACE(" returning Direct3D2 interface at %p.\n", *obj);
} else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) ) {
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D3);
TRACE(" returning Direct3D3 interface at %p.\n", *obj);
} else {
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D7);
TRACE(" returning Direct3D7 interface at %p.\n", *obj);
}
/* And store the D3D object */ /* And store the D3D object */
This->d3d = d3d_impl; This->d3d = d3d_impl;
TRACE(" returning Direct3D interface at %p.\n", *obj);
}
else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
{
IDirect3DImpl *d3d_impl;
HRESULT ret_value;
ret_value = direct3d_create(&d3d_impl, This);
if (FAILED(ret_value)) return ret_value;
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D2);
TRACE(" returning Direct3D2 interface at %p.\n", *obj);
}
else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
{
IDirect3DImpl *d3d_impl;
HRESULT ret_value;
ret_value = direct3d_create(&d3d_impl, This);
if (FAILED(ret_value)) return ret_value;
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D3);
TRACE(" returning Direct3D3 interface at %p.\n", *obj);
}
else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
{
IDirect3DImpl *d3d_impl;
HRESULT ret_value;
ret_value = direct3d_create(&d3d_impl, This);
if (FAILED(ret_value)) return ret_value;
*obj = ICOM_INTERFACE(d3d_impl, IDirect3D7);
TRACE(" returning Direct3D7 interface at %p.\n", *obj);
} }
#endif #endif
else else
...@@ -375,6 +352,9 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD, ...@@ -375,6 +352,9 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
hr = This->create_texture(This, &ddsd, ppSurf, pUnkOuter, mipmap_level); hr = This->create_texture(This, &ddsd, ppSurf, pUnkOuter, mipmap_level);
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,
ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), mipmap_level);
/* Create attached mipmaps if required. */ /* Create attached mipmaps if required. */
if (more_mipmaps(&ddsd)) if (more_mipmaps(&ddsd))
{ {
...@@ -411,6 +391,8 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD, ...@@ -411,6 +391,8 @@ create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,
IDirectDrawSurface7_Release(*ppSurf); IDirectDrawSurface7_Release(*ppSurf);
return hr; return hr;
} }
if (This->d3d) This->d3d->create_texture(This->d3d, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE,
ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), mipmap_level);
IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap); IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap);
IDirectDrawSurface7_Release(prev_mipmap); IDirectDrawSurface7_Release(prev_mipmap);
...@@ -1131,6 +1113,11 @@ Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps, ...@@ -1131,6 +1113,11 @@ Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
ICOM_THIS(IDirectDrawImpl,iface); ICOM_THIS(IDirectDrawImpl,iface);
TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free); TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free);
if (TRACE_ON(ddraw)) {
TRACE(" Asking for memory of type : \n");
DDRAW_dump_DDSCAPS2(ddscaps);
}
/* We have 16 MB videomemory */ /* We have 16 MB videomemory */
if (total) *total= This->total_vidmem; if (total) *total= This->total_vidmem;
if (free) *free = This->available_vidmem; if (free) *free = This->available_vidmem;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "ddraw.h" #include "ddraw.h"
#include "d3d.h"
#include "ddcomimpl.h" #include "ddcomimpl.h"
#include "ddrawi.h" #include "ddrawi.h"
...@@ -220,6 +221,8 @@ struct IDirectDrawSurfaceImpl ...@@ -220,6 +221,8 @@ struct IDirectDrawSurfaceImpl
ICOM_VFIELD_MULTI(IDirectDrawSurface7); ICOM_VFIELD_MULTI(IDirectDrawSurface7);
ICOM_VFIELD_MULTI(IDirectDrawSurface3); ICOM_VFIELD_MULTI(IDirectDrawSurface3);
ICOM_VFIELD_MULTI(IDirectDrawGammaControl); ICOM_VFIELD_MULTI(IDirectDrawGammaControl);
ICOM_VFIELD_MULTI(IDirect3DTexture2);
ICOM_VFIELD_MULTI(IDirect3DTexture);
DWORD ref; DWORD ref;
struct IDirectDrawSurfaceImpl* attached; /* attached surfaces */ struct IDirectDrawSurfaceImpl* attached; /* attached surfaces */
...@@ -289,10 +292,10 @@ struct IDirectDrawSurfaceImpl ...@@ -289,10 +292,10 @@ struct IDirectDrawSurfaceImpl
void (*aux_release)(LPVOID ctx, LPVOID data); void (*aux_release)(LPVOID ctx, LPVOID data);
BOOL (*aux_flip)(LPVOID ctx, LPVOID data); BOOL (*aux_flip)(LPVOID ctx, LPVOID data);
void (*aux_unlock)(LPVOID ctx, LPVOID data, LPRECT lpRect); void (*aux_unlock)(LPVOID ctx, LPVOID data, LPRECT lpRect);
struct IDirect3DTextureImpl *texture; HRESULT (WINAPI *SetColorKey_cb)(struct IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
HRESULT (WINAPI *SetColorKey_cb)(struct IDirect3DTextureImpl *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;
LPVOID tex_private;
}; };
/***************************************************************************** /*****************************************************************************
......
...@@ -387,6 +387,7 @@ HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw) ...@@ -387,6 +387,7 @@ HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw)
object->ref = 1; object->ref = 1;
object->ddraw = ddraw; object->ddraw = ddraw;
object->create_texture = d3dtexture_create;
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);
......
...@@ -81,7 +81,7 @@ Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This, ...@@ -81,7 +81,7 @@ Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
DDRAW_IDDS3_Thunk_VTable); DDRAW_IDDS3_Thunk_VTable);
ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl, ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl,
DDRAW_IDDGC_VTable); DDRAW_IDDGC_VTable);
/* There is no generic implementation of IDDS7 */ /* There is no generic implementation of IDDS7 or texture */
Main_DirectDraw_AddSurface(pDD, This); Main_DirectDraw_AddSurface(pDD, This);
return DD_OK; return DD_OK;
...@@ -101,6 +101,7 @@ static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This) ...@@ -101,6 +101,7 @@ static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This)
{ {
This->final_release(This); This->final_release(This);
if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private); if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private);
if (This->tex_private) HeapFree(GetProcessHeap(), 0, This->tex_private);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
...@@ -146,6 +147,8 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid, ...@@ -146,6 +147,8 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
ICOM_THIS(IDirectDrawSurfaceImpl, iface); ICOM_THIS(IDirectDrawSurfaceImpl, iface);
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj); TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj);
*ppObj = NULL;
if (IsEqualGUID(&IID_IUnknown, riid) if (IsEqualGUID(&IID_IUnknown, riid)
|| IsEqualGUID(&IID_IDirectDrawSurface7, riid) || IsEqualGUID(&IID_IDirectDrawSurface7, riid)
|| IsEqualGUID(&IID_IDirectDrawSurface4, riid)) || IsEqualGUID(&IID_IDirectDrawSurface4, riid))
...@@ -184,32 +187,38 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid, ...@@ -184,32 +187,38 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid,
This->ref++; /* No idea if this is correct.. Need to check using real Windows */ This->ref++; /* No idea if this is correct.. Need to check using real Windows */
return ret_value; return ret_value;
} }
else if (IsEqualGUID( &IID_IDirect3DTexture, riid )) else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
{ IsEqualGUID( &IID_IDirect3DTexture2, riid ))
IDirect3DTextureImpl *d3dteximpl;
HRESULT ret_value;
ret_value = d3dtexture_create(&d3dteximpl, NULL, This);
if (FAILED(ret_value)) return ret_value;
*ppObj = ICOM_INTERFACE(d3dteximpl, IDirect3DTexture);
TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
This->ref++; /* No idea if this is correct.. Need to check using real Windows */
return ret_value;
}
else if (IsEqualGUID( &IID_IDirect3DTexture2, riid ))
{ {
IDirect3DTextureImpl *d3dteximpl; HRESULT ret_value = S_OK;
HRESULT ret_value;
/* In case the texture surface was created before the D3D creation */
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... */
if ((This->tex_private == NULL) &&
((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY)) == 0)) {
if (This->ddraw_owner->d3d == NULL) {
ERR("Texture created with no D3D object yet.. Not supported !\n");
return E_NOINTERFACE;
}
ret_value = d3dtexture_create(&d3dteximpl, NULL, This); if (((This->surface_desc.dwFlags & DDSD_MIPMAPCOUNT) &&
if (FAILED(ret_value)) return ret_value; (This->surface_desc.u2.dwMipMapCount > 1)) ||
(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)) {
ERR(" need to fix mipmaping in this case !!\n");
}
*ppObj = ICOM_INTERFACE(d3dteximpl, IDirect3DTexture2); ret_value = This->ddraw_owner->d3d->create_texture(This->ddraw_owner->d3d, This, FALSE, NULL, 0);
TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj); if (FAILED(ret_value)) return ret_value;
}
This->ref++; /* No idea if this is correct.. Need to check using real Windows */ if (IsEqualGUID( &IID_IDirect3DTexture, riid )) {
*ppObj = ICOM_INTERFACE(This, IDirect3DTexture);
TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
} else {
*ppObj = ICOM_INTERFACE(This, IDirect3DTexture2);
TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
}
This->ref++;
return ret_value; return ret_value;
} }
#endif #endif
......
...@@ -46,14 +46,14 @@ void set_render_state(D3DRENDERSTATETYPE dwRenderStateType, ...@@ -46,14 +46,14 @@ void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
/* All others state variables */ /* All others state variables */
switch (dwRenderStateType) { switch (dwRenderStateType) {
case D3DRENDERSTATE_TEXTUREHANDLE: { /* 1 */ case D3DRENDERSTATE_TEXTUREHANDLE: { /* 1 */
IDirect3DTextureImpl *tex = (IDirect3DTextureImpl*) dwRenderState; IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState;
if (tex == NULL) { if (tex == NULL) {
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
TRACE("disabling texturing\n"); TRACE("disabling texturing\n");
} else { } else {
IDirect3DTextureGLImpl *gl_tex = (IDirect3DTextureGLImpl *) tex; IDirect3DTextureGLImpl *gl_tex = (IDirect3DTextureGLImpl *) tex->tex_private;
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
/* Default parameters */ /* Default parameters */
......
...@@ -82,10 +82,17 @@ typedef struct IDirect3DLightGLImpl ...@@ -82,10 +82,17 @@ typedef struct IDirect3DLightGLImpl
GLenum light_num; GLenum light_num;
} IDirect3DLightGLImpl; } IDirect3DLightGLImpl;
/* This structure is used for the 'private' field of the IDirectDrawSurfaceImpl structure */
typedef struct IDirect3DTextureGLImpl typedef struct IDirect3DTextureGLImpl
{ {
struct IDirect3DTextureImpl parent;
GLuint tex_name; GLuint tex_name;
BOOLEAN loaded; /* For the moment, this is here.. Should be part of surface management though */
BOOLEAN first_unlock;
DWORD mipmap_level;
/* This is for now used to override 'standard' surface stuff to be as transparent as possible */
void (*final_release)(struct IDirectDrawSurfaceImpl *This);
void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
} IDirect3DTextureGLImpl; } IDirect3DTextureGLImpl;
typedef struct IDirect3DDeviceGLImpl typedef struct IDirect3DDeviceGLImpl
...@@ -111,7 +118,7 @@ typedef struct IDirect3DDeviceGLImpl ...@@ -111,7 +118,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(IDirect3DTextureImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf); extern HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf, DWORD mipmap_level);
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);
...@@ -126,7 +133,7 @@ extern HRESULT d3ddevice_find(IDirect3DImpl *d3d, LPD3DFINDDEVICESEARCH lpD3DDFS ...@@ -126,7 +133,7 @@ extern HRESULT d3ddevice_find(IDirect3DImpl *d3d, LPD3DFINDDEVICESEARCH lpD3DDFS
/* Some helper functions.. Would need to put them in a better place */ /* Some helper functions.. Would need to put them in a better place */
extern void dump_flexible_vertex(DWORD d3dvtVertexType); extern void dump_flexible_vertex(DWORD d3dvtVertexType);
extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType); extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements);
/* Matrix copy WITH transposition */ /* Matrix copy WITH transposition */
#define conv_mat2(mat,gl_mat) \ #define conv_mat2(mat,gl_mat) \
......
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