Replaced all occurences of SYSMETRICS_xx and sysMetrics[SM_xx] by
[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 "debug.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 #define SNOOP_PALETTED()                                                                        \
30       {                                                                                         \
31         FILE *f;                                                                                \
32         char buf[32];                                                                           \
33         int x, y;                                                                               \
34                                                                                                 \
35         sprintf(buf, "%d.pnm", This->tex_name);                                                 \
36         f = fopen(buf, "wb");                                                                   \
37         fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);                      \
38         for (y = 0; y < src_d->dwHeight; y++) {                                                 \
39           for (x = 0; x < src_d->dwWidth; x++) {                                                \
40             unsigned char c = ((unsigned char *) src_d->y.lpSurface)[y * src_d->dwWidth + x];   \
41             fputc(table[c][0], f);                                                              \
42             fputc(table[c][1], f);                                                              \
43             fputc(table[c][2], f);                                                              \
44           }                                                                                     \
45         }                                                                                       \
46         fclose(f);                                                                              \
47       }
48
49 #define SNOOP_5650()                                                                                    \
50           {                                                                                             \
51             FILE *f;                                                                                    \
52             char buf[32];                                                                               \
53             int x, y;                                                                                   \
54                                                                                                         \
55             sprintf(buf, "%d.pnm", This->tex_name);                                                     \
56             f = fopen(buf, "wb");                                                                       \
57             fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);                          \
58             for (y = 0; y < src_d->dwHeight; y++) {                                                     \
59               for (x = 0; x < src_d->dwWidth; x++) {                                                    \
60                 unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];     \
61                 fputc((c & 0xF800) >> 8, f);                                                            \
62                 fputc((c & 0x07E0) >> 3, f);                                                            \
63                 fputc((c & 0x001F) << 3, f);                                                            \
64               }                                                                                         \
65             }                                                                                           \
66             fclose(f);                                                                                  \
67           }
68
69 #define SNOOP_5551()                                                                                    \
70           {                                                                                             \
71             FILE *f;                                                                                    \
72             char buf[32];                                                                               \
73             int x, y;                                                                                   \
74                                                                                                         \
75             sprintf(buf, "%d.pnm", This->tex_name);                                                     \
76             f = fopen(buf, "wb");                                                                       \
77             fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);                          \
78             for (y = 0; y < src_d->dwHeight; y++) {                                                     \
79               for (x = 0; x < src_d->dwWidth; x++) {                                                    \
80                 unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];     \
81                 fputc((c & 0xF800) >> 8, f);                                                            \
82                 fputc((c & 0x07C0) >> 3, f);                                                            \
83                 fputc((c & 0x003E) << 2, f);                                                            \
84               }                                                                                         \
85             }                                                                                           \
86             fclose(f);                                                                                  \
87           }
88 #else
89 #define SNOOP_PALETTED()
90 #define SNOOP_5650()
91 #define SNOOP_5551()
92 #endif
93
94 static ICOM_VTABLE(IDirect3DTexture2) texture2_vtable;
95 static ICOM_VTABLE(IDirect3DTexture) texture_vtable;
96
97 /*******************************************************************************
98  *                              Texture2 Creation functions
99  */
100 LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurface4Impl* surf)
101 {
102   IDirect3DTexture2Impl* tex;
103   
104   tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl));
105   tex->ref = 1;
106   tex->lpvtbl = &texture2_vtable;
107   tex->surface = surf;
108   
109   return (LPDIRECT3DTEXTURE2)tex;
110 }
111
112 /*******************************************************************************
113  *                              Texture Creation functions
114  */
115 LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurface4Impl* surf)
116 {
117   IDirect3DTexture2Impl* tex;
118   
119   tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl));
120   tex->ref = 1;
121   tex->lpvtbl = (ICOM_VTABLE(IDirect3DTexture2)*)&texture_vtable;
122   tex->surface = surf;
123   
124   return (LPDIRECT3DTEXTURE)tex;
125 }
126
127 /*******************************************************************************
128  *                         IDirectSurface callback methods
129  */
130 HRESULT WINAPI  SetColorKey_cb(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
131 {
132   DDSURFACEDESC *tex_d;
133   int bpp;
134   GLuint current_texture;
135   
136   TRACE(ddraw, "(%p) : colorkey callback\n", texture);
137
138   /* Get the texture description */
139   tex_d = &(texture->surface->s.surface_desc);
140   bpp = (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ?
141          1 /* 8 bit of palette index */:
142          tex_d->ddpfPixelFormat.x.dwRGBBitCount / 8 /* RGB bits for each colors */ );
143   
144   /* Now, save the current texture */
145   ENTER_GL();
146   glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
147
148   /* If the GetHandle was not done yet, it's an error */
149   if (texture->tex_name == 0) {
150     ERR(ddraw, "Unloaded texture !\n");
151     LEAVE_GL();
152     return DD_OK;
153   }
154   glBindTexture(GL_TEXTURE_2D, texture->tex_name);
155
156   if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
157     FIXME(ddraw, "Todo Paletted\n");
158   } else if (tex_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
159     if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 8) {
160       FIXME(ddraw, "Todo 3_3_2_0\n");
161     } else if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 16) {
162       if (tex_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000000) {
163         /* Now transform the 5_6_5 into a 5_5_5_1 surface to support color keying */
164         unsigned short *dest = (unsigned short *) HeapAlloc(GetProcessHeap(),
165                                                             HEAP_ZERO_MEMORY,
166                                                             tex_d->dwWidth * tex_d->dwHeight * bpp);
167         unsigned short *src = (unsigned short *) tex_d->y.lpSurface;
168         int x, y;
169
170         for (y = 0; y < tex_d->dwHeight; y++) {
171           for (x = 0; x < tex_d->dwWidth; x++) {
172             unsigned short cpixel = src[x + y * tex_d->dwWidth];
173             
174             if ((dwFlags & DDCKEY_SRCBLT) &&
175                 (cpixel >= ckey->dwColorSpaceLowValue) &&
176                 (cpixel <= ckey->dwColorSpaceHighValue)) /* No alpha bit => this pixel is transparent */
177               dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0000;
178             else                                         /* Alpha bit is set => this pixel will be seen */
179               dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0001; 
180           }
181         }
182
183         glTexImage2D(GL_TEXTURE_2D,
184                      0,
185                      GL_RGBA,
186                      tex_d->dwWidth, tex_d->dwHeight,
187                      0,
188                      GL_RGBA,
189                      GL_UNSIGNED_SHORT_5_5_5_1,
190                      dest);
191
192         /* Frees the temporary surface */
193         HeapFree(GetProcessHeap(),0,dest);
194       } else if (tex_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000001) {
195         FIXME(ddraw, "Todo 5_5_5_1\n");
196       } else if (tex_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x0000000F) {
197         FIXME(ddraw, "Todo 4_4_4_4\n");
198       } else {
199         ERR(ddraw, "Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
200       }
201     } else if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 24) {
202       FIXME(ddraw, "Todo 8_8_8_0\n");
203     } else if (tex_d->ddpfPixelFormat.x.dwRGBBitCount == 32) {
204       FIXME(ddraw, "Todo 8_8_8_8\n");
205     } else {
206       ERR(ddraw, "Unhandled texture format (bad RGB count)\n");
207     }
208   } else {
209     ERR(ddraw, "Unhandled texture format (neither RGB nor INDEX)\n");
210   }
211   LEAVE_GL();
212
213   return DD_OK;
214 }
215
216 /*******************************************************************************
217  *                              IDirect3DTexture2 methods
218  */
219
220 static HRESULT WINAPI IDirect3DTexture2Impl_QueryInterface(LPDIRECT3DTEXTURE2 iface,
221                                                         REFIID riid,
222                                                         LPVOID* ppvObj)
223 {
224   ICOM_THIS(IDirect3DTexture2Impl,iface);
225   char xrefiid[50];
226   
227   WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
228   FIXME(ddraw, "(%p)->(%s,%p): stub\n", This, xrefiid,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(ddraw, "(%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( ddraw, "(%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(ddraw, "(%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(ddraw, "OpenGL texture handle is : %d\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(ddraw, "(%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(ddraw, "(%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(ddraw, "(%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(ddraw, "OpenGL texture handle is : %d\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(ddraw, "(%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(ddraw, "(%p)->(%p)\n", This, ilpD3DTexture2);
353
354   TRACE(ddraw, "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(ddraw, "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.x.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->y.lpSurface, src_d->y.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(ddraw, "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       /* Use Paletted Texture Extension */
425       glColorTableEXT(GL_TEXTURE_2D,    /* target */
426                       GL_RGBA,          /* internal format */
427                       256,              /* table size */
428                       GL_RGBA,          /* table format */
429                       GL_UNSIGNED_BYTE, /* table type */
430                       table);           /* the color table */
431
432       glTexImage2D(GL_TEXTURE_2D,       /* target */
433                    0,                   /* level */
434                    GL_COLOR_INDEX8_EXT, /* internal format */
435                    src_d->dwWidth, src_d->dwHeight, /* width, height */
436                    0,                   /* border */
437                    GL_COLOR_INDEX,      /* texture format */
438                    GL_UNSIGNED_BYTE,    /* texture type */
439                    src_d->y.lpSurface); /* the texture */
440     } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
441       /* ************
442          RGB Textures
443          ************ */
444       if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 8) {
445         /* **********************
446            GL_UNSIGNED_BYTE_3_3_2 
447            ********************** */
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_BYTE_3_3_2,
455                      src_d->y.lpSurface);
456       } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 16) {
457         if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000000) {
458             
459           /* Texture snooping */
460           SNOOP_5650();
461           
462           glTexImage2D(GL_TEXTURE_2D,
463                        0,
464                        GL_RGB,
465                        src_d->dwWidth, src_d->dwHeight,
466                        0,
467                        GL_RGB,
468                        GL_UNSIGNED_SHORT_5_6_5,
469                        src_d->y.lpSurface);
470         } else if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000001) {
471           /* Texture snooping */
472           SNOOP_5551();
473           
474           glTexImage2D(GL_TEXTURE_2D,
475                        0,
476                        GL_RGBA,
477                        src_d->dwWidth, src_d->dwHeight,
478                        0,
479                        GL_RGBA,
480                        GL_UNSIGNED_SHORT_5_5_5_1,
481                        src_d->y.lpSurface);
482         } else if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x0000000F) {
483           glTexImage2D(GL_TEXTURE_2D,
484                        0,
485                        GL_RGBA,
486                        src_d->dwWidth, src_d->dwHeight,
487                        0,
488                        GL_RGBA,
489                        GL_UNSIGNED_SHORT_4_4_4_4,
490                        src_d->y.lpSurface);
491         } else {
492           ERR(ddraw, "Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
493         }
494       } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 24) {
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,
502                      src_d->y.lpSurface);
503       } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 32) {
504         glTexImage2D(GL_TEXTURE_2D,
505                      0,
506                      GL_RGBA,
507                      src_d->dwWidth, src_d->dwHeight,
508                      0,
509                      GL_RGBA,
510                      GL_UNSIGNED_BYTE,
511                      src_d->y.lpSurface);
512       } else {
513         ERR(ddraw, "Unhandled texture format (bad RGB count)\n");
514       }
515     } else {
516       ERR(ddraw, "Unhandled texture format (neither RGB nor INDEX)\n");
517     }
518
519     glBindTexture(GL_TEXTURE_2D, current_texture);
520
521     LEAVE_GL();
522   }
523   
524   return D3D_OK;
525 }
526
527
528 /*******************************************************************************
529  *                              IDirect3DTexture2 VTable
530  */
531 static ICOM_VTABLE(IDirect3DTexture2) texture2_vtable = {
532   /*** IUnknown methods ***/
533   IDirect3DTexture2Impl_QueryInterface,
534   IDirect3DTexture2Impl_AddRef,
535   IDirect3DTexture2Impl_Release,
536   /*** IDirect3DTexture methods ***/
537   IDirect3DTexture2Impl_GetHandle,
538   IDirect3DTexture2Impl_PaletteChanged,
539   IDirect3DTexture2Impl_Load
540 };
541
542 /*******************************************************************************
543  *                              IDirect3DTexture VTable
544  */
545 static ICOM_VTABLE(IDirect3DTexture) texture_vtable = {
546   /*** IUnknown methods ***/
547   IDirect3DTexture2Impl_QueryInterface,
548   IDirect3DTexture2Impl_AddRef,
549   IDirect3DTexture2Impl_Release,
550   /*** IDirect3DTexture methods ***/
551   IDirect3DTextureImpl_Initialize,
552   IDirect3DTextureImpl_GetHandle,
553   IDirect3DTexture2Impl_PaletteChanged,
554   IDirect3DTexture2Impl_Load,
555   IDirect3DTextureImpl_Unload
556 };
557
558 #else /* HAVE_MESAGL */
559
560 /* These function should never be called if MesaGL is not present */
561 LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurface4Impl* surf) {
562   ERR(ddraw, "Should not be called...\n");
563   return NULL;
564 }
565
566 LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurface4Impl* surf) {
567   ERR(ddraw, "Should not be called...\n");
568   return NULL;
569 }
570
571 #endif /* HAVE_MESAGL */