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