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