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