Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 1 | /* Direct3D Texture |
| 2 | (c) 1998 Lionel ULMER |
| 3 | |
| 4 | This files contains the implementation of interface Direct3DTexture2. */ |
| 5 | |
| 6 | |
David Luyer | ee517e8 | 1999-02-28 12:27:56 +0000 | [diff] [blame] | 7 | #include <string.h> |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 8 | #include "config.h" |
Jim Aston | 2e1cafa | 1999-03-14 16:35:05 +0000 | [diff] [blame] | 9 | #include "windef.h" |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 10 | #include "winerror.h" |
Francois Gouget | a94d649 | 1999-02-02 16:14:23 +0000 | [diff] [blame] | 11 | #include "wine/obj_base.h" |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 12 | #include "heap.h" |
| 13 | #include "ddraw.h" |
| 14 | #include "d3d.h" |
| 15 | #include "debug.h" |
| 16 | |
| 17 | #include "d3d_private.h" |
| 18 | |
| 19 | #ifdef HAVE_MESAGL |
| 20 | |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 21 | /* Define this if you want to save to a file all the textures used by a game |
| 22 | (can be funny to see how they managed to cram all the pictures in |
| 23 | texture memory) */ |
| 24 | #undef TEXTURE_SNOOP |
| 25 | |
Lionel Ulmer | 81c7544 | 1999-04-06 07:10:48 +0000 | [diff] [blame^] | 26 | #ifdef TEXTURE_SNOOP |
| 27 | #define SNOOP_PALETTED() \ |
| 28 | { \ |
| 29 | FILE *f; \ |
| 30 | char buf[32]; \ |
| 31 | int x, y; \ |
| 32 | \ |
| 33 | sprintf(buf, "%d.pnm", This->tex_name); \ |
| 34 | f = fopen(buf, "wb"); \ |
| 35 | fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ |
| 36 | for (y = 0; y < src_d->dwHeight; y++) { \ |
| 37 | for (x = 0; x < src_d->dwWidth; x++) { \ |
| 38 | unsigned char c = ((unsigned char *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \ |
| 39 | fputc(table[c][0], f); \ |
| 40 | fputc(table[c][1], f); \ |
| 41 | fputc(table[c][2], f); \ |
| 42 | } \ |
| 43 | } \ |
| 44 | fclose(f); \ |
| 45 | } |
| 46 | |
| 47 | #define SNOOP_5650() \ |
| 48 | { \ |
| 49 | FILE *f; \ |
| 50 | char buf[32]; \ |
| 51 | int x, y; \ |
| 52 | \ |
| 53 | sprintf(buf, "%d.pnm", This->tex_name); \ |
| 54 | f = fopen(buf, "wb"); \ |
| 55 | fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ |
| 56 | for (y = 0; y < src_d->dwHeight; y++) { \ |
| 57 | for (x = 0; x < src_d->dwWidth; x++) { \ |
| 58 | unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \ |
| 59 | fputc((c & 0xF800) >> 8, f); \ |
| 60 | fputc((c & 0x07E0) >> 3, f); \ |
| 61 | fputc((c & 0x001F) << 3, f); \ |
| 62 | } \ |
| 63 | } \ |
| 64 | fclose(f); \ |
| 65 | } |
| 66 | |
| 67 | #define SNOOP_5551() \ |
| 68 | { \ |
| 69 | FILE *f; \ |
| 70 | char buf[32]; \ |
| 71 | int x, y; \ |
| 72 | \ |
| 73 | sprintf(buf, "%d.pnm", This->tex_name); \ |
| 74 | f = fopen(buf, "wb"); \ |
| 75 | fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ |
| 76 | for (y = 0; y < src_d->dwHeight; y++) { \ |
| 77 | for (x = 0; x < src_d->dwWidth; x++) { \ |
| 78 | unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \ |
| 79 | fputc((c & 0xF800) >> 8, f); \ |
| 80 | fputc((c & 0x07C0) >> 3, f); \ |
| 81 | fputc((c & 0x003E) << 2, f); \ |
| 82 | } \ |
| 83 | } \ |
| 84 | fclose(f); \ |
| 85 | } |
| 86 | #else |
| 87 | #define SNOOP_PALETTED() |
| 88 | #define SNOOP_5650() |
| 89 | #define SNOOP_5551() |
| 90 | #endif |
| 91 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 92 | static ICOM_VTABLE(IDirect3DTexture2) texture2_vtable; |
| 93 | static ICOM_VTABLE(IDirect3DTexture) texture_vtable; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 94 | |
| 95 | /******************************************************************************* |
| 96 | * Texture2 Creation functions |
| 97 | */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 98 | LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurface4Impl* surf) |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 99 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 100 | IDirect3DTexture2Impl* tex; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 101 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 102 | tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl)); |
| 103 | tex->ref = 1; |
| 104 | tex->lpvtbl = &texture2_vtable; |
| 105 | tex->surface = surf; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 106 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 107 | return (LPDIRECT3DTEXTURE2)tex; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 108 | } |
| 109 | |
| 110 | /******************************************************************************* |
| 111 | * Texture Creation functions |
| 112 | */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 113 | LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurface4Impl* surf) |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 114 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 115 | IDirect3DTexture2Impl* tex; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 116 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 117 | tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl)); |
| 118 | tex->ref = 1; |
| 119 | tex->lpvtbl = (ICOM_VTABLE(IDirect3DTexture2)*)&texture_vtable; |
| 120 | tex->surface = surf; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 121 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 122 | return (LPDIRECT3DTEXTURE)tex; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 123 | } |
| 124 | |
Lionel Ulmer | 81c7544 | 1999-04-06 07:10:48 +0000 | [diff] [blame^] | 125 | /******************************************************************************* |
| 126 | * IDirectSurface callback methods |
| 127 | */ |
| 128 | HRESULT WINAPI SetColorKey_cb(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) |
| 129 | { |
| 130 | DDSURFACEDESC *tex_d; |
| 131 | int bpp; |
| 132 | GLuint current_texture; |
| 133 | |
| 134 | TRACE(ddraw, "(%p) : colorkey callback\n", texture); |
| 135 | |
| 136 | /* Get the texture description */ |
| 137 | tex_d = &(texture->surface->s.surface_desc); |
| 138 | bpp = (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? |
| 139 | 1 /* 8 bit of palette index */: |
| 140 | tex_d->ddpfPixelFormat.x.dwRGBBitCount / 8 /* RGB bits for each colors */ ); |
| 141 | |
| 142 | /* Now, save the current texture */ |
| 143 | glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); |
| 144 | |
| 145 | /* If the GetHandle was not done yet, it's an error */ |
| 146 | if (texture->tex_name == 0) { |
| 147 | ERR(ddraw, "Unloaded texture !\n"); |
| 148 | return DD_OK; |
| 149 | } |
| 150 | glBindTexture(GL_TEXTURE_2D, texture->tex_name); |
| 151 | |
| 152 | if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { |
| 153 | FIXME(ddraw, "Todo Paletted\n"); |
| 154 | } else if (tex_d->ddpfPixelFormat.dwFlags & DDPF_RGB) { |
| 155 | if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 8) { |
| 156 | FIXME(ddraw, "Todo 3_3_2_0\n"); |
| 157 | } else if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 16) { |
| 158 | if (tex_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000000) { |
| 159 | /* Now transform the 5_6_5 into a 5_5_5_1 surface to support color keying */ |
| 160 | unsigned short *dest = (unsigned short *) HeapAlloc(GetProcessHeap(), |
| 161 | HEAP_ZERO_MEMORY, |
| 162 | tex_d->dwWidth * tex_d->dwHeight * bpp); |
| 163 | unsigned short *src = (unsigned short *) tex_d->y.lpSurface; |
| 164 | int x, y; |
| 165 | |
| 166 | for (y = 0; y < tex_d->dwHeight; y++) { |
| 167 | for (x = 0; x < tex_d->dwWidth; x++) { |
| 168 | unsigned short cpixel = src[x + y * tex_d->dwWidth]; |
| 169 | |
| 170 | if ((dwFlags & DDCKEY_SRCBLT) && |
| 171 | (cpixel >= ckey->dwColorSpaceLowValue) && |
| 172 | (cpixel <= ckey->dwColorSpaceHighValue)) /* No alpha bit => this pixel is transparent */ |
| 173 | dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0000; |
| 174 | else /* Alpha bit is set => this pixel will be seen */ |
| 175 | dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0001; |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | glTexImage2D(GL_TEXTURE_2D, |
| 180 | 0, |
| 181 | GL_RGBA, |
| 182 | tex_d->dwWidth, tex_d->dwHeight, |
| 183 | 0, |
| 184 | GL_RGBA, |
| 185 | GL_UNSIGNED_SHORT_5_5_5_1, |
| 186 | dest); |
| 187 | |
| 188 | /* Frees the temporary surface */ |
| 189 | HeapFree(GetProcessHeap(),0,dest); |
| 190 | } else if (tex_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000001) { |
| 191 | FIXME(ddraw, "Todo 5_5_5_1\n"); |
| 192 | } else if (tex_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x0000000F) { |
| 193 | FIXME(ddraw, "Todo 4_4_4_4\n"); |
| 194 | } else { |
| 195 | ERR(ddraw, "Unhandled texture format (bad Aplha channel for a 16 bit texture)\n"); |
| 196 | } |
| 197 | } else if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 24) { |
| 198 | FIXME(ddraw, "Todo 8_8_8_0\n"); |
| 199 | } else if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 32) { |
| 200 | FIXME(ddraw, "Todo 8_8_8_8\n"); |
| 201 | } else { |
| 202 | ERR(ddraw, "Unhandled texture format (bad RGB count)\n"); |
| 203 | } |
| 204 | } else { |
| 205 | ERR(ddraw, "Unhandled texture format (neither RGB nor INDEX)\n"); |
| 206 | } |
| 207 | |
| 208 | return DD_OK; |
| 209 | } |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 210 | |
| 211 | /******************************************************************************* |
| 212 | * IDirect3DTexture2 methods |
| 213 | */ |
| 214 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 215 | static HRESULT WINAPI IDirect3DTexture2Impl_QueryInterface(LPDIRECT3DTEXTURE2 iface, |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 216 | REFIID riid, |
| 217 | LPVOID* ppvObj) |
| 218 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 219 | ICOM_THIS(IDirect3DTexture2Impl,iface); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 220 | char xrefiid[50]; |
| 221 | |
| 222 | WINE_StringFromCLSID((LPCLSID)riid,xrefiid); |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 223 | FIXME(ddraw, "(%p)->(%s,%p): stub\n", This, xrefiid,ppvObj); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 224 | |
| 225 | return S_OK; |
| 226 | } |
| 227 | |
| 228 | |
| 229 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 230 | static ULONG WINAPI IDirect3DTexture2Impl_AddRef(LPDIRECT3DTEXTURE2 iface) |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 231 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 232 | ICOM_THIS(IDirect3DTexture2Impl,iface); |
| 233 | TRACE(ddraw, "(%p)->()incrementing from %lu.\n", This, This->ref ); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 234 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 235 | return ++(This->ref); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 236 | } |
| 237 | |
| 238 | |
| 239 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 240 | static ULONG WINAPI IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface) |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 241 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 242 | ICOM_THIS(IDirect3DTexture2Impl,iface); |
| 243 | FIXME( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref ); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 244 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 245 | if (!--(This->ref)) { |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 246 | /* Delete texture from OpenGL */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 247 | glDeleteTextures(1, &(This->tex_name)); |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 248 | |
| 249 | /* Release surface */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 250 | IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->surface); |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 251 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 252 | HeapFree(GetProcessHeap(),0,This); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 253 | return 0; |
| 254 | } |
| 255 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 256 | return This->ref; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 257 | } |
| 258 | |
| 259 | /*** IDirect3DTexture methods ***/ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 260 | static HRESULT WINAPI IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface, |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 261 | LPDIRECT3DDEVICE lpD3DDevice, |
| 262 | LPD3DTEXTUREHANDLE lpHandle) |
| 263 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 264 | ICOM_THIS(IDirect3DTexture2Impl,iface); |
| 265 | IDirect3DDeviceImpl* ilpD3DDevice=(IDirect3DDeviceImpl*)lpD3DDevice; |
| 266 | FIXME(ddraw, "(%p)->(%p,%p): stub\n", This, ilpD3DDevice, lpHandle); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 267 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 268 | *lpHandle = (D3DTEXTUREHANDLE) This; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 269 | |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 270 | /* Now, bind a new texture */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 271 | ilpD3DDevice->set_context(ilpD3DDevice); |
| 272 | This->D3Ddevice = (void *) ilpD3DDevice; |
| 273 | if (This->tex_name == 0) |
| 274 | glGenTextures(1, &(This->tex_name)); |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 275 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 276 | TRACE(ddraw, "OpenGL texture handle is : %d\n", This->tex_name); |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 277 | |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 278 | return D3D_OK; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 279 | } |
| 280 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 281 | static HRESULT WINAPI IDirect3DTextureImpl_Initialize(LPDIRECT3DTEXTURE iface, |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 282 | LPDIRECT3DDEVICE lpD3DDevice, |
| 283 | LPDIRECTDRAWSURFACE lpSurface) |
| 284 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 285 | ICOM_THIS(IDirect3DTexture2Impl,iface); |
| 286 | TRACE(ddraw, "(%p)->(%p,%p)\n", This, lpD3DDevice, lpSurface); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 287 | |
| 288 | return DDERR_ALREADYINITIALIZED; |
| 289 | } |
| 290 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 291 | static HRESULT WINAPI IDirect3DTextureImpl_Unload(LPDIRECT3DTEXTURE iface) |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 292 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 293 | ICOM_THIS(IDirect3DTexture2Impl,iface); |
| 294 | FIXME(ddraw, "(%p)->(): stub\n", This); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 295 | |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 296 | return D3D_OK; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 297 | } |
| 298 | |
| 299 | /*** IDirect3DTexture2 methods ***/ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 300 | static HRESULT WINAPI IDirect3DTexture2Impl_GetHandle(LPDIRECT3DTEXTURE2 iface, |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 301 | LPDIRECT3DDEVICE2 lpD3DDevice2, |
| 302 | LPD3DTEXTUREHANDLE lpHandle) |
| 303 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 304 | ICOM_THIS(IDirect3DTexture2Impl,iface); |
| 305 | IDirect3DDevice2Impl* ilpD3DDevice2=(IDirect3DDevice2Impl*)lpD3DDevice2; |
| 306 | TRACE(ddraw, "(%p)->(%p,%p)\n", This, ilpD3DDevice2, lpHandle); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 307 | |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 308 | /* For 32 bits OSes, handles = pointers */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 309 | *lpHandle = (D3DTEXTUREHANDLE) This; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 310 | |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 311 | /* Now, bind a new texture */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 312 | ilpD3DDevice2->set_context(ilpD3DDevice2); |
| 313 | This->D3Ddevice = (void *) ilpD3DDevice2; |
| 314 | if (This->tex_name == 0) |
| 315 | glGenTextures(1, &(This->tex_name)); |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 316 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 317 | TRACE(ddraw, "OpenGL texture handle is : %d\n", This->tex_name); |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 318 | |
| 319 | return D3D_OK; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 320 | } |
| 321 | |
| 322 | /* Common methods */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 323 | static HRESULT WINAPI IDirect3DTexture2Impl_PaletteChanged(LPDIRECT3DTEXTURE2 iface, |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 324 | DWORD dwStart, |
| 325 | DWORD dwCount) |
| 326 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 327 | ICOM_THIS(IDirect3DTexture2Impl,iface); |
| 328 | FIXME(ddraw, "(%p)->(%8ld,%8ld): stub\n", This, dwStart, dwCount); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 329 | |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 330 | return D3D_OK; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 331 | } |
| 332 | |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 333 | /* NOTE : if you experience crashes in this function, you must have a buggy |
| 334 | version of Mesa. See the file d3dtexture.c for a cure */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 335 | static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface, |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 336 | LPDIRECT3DTEXTURE2 lpD3DTexture2) |
| 337 | { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 338 | ICOM_THIS(IDirect3DTexture2Impl,iface); |
| 339 | IDirect3DTexture2Impl* ilpD3DTexture2=(IDirect3DTexture2Impl*)lpD3DTexture2; |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 340 | DDSURFACEDESC *src_d, *dst_d; |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 341 | TRACE(ddraw, "(%p)->(%p)\n", This, ilpD3DTexture2); |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 342 | |
Lionel Ulmer | 81c7544 | 1999-04-06 07:10:48 +0000 | [diff] [blame^] | 343 | TRACE(ddraw, "Copied surface %p to surface %p\n", ilpD3DTexture2->surface, This->surface); |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 344 | |
| 345 | /* Suppress the ALLOCONLOAD flag */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 346 | This->surface->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 347 | |
| 348 | /* Copy one surface on the other */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 349 | dst_d = &(This->surface->s.surface_desc); |
| 350 | src_d = &(ilpD3DTexture2->surface->s.surface_desc); |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 351 | |
Lionel Ulmer | 81c7544 | 1999-04-06 07:10:48 +0000 | [diff] [blame^] | 352 | /* Install the callbacks to the destination surface */ |
| 353 | This->surface->s.texture = This; |
| 354 | This->surface->s.SetColorKey_cb = SetColorKey_cb; |
| 355 | |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 356 | if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) { |
| 357 | /* Should also check for same pixel format, lPitch, ... */ |
| 358 | ERR(ddraw, "Error in surface sizes\n"); |
| 359 | return D3DERR_TEXTURE_LOAD_FAILED; |
| 360 | } else { |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 361 | /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */ |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 362 | /* I should put a macro for the calculus of bpp */ |
| 363 | int bpp = (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? |
| 364 | 1 /* 8 bit of palette index */: |
| 365 | src_d->ddpfPixelFormat.x.dwRGBBitCount / 8 /* RGB bits for each colors */ ); |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 366 | GLuint current_texture; |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 367 | |
Lionel Ulmer | 81c7544 | 1999-04-06 07:10:48 +0000 | [diff] [blame^] | 368 | /* Copy the main memry texture into the surface that corresponds to the OpenGL |
| 369 | texture object. */ |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 370 | memcpy(dst_d->y.lpSurface, src_d->y.lpSurface, src_d->dwWidth * src_d->dwHeight * bpp); |
| 371 | |
| 372 | /* Now, load the texture */ |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 373 | /* d3dd->set_context(d3dd); We need to set the context somehow.... */ |
| 374 | glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 375 | |
| 376 | /* If the GetHandle was not done, get the texture name here */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 377 | if (This->tex_name == 0) |
| 378 | glGenTextures(1, &(This->tex_name)); |
| 379 | glBindTexture(GL_TEXTURE_2D, This->tex_name); |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 380 | |
| 381 | if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 382 | /* **************** |
| 383 | Paletted Texture |
| 384 | **************** */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 385 | IDirectDrawPaletteImpl* pal = This->surface->s.palette; |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 386 | BYTE table[256][4]; |
| 387 | int i; |
| 388 | |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 389 | if (pal == NULL) { |
| 390 | ERR(ddraw, "Palettized texture Loading with a NULL palette !\n"); |
| 391 | return D3DERR_TEXTURE_LOAD_FAILED; |
| 392 | } |
| 393 | |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 394 | /* Get the surface's palette */ |
| 395 | for (i = 0; i < 256; i++) { |
| 396 | table[i][0] = pal->palents[i].peRed; |
| 397 | table[i][1] = pal->palents[i].peGreen; |
| 398 | table[i][2] = pal->palents[i].peBlue; |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 399 | if ((This->surface->s.surface_desc.dwFlags & DDSD_CKSRCBLT) && |
| 400 | (i >= This->surface->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) && |
| 401 | (i <= This->surface->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue)) |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 402 | table[i][3] = 0x00; |
| 403 | else |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 404 | table[i][3] = 0xFF; |
| 405 | } |
| 406 | |
Lionel Ulmer | 81c7544 | 1999-04-06 07:10:48 +0000 | [diff] [blame^] | 407 | /* Texture snooping */ |
| 408 | SNOOP_PALETTED(); |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 409 | |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 410 | /* Use Paletted Texture Extension */ |
| 411 | glColorTableEXT(GL_TEXTURE_2D, /* target */ |
| 412 | GL_RGBA, /* internal format */ |
| 413 | 256, /* table size */ |
| 414 | GL_RGBA, /* table format */ |
| 415 | GL_UNSIGNED_BYTE, /* table type */ |
| 416 | table); /* the color table */ |
| 417 | |
| 418 | glTexImage2D(GL_TEXTURE_2D, /* target */ |
| 419 | 0, /* level */ |
| 420 | GL_COLOR_INDEX8_EXT, /* internal format */ |
| 421 | src_d->dwWidth, src_d->dwHeight, /* width, height */ |
| 422 | 0, /* border */ |
| 423 | GL_COLOR_INDEX, /* texture format */ |
| 424 | GL_UNSIGNED_BYTE, /* texture type */ |
| 425 | src_d->y.lpSurface); /* the texture */ |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 426 | } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) { |
| 427 | /* ************ |
| 428 | RGB Textures |
| 429 | ************ */ |
| 430 | if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 8) { |
| 431 | /* ********************** |
| 432 | GL_UNSIGNED_BYTE_3_3_2 |
| 433 | ********************** */ |
| 434 | glTexImage2D(GL_TEXTURE_2D, |
| 435 | 0, |
| 436 | GL_RGB, |
| 437 | src_d->dwWidth, src_d->dwHeight, |
| 438 | 0, |
| 439 | GL_RGB, |
| 440 | GL_UNSIGNED_BYTE_3_3_2, |
| 441 | src_d->y.lpSurface); |
| 442 | } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 16) { |
| 443 | if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000000) { |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 444 | |
Lionel Ulmer | 81c7544 | 1999-04-06 07:10:48 +0000 | [diff] [blame^] | 445 | /* Texture snooping */ |
| 446 | SNOOP_5650(); |
| 447 | |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 448 | glTexImage2D(GL_TEXTURE_2D, |
| 449 | 0, |
| 450 | GL_RGB, |
| 451 | src_d->dwWidth, src_d->dwHeight, |
| 452 | 0, |
| 453 | GL_RGB, |
| 454 | GL_UNSIGNED_SHORT_5_6_5, |
| 455 | src_d->y.lpSurface); |
| 456 | } else if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000001) { |
Lionel Ulmer | 81c7544 | 1999-04-06 07:10:48 +0000 | [diff] [blame^] | 457 | /* Texture snooping */ |
| 458 | SNOOP_5551(); |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 459 | |
| 460 | glTexImage2D(GL_TEXTURE_2D, |
| 461 | 0, |
| 462 | GL_RGBA, |
| 463 | src_d->dwWidth, src_d->dwHeight, |
| 464 | 0, |
| 465 | GL_RGBA, |
| 466 | GL_UNSIGNED_SHORT_5_5_5_1, |
| 467 | src_d->y.lpSurface); |
| 468 | } else if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x0000000F) { |
| 469 | glTexImage2D(GL_TEXTURE_2D, |
| 470 | 0, |
| 471 | GL_RGBA, |
| 472 | src_d->dwWidth, src_d->dwHeight, |
| 473 | 0, |
| 474 | GL_RGBA, |
| 475 | GL_UNSIGNED_SHORT_4_4_4_4, |
| 476 | src_d->y.lpSurface); |
| 477 | } else { |
| 478 | ERR(ddraw, "Unhandled texture format (bad Aplha channel for a 16 bit texture)\n"); |
| 479 | } |
| 480 | } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 24) { |
| 481 | glTexImage2D(GL_TEXTURE_2D, |
| 482 | 0, |
| 483 | GL_RGB, |
| 484 | src_d->dwWidth, src_d->dwHeight, |
| 485 | 0, |
| 486 | GL_RGB, |
| 487 | GL_UNSIGNED_BYTE, |
| 488 | src_d->y.lpSurface); |
| 489 | } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 32) { |
| 490 | glTexImage2D(GL_TEXTURE_2D, |
| 491 | 0, |
| 492 | GL_RGBA, |
| 493 | src_d->dwWidth, src_d->dwHeight, |
| 494 | 0, |
| 495 | GL_RGBA, |
| 496 | GL_UNSIGNED_BYTE, |
| 497 | src_d->y.lpSurface); |
| 498 | } else { |
| 499 | ERR(ddraw, "Unhandled texture format (bad RGB count)\n"); |
| 500 | } |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 501 | } else { |
Lionel Ulmer | 1d3e501 | 1999-01-23 12:32:46 +0000 | [diff] [blame] | 502 | ERR(ddraw, "Unhandled texture format (neither RGB nor INDEX)\n"); |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 503 | } |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 504 | |
| 505 | glBindTexture(GL_TEXTURE_2D, current_texture); |
Alexandre Julliard | 638f169 | 1999-01-17 16:32:32 +0000 | [diff] [blame] | 506 | } |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 507 | |
Alexandre Julliard | 8da12c4 | 1999-01-17 16:55:11 +0000 | [diff] [blame] | 508 | return D3D_OK; |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 509 | } |
| 510 | |
| 511 | |
| 512 | /******************************************************************************* |
| 513 | * IDirect3DTexture2 VTable |
| 514 | */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 515 | static ICOM_VTABLE(IDirect3DTexture2) texture2_vtable = { |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 516 | /*** IUnknown methods ***/ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 517 | IDirect3DTexture2Impl_QueryInterface, |
| 518 | IDirect3DTexture2Impl_AddRef, |
| 519 | IDirect3DTexture2Impl_Release, |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 520 | /*** IDirect3DTexture methods ***/ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 521 | IDirect3DTexture2Impl_GetHandle, |
| 522 | IDirect3DTexture2Impl_PaletteChanged, |
| 523 | IDirect3DTexture2Impl_Load |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 524 | }; |
| 525 | |
| 526 | /******************************************************************************* |
| 527 | * IDirect3DTexture VTable |
| 528 | */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 529 | static ICOM_VTABLE(IDirect3DTexture) texture_vtable = { |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 530 | /*** IUnknown methods ***/ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 531 | IDirect3DTexture2Impl_QueryInterface, |
| 532 | IDirect3DTexture2Impl_AddRef, |
| 533 | IDirect3DTexture2Impl_Release, |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 534 | /*** IDirect3DTexture methods ***/ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 535 | IDirect3DTextureImpl_Initialize, |
| 536 | IDirect3DTextureImpl_GetHandle, |
| 537 | IDirect3DTexture2Impl_PaletteChanged, |
| 538 | IDirect3DTexture2Impl_Load, |
| 539 | IDirect3DTextureImpl_Unload |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 540 | }; |
| 541 | |
| 542 | #else /* HAVE_MESAGL */ |
| 543 | |
| 544 | /* These function should never be called if MesaGL is not present */ |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 545 | LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurface4Impl* surf) { |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 546 | ERR(ddraw, "Should not be called...\n"); |
| 547 | return NULL; |
| 548 | } |
| 549 | |
Francois Gouget | 022d372 | 1999-03-27 16:56:13 +0000 | [diff] [blame] | 550 | LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurface4Impl* surf) { |
Lionel Ulmer | 5ff0077 | 1999-01-03 17:00:19 +0000 | [diff] [blame] | 551 | ERR(ddraw, "Should not be called...\n"); |
| 552 | return NULL; |
| 553 | } |
| 554 | |
| 555 | #endif /* HAVE_MESAGL */ |