From 81c7544184e3a4c3b1dc5154c569bc7bc2be4cd3 Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Tue, 6 Apr 1999 07:10:48 +0000 Subject: [PATCH] - clean-up of texture 'loading' - added SetColorKey callback for already loaded textures --- graphics/d3d_private.h | 5 +- graphics/d3dtexture.c | 225 ++++++++++++++++++++++++++++++++++------------- graphics/ddraw.c | 31 +++++++ graphics/ddraw_private.h | 6 +- 4 files changed, 202 insertions(+), 65 deletions(-) diff --git a/graphics/d3d_private.h b/graphics/d3d_private.h index cc44b1fa4b1..519688ea555 100644 --- a/graphics/d3d_private.h +++ b/graphics/d3d_private.h @@ -8,12 +8,8 @@ #define __GRAPHICS_WINE_D3D_PRIVATE_H #include "wine_gl.h" - #include "d3d.h" -#include "ddraw_private.h" - - /***************************************************************************** * Predeclare the interface implementation structures */ @@ -27,6 +23,7 @@ typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl; typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl; typedef struct IDirect3DDevice2Impl IDirect3DDevice2Impl; +#include "ddraw_private.h" /***************************************************************************** * IDirect3D implementation structure diff --git a/graphics/d3dtexture.c b/graphics/d3dtexture.c index 2dfeadf91d3..5f4fea057e9 100644 --- a/graphics/d3dtexture.c +++ b/graphics/d3dtexture.c @@ -23,6 +23,72 @@ texture memory) */ #undef TEXTURE_SNOOP +#ifdef TEXTURE_SNOOP +#define SNOOP_PALETTED() \ + { \ + FILE *f; \ + char buf[32]; \ + int x, y; \ + \ + sprintf(buf, "%d.pnm", This->tex_name); \ + f = fopen(buf, "wb"); \ + fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ + for (y = 0; y < src_d->dwHeight; y++) { \ + for (x = 0; x < src_d->dwWidth; x++) { \ + unsigned char c = ((unsigned char *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \ + fputc(table[c][0], f); \ + fputc(table[c][1], f); \ + fputc(table[c][2], f); \ + } \ + } \ + fclose(f); \ + } + +#define SNOOP_5650() \ + { \ + FILE *f; \ + char buf[32]; \ + int x, y; \ + \ + sprintf(buf, "%d.pnm", This->tex_name); \ + f = fopen(buf, "wb"); \ + fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ + for (y = 0; y < src_d->dwHeight; y++) { \ + for (x = 0; x < src_d->dwWidth; x++) { \ + unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \ + fputc((c & 0xF800) >> 8, f); \ + fputc((c & 0x07E0) >> 3, f); \ + fputc((c & 0x001F) << 3, f); \ + } \ + } \ + fclose(f); \ + } + +#define SNOOP_5551() \ + { \ + FILE *f; \ + char buf[32]; \ + int x, y; \ + \ + sprintf(buf, "%d.pnm", This->tex_name); \ + f = fopen(buf, "wb"); \ + fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ + for (y = 0; y < src_d->dwHeight; y++) { \ + for (x = 0; x < src_d->dwWidth; x++) { \ + unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \ + fputc((c & 0xF800) >> 8, f); \ + fputc((c & 0x07C0) >> 3, f); \ + fputc((c & 0x003E) << 2, f); \ + } \ + } \ + fclose(f); \ + } +#else +#define SNOOP_PALETTED() +#define SNOOP_5650() +#define SNOOP_5551() +#endif + static ICOM_VTABLE(IDirect3DTexture2) texture2_vtable; static ICOM_VTABLE(IDirect3DTexture) texture_vtable; @@ -56,6 +122,91 @@ LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurface4Impl* surf) return (LPDIRECT3DTEXTURE)tex; } +/******************************************************************************* + * IDirectSurface callback methods + */ +HRESULT WINAPI SetColorKey_cb(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) +{ + DDSURFACEDESC *tex_d; + int bpp; + GLuint current_texture; + + TRACE(ddraw, "(%p) : colorkey callback\n", texture); + + /* Get the texture description */ + tex_d = &(texture->surface->s.surface_desc); + bpp = (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? + 1 /* 8 bit of palette index */: + tex_d->ddpfPixelFormat.x.dwRGBBitCount / 8 /* RGB bits for each colors */ ); + + /* Now, save the current texture */ + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); + + /* If the GetHandle was not done yet, it's an error */ + if (texture->tex_name == 0) { + ERR(ddraw, "Unloaded texture !\n"); + return DD_OK; + } + glBindTexture(GL_TEXTURE_2D, texture->tex_name); + + if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { + FIXME(ddraw, "Todo Paletted\n"); + } else if (tex_d->ddpfPixelFormat.dwFlags & DDPF_RGB) { + if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 8) { + FIXME(ddraw, "Todo 3_3_2_0\n"); + } else if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 16) { + if (tex_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000000) { + /* Now transform the 5_6_5 into a 5_5_5_1 surface to support color keying */ + unsigned short *dest = (unsigned short *) HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + tex_d->dwWidth * tex_d->dwHeight * bpp); + unsigned short *src = (unsigned short *) tex_d->y.lpSurface; + int x, y; + + for (y = 0; y < tex_d->dwHeight; y++) { + for (x = 0; x < tex_d->dwWidth; x++) { + unsigned short cpixel = src[x + y * tex_d->dwWidth]; + + if ((dwFlags & DDCKEY_SRCBLT) && + (cpixel >= ckey->dwColorSpaceLowValue) && + (cpixel <= ckey->dwColorSpaceHighValue)) /* No alpha bit => this pixel is transparent */ + dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0000; + else /* Alpha bit is set => this pixel will be seen */ + dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0001; + } + } + + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA, + tex_d->dwWidth, tex_d->dwHeight, + 0, + GL_RGBA, + GL_UNSIGNED_SHORT_5_5_5_1, + dest); + + /* Frees the temporary surface */ + HeapFree(GetProcessHeap(),0,dest); + } else if (tex_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000001) { + FIXME(ddraw, "Todo 5_5_5_1\n"); + } else if (tex_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x0000000F) { + FIXME(ddraw, "Todo 4_4_4_4\n"); + } else { + ERR(ddraw, "Unhandled texture format (bad Aplha channel for a 16 bit texture)\n"); + } + } else if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 24) { + FIXME(ddraw, "Todo 8_8_8_0\n"); + } else if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 32) { + FIXME(ddraw, "Todo 8_8_8_8\n"); + } else { + ERR(ddraw, "Unhandled texture format (bad RGB count)\n"); + } + } else { + ERR(ddraw, "Unhandled texture format (neither RGB nor INDEX)\n"); + } + + return DD_OK; +} /******************************************************************************* * IDirect3DTexture2 methods @@ -189,7 +340,7 @@ static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface, DDSURFACEDESC *src_d, *dst_d; TRACE(ddraw, "(%p)->(%p)\n", This, ilpD3DTexture2); - TRACE(ddraw, "Copied to surface %p, surface %p\n", This->surface, ilpD3DTexture2->surface); + TRACE(ddraw, "Copied surface %p to surface %p\n", ilpD3DTexture2->surface, This->surface); /* Suppress the ALLOCONLOAD flag */ This->surface->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; @@ -198,6 +349,10 @@ static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface, dst_d = &(This->surface->s.surface_desc); src_d = &(ilpD3DTexture2->surface->s.surface_desc); + /* Install the callbacks to the destination surface */ + This->surface->s.texture = This; + This->surface->s.SetColorKey_cb = SetColorKey_cb; + if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) { /* Should also check for same pixel format, lPitch, ... */ ERR(ddraw, "Error in surface sizes\n"); @@ -210,7 +365,8 @@ static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface, src_d->ddpfPixelFormat.x.dwRGBBitCount / 8 /* RGB bits for each colors */ ); GLuint current_texture; - /* Not sure if this is usefull ! */ + /* Copy the main memry texture into the surface that corresponds to the OpenGL + texture object. */ memcpy(dst_d->y.lpSurface, src_d->y.lpSurface, src_d->dwWidth * src_d->dwHeight * bpp); /* Now, load the texture */ @@ -248,26 +404,9 @@ static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface, table[i][3] = 0xFF; } -#ifdef TEXTURE_SNOOP - { - FILE *f; - char buf[32]; - int x, y; + /* Texture snooping */ + SNOOP_PALETTED(); - sprintf(buf, "%d.pnm", This->tex_name); - f = fopen(buf, "wb"); - fprintf(f, "P6\n%d %d\n255\n", src_d->dwWidth, src_d->dwHeight); - for (y = 0; y < src_d->dwHeight; y++) { - for (x = 0; x < src_d->dwWidth; x++) { - unsigned char c = ((unsigned char *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; - fputc(table[c][0], f); - fputc(table[c][1], f); - fputc(table[c][2], f); - } - } - fclose(f); - } -#endif /* Use Paletted Texture Extension */ glColorTableEXT(GL_TEXTURE_2D, /* target */ GL_RGBA, /* internal format */ @@ -302,26 +441,10 @@ static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface, src_d->y.lpSurface); } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 16) { if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000000) { -#ifdef TEXTURE_SNOOP - { - FILE *f; - char buf[32]; - int x, y; - sprintf(buf, "%d.pnm", This->tex_name); - f = fopen(buf, "wb"); - fprintf(f, "P6\n%d %d\n255\n", src_d->dwWidth, src_d->dwHeight); - for (y = 0; y < src_d->dwHeight; y++) { - for (x = 0; x < src_d->dwWidth; x++) { - unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; - fputc((c & 0xF800) >> 8, f); - fputc((c & 0x07E0) >> 3, f); - fputc((c & 0x001F) << 3, f); - } - } - fclose(f); - } -#endif + /* Texture snooping */ + SNOOP_5650(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, @@ -331,26 +454,8 @@ static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface, GL_UNSIGNED_SHORT_5_6_5, src_d->y.lpSurface); } else if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000001) { -#ifdef TEXTURE_SNOOP - { - FILE *f; - char buf[32]; - int x, y; - - sprintf(buf, "%d.pnm", This->tex_name); - f = fopen(buf, "wb"); - fprintf(f, "P6\n%d %d\n255\n", src_d->dwWidth, src_d->dwHeight); - for (y = 0; y < src_d->dwHeight; y++) { - for (x = 0; x < src_d->dwWidth; x++) { - unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; - fputc((c & 0xF800) >> 8, f); - fputc((c & 0x07C0) >> 3, f); - fputc((c & 0x003E) << 2, f); - } - } - fclose(f); - } -#endif + /* Texture snooping */ + SNOOP_5551(); glTexImage2D(GL_TEXTURE_2D, 0, diff --git a/graphics/ddraw.c b/graphics/ddraw.c index c1633bf7952..70ce4defb9f 100644 --- a/graphics/ddraw.c +++ b/graphics/ddraw.c @@ -506,6 +506,25 @@ static void _dump_pixelformat(LPDDPIXELFORMAT pf) { pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask); } +static void _dump_colorkeyflag(DWORD ck) { + int i; + const struct { + DWORD mask; + char *name; + } flags[] = { +#define FE(x) { x, #x}, + FE(DDCKEY_COLORSPACE) + FE(DDCKEY_DESTBLT) + FE(DDCKEY_DESTOVERLAY) + FE(DDCKEY_SRCBLT) + FE(DDCKEY_SRCOVERLAY) + }; + for (i=0;i(0x%08lx,%p)\n",This,dwFlags,ckey); + if (TRACE_ON(ddraw)) { + DUMP(" (0x%08lx <-> 0x%08lx) - ", + ckey->dwColorSpaceLowValue, + ckey->dwColorSpaceHighValue); + _dump_colorkeyflag(dwFlags); + } + + /* If this surface was loaded as a texture, call also the texture + SetColorKey callback */ + if (This->s.texture) { + This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey); + } if( dwFlags & DDCKEY_SRCBLT ) { diff --git a/graphics/ddraw_private.h b/graphics/ddraw_private.h index 9e8857046d0..48ccb83756e 100644 --- a/graphics/ddraw_private.h +++ b/graphics/ddraw_private.h @@ -3,7 +3,6 @@ #include "ddraw.h" - /***************************************************************************** * Predeclare the interface implementation structures */ @@ -18,6 +17,7 @@ typedef struct IDirectDrawSurface4Impl IDirectDrawSurface3Impl; typedef struct IDirectDrawSurface4Impl IDirectDrawSurface4Impl; typedef struct IDirectDrawColorControlImpl IDirectDrawColorControlImpl; +#include "d3d_private.h" /***************************************************************************** * IDirectDrawPalette implementation structure @@ -143,6 +143,10 @@ struct _common_directdrawsurface IDirectDrawSurface4Impl* backbuffer; DDSURFACEDESC surface_desc; + + /* Callback for loaded textures */ + IDirect3DTexture2Impl* texture; + HRESULT WINAPI (*SetColorKey_cb)(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ; }; struct _dga_directdrawsurface -- 2.11.4.GIT