2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the implementation of interface Direct3DTexture2.
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.
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.
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
30 #include "wine/debug.h"
32 #include "mesa_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
36 /* Define this if you want to save to a file all the textures used by a game
37 (can be funny to see how they managed to cram all the pictures in
44 static void snoop_texture(IDirectDrawSurfaceImpl *This) {
45 IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
49 sprintf(buf, "tex_%05d.pnm", glThis->tex_name);
51 DDRAW_dump_surface_to_disk(This, f);
56 #define snoop_texture(a)
60 /*******************************************************************************
61 * IDirectSurface callback methods
63 HRESULT WINAPI gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
66 GLuint current_texture;
67 IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) texture->tex_private;
69 TRACE("(%p) : colorkey callback\n", texture);
71 /* Get the texture description */
72 tex_d = (DDSURFACEDESC *)&(texture->surface_desc);
74 /* Now, save the current texture */
76 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
77 if (glThis->tex_name == 0) ERR("Unbound GL texture !!!\n");
78 glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
80 if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
81 FIXME("Todo Paletted\n");
82 } else if (tex_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
83 if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
84 FIXME("Todo 3_3_2_0\n");
85 } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
86 if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
87 /* Now transform the 5_6_5 into a 5_5_5_1 surface to support color keying */
88 unsigned short *dest = (unsigned short *) HeapAlloc(GetProcessHeap(),
90 tex_d->u1.lPitch * tex_d->dwHeight);
91 unsigned short *src = (unsigned short *) tex_d->lpSurface;
94 for (y = 0; y < tex_d->dwHeight; y++) {
95 for (x = 0; x < tex_d->dwWidth; x++) {
96 unsigned short cpixel = src[x + y * tex_d->dwWidth];
98 if ((dwFlags & DDCKEY_SRCBLT) &&
99 (cpixel >= ckey->dwColorSpaceLowValue) &&
100 (cpixel <= ckey->dwColorSpaceHighValue)) /* No alpha bit => this pixel is transparent */
101 dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0000;
102 else /* Alpha bit is set => this pixel will be seen */
103 dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0001;
107 glTexSubImage2D(GL_TEXTURE_2D,
108 glThis->mipmap_level,
110 tex_d->dwWidth, tex_d->dwHeight,
112 GL_UNSIGNED_SHORT_5_5_5_1,
115 /* Frees the temporary surface */
116 HeapFree(GetProcessHeap(),0,dest);
117 } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
118 FIXME("Todo 5_5_5_1\n");
119 } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
120 FIXME("Todo 4_4_4_4\n");
122 ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
124 } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
125 FIXME("Todo 8_8_8_0\n");
126 } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
127 FIXME("Todo 8_8_8_8\n");
129 ERR("Unhandled texture format (bad RGB count)\n");
132 ERR("Unhandled texture format (neither RGB nor INDEX)\n");
134 glBindTexture(GL_TEXTURE_2D, current_texture);
141 gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) {
142 IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
143 GLuint current_texture;
145 static BOOL color_table_queried = FALSE;
147 void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
148 GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
150 DDSURFACEDESC *src_d = (DDSURFACEDESC *)&(This->surface_desc);
152 TRACE(" uploading texture to GL id %d (initial = %d).\n", glThis->tex_name, init_upload);
154 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
155 glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
157 /* Texture snooping for the curious :-) */
160 if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
164 IDirectDrawPaletteImpl* pal = This->palette;
169 if (color_table_queried == FALSE) {
171 ((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
176 ERR("Palettized texture Loading with a NULL palette !\n");
180 /* Get the surface's palette */
181 for (i = 0; i < 256; i++) {
182 table[i][0] = pal->palents[i].peRed;
183 table[i][1] = pal->palents[i].peGreen;
184 table[i][2] = pal->palents[i].peBlue;
185 if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
186 (i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
187 (i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
193 if (ptr_ColorTableEXT != NULL) {
194 /* use Paletted Texture Extension */
195 ptr_ColorTableEXT(GL_TEXTURE_2D, /* target */
196 GL_RGBA, /* internal format */
197 256, /* table size */
198 GL_RGBA, /* table format */
199 GL_UNSIGNED_BYTE, /* table type */
200 table); /* the color table */
202 glTexImage2D(GL_TEXTURE_2D, /* target */
203 glThis->mipmap_level, /* level */
204 GL_COLOR_INDEX8_EXT, /* internal format */
205 src_d->dwWidth, src_d->dwHeight, /* width, height */
207 GL_COLOR_INDEX, /* texture format */
208 GL_UNSIGNED_BYTE, /* texture type */
209 src_d->lpSurface); /* the texture */
211 DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
213 BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
215 for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
217 *dst++ = table[color][0];
218 *dst++ = table[color][1];
219 *dst++ = table[color][2];
220 *dst++ = table[color][3];
224 glTexImage2D(GL_TEXTURE_2D,
225 glThis->mipmap_level,
227 src_d->dwWidth, src_d->dwHeight,
233 glTexSubImage2D(GL_TEXTURE_2D,
234 glThis->mipmap_level,
236 src_d->dwWidth, src_d->dwHeight,
241 HeapFree(GetProcessHeap(), 0, surface);
243 } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
247 if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
248 /* **********************
249 GL_UNSIGNED_BYTE_3_3_2
250 ********************** */
252 glTexImage2D(GL_TEXTURE_2D,
253 glThis->mipmap_level,
255 src_d->dwWidth, src_d->dwHeight,
258 GL_UNSIGNED_BYTE_3_3_2,
261 glTexSubImage2D(GL_TEXTURE_2D,
262 glThis->mipmap_level,
264 src_d->dwWidth, src_d->dwHeight,
266 GL_UNSIGNED_BYTE_3_3_2,
268 } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
269 if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
271 glTexImage2D(GL_TEXTURE_2D,
272 glThis->mipmap_level,
274 src_d->dwWidth, src_d->dwHeight,
277 GL_UNSIGNED_SHORT_5_6_5,
280 glTexSubImage2D(GL_TEXTURE_2D,
281 glThis->mipmap_level,
283 src_d->dwWidth, src_d->dwHeight,
285 GL_UNSIGNED_SHORT_5_6_5,
288 } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
290 glTexImage2D(GL_TEXTURE_2D,
291 glThis->mipmap_level,
293 src_d->dwWidth, src_d->dwHeight,
296 GL_UNSIGNED_SHORT_5_5_5_1,
299 glTexSubImage2D(GL_TEXTURE_2D,
300 glThis->mipmap_level,
302 src_d->dwWidth, src_d->dwHeight,
304 GL_UNSIGNED_SHORT_5_5_5_1,
306 } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
308 glTexImage2D(GL_TEXTURE_2D,
309 glThis->mipmap_level,
311 src_d->dwWidth, src_d->dwHeight,
314 GL_UNSIGNED_SHORT_4_4_4_4,
317 glTexSubImage2D(GL_TEXTURE_2D,
318 glThis->mipmap_level,
320 src_d->dwWidth, src_d->dwHeight,
322 GL_UNSIGNED_SHORT_4_4_4_4,
324 } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000F000) {
325 /* Move the four Alpha bits... */
326 WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
328 WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
330 for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
331 *dst++ = (((*src & 0xFFF0) >> 4) |
332 ((*src & 0x000F) << 12));
337 glTexImage2D(GL_TEXTURE_2D,
338 glThis->mipmap_level,
340 src_d->dwWidth, src_d->dwHeight,
343 GL_UNSIGNED_SHORT_4_4_4_4,
346 glTexSubImage2D(GL_TEXTURE_2D,
347 glThis->mipmap_level,
349 src_d->dwWidth, src_d->dwHeight,
351 GL_UNSIGNED_SHORT_4_4_4_4,
354 HeapFree(GetProcessHeap(), 0, surface);
355 } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
356 /* Converting the 1555 format in 5551 packed */
357 WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
359 WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
361 for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
362 *dst++ = (((*src & 0x8000) >> 15) |
363 ((*src & 0x7FFF) << 1));
368 glTexImage2D(GL_TEXTURE_2D,
369 glThis->mipmap_level,
371 src_d->dwWidth, src_d->dwHeight,
374 GL_UNSIGNED_SHORT_5_5_5_1,
377 glTexSubImage2D(GL_TEXTURE_2D,
378 glThis->mipmap_level,
380 src_d->dwWidth, src_d->dwHeight,
382 GL_UNSIGNED_SHORT_5_5_5_1,
385 HeapFree(GetProcessHeap(), 0, surface);
387 ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
389 } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
391 glTexImage2D(GL_TEXTURE_2D,
392 glThis->mipmap_level,
394 src_d->dwWidth, src_d->dwHeight,
400 glTexSubImage2D(GL_TEXTURE_2D,
401 glThis->mipmap_level,
403 src_d->dwWidth, src_d->dwHeight,
407 } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
409 glTexImage2D(GL_TEXTURE_2D,
410 glThis->mipmap_level,
412 src_d->dwWidth, src_d->dwHeight,
418 glTexSubImage2D(GL_TEXTURE_2D,
419 glThis->mipmap_level,
421 src_d->dwWidth, src_d->dwHeight,
426 ERR("Unhandled texture format (bad RGB count)\n");
429 ERR("Unhandled texture format (neither RGB nor INDEX)\n");
431 glBindTexture(GL_TEXTURE_2D, current_texture);
435 Main_IDirect3DTextureImpl_1_Initialize(LPDIRECT3DTEXTURE iface,
436 LPDIRECT3DDEVICE lpDirect3DDevice,
437 LPDIRECTDRAWSURFACE lpDDSurface)
439 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
440 FIXME("(%p/%p)->(%p,%p) no-op...\n", This, iface, lpDirect3DDevice, lpDDSurface);
445 Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
449 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
450 FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This, iface, dwStart, dwCount);
455 Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface)
457 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
458 FIXME("(%p/%p)->(): stub!\n", This, iface);
463 Main_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
464 LPDIRECT3DDEVICE2 lpDirect3DDevice2,
465 LPD3DTEXTUREHANDLE lpHandle)
467 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
468 FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpDirect3DDevice2, lpHandle);
473 Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
474 LPDIRECT3DTEXTURE2 lpD3DTexture2)
476 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
477 FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2);
482 gltex_final_release(IDirectDrawSurfaceImpl *This)
484 IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
487 TRACE(" deleting texture with GL id %d.\n", glThis->tex_name);
489 /* And delete texture handle */
491 if (glThis->tex_name != 0)
492 glDeleteTextures(1, &(glThis->tex_name));
495 /* And if this texture was the current one, remove it at the device level */
496 if (This->d3ddevice != NULL)
497 if (This->d3ddevice->current_texture[0] == This)
498 This->d3ddevice->current_texture[0] = NULL;
500 /* All this should be part of main surface management not just a hack for texture.. */
501 if (glThis->loaded) {
502 mem_used = This->surface_desc.dwHeight *
503 This->surface_desc.u1.lPitch;
504 This->ddraw_owner->free_memory(This->ddraw_owner, mem_used);
507 glThis->final_release(This);
511 gltex_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
513 IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
515 glThis->lock_update(This, pRect, dwFlags);
519 gltex_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
521 IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
524 gltex_upload_texture(This, glThis->first_unlock);
526 glThis->first_unlock = FALSE;
528 glThis->unlock_update(This, pRect);
532 GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
533 LPDIRECT3DDEVICE2 lpDirect3DDevice2,
534 LPD3DTEXTUREHANDLE lpHandle)
536 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
537 IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
538 IDirect3DDeviceImpl *lpDeviceImpl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, lpDirect3DDevice2);
540 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice2, lpHandle);
542 /* The handle is simply the pointer to the implementation structure */
543 *lpHandle = (D3DTEXTUREHANDLE) This;
545 TRACE(" returning handle %08lx.\n", *lpHandle);
547 /* Now, bind a new texture */
548 This->d3ddevice = lpDeviceImpl;
550 /* Associate the texture with the device and perform the appropriate AddRef/Release */
551 /* FIXME: Is there only one or several textures associated with the device ? */
552 if (lpDeviceImpl->current_texture[0] != NULL)
553 IDirectDrawSurface7_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture[0], IDirectDrawSurface7));
554 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This, IDirectDrawSurface7));
555 lpDeviceImpl->current_texture[0] = This;
557 TRACE("OpenGL texture handle is : %d\n", glThis->tex_name);
563 GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
564 LPDIRECT3DTEXTURE2 lpD3DTexture2)
566 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
567 IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
568 IDirectDrawSurfaceImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpD3DTexture2);
570 DDSURFACEDESC *src_d, *dst_d;
572 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2);
574 if (glThis->loaded == FALSE) {
575 /* Only check memory for not already loaded texture... */
576 mem_used = This->surface_desc.dwHeight *
577 This->surface_desc.u1.lPitch;
578 if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) {
579 TRACE(" out of virtual memory... Warning application.\n");
580 return D3DERR_TEXTURE_LOAD_FAILED;
583 glThis->loaded = TRUE;
585 TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl, This);
587 if ( This->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
588 /* If the surface is not allocated and its location is not yet specified,
589 force it to video memory */
590 if ( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
591 This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
593 /* Suppress the ALLOCONLOAD flag */
594 This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
595 This->palette = lpD3DTextureImpl->palette;
597 /* Copy one surface on the other */
598 dst_d = (DDSURFACEDESC *)&(This->surface_desc);
599 src_d = (DDSURFACEDESC *)&(lpD3DTextureImpl->surface_desc);
601 if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
602 /* Should also check for same pixel format, u1.lPitch, ... */
603 ERR("Error in surface sizes\n");
604 return D3DERR_TEXTURE_LOAD_FAILED;
606 /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
607 /* I should put a macro for the calculus of bpp */
609 /* Copy also the ColorKeying stuff */
610 if (src_d->dwFlags & DDSD_CKSRCBLT) {
611 dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
612 dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
615 /* Copy the main memry texture into the surface that corresponds to the OpenGL
617 memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
619 /* If the GetHandle was not done, it is an error... */
620 if (glThis->tex_name == 0) ERR("Unbound GL texture !!!\n");
624 /* Now, load the texture */
625 /* d3dd->set_context(d3dd); We need to set the context somehow.... */
627 gltex_upload_texture(This, glThis->first_unlock);
628 glThis->first_unlock = FALSE;
637 Thunk_IDirect3DTextureImpl_2_QueryInterface(LPDIRECT3DTEXTURE2 iface,
641 TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
642 return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface),
648 Thunk_IDirect3DTextureImpl_2_AddRef(LPDIRECT3DTEXTURE2 iface)
650 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
651 return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
655 Thunk_IDirect3DTextureImpl_2_Release(LPDIRECT3DTEXTURE2 iface)
657 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
658 return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
662 Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface,
666 TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
667 return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface),
673 Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface)
675 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
676 return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
680 Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface)
682 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
683 return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
687 Thunk_IDirect3DTextureImpl_1_PaletteChanged(LPDIRECT3DTEXTURE iface,
691 TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface, dwStart, dwCount);
692 return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
698 Thunk_IDirect3DTextureImpl_1_GetHandle(LPDIRECT3DTEXTURE iface,
699 LPDIRECT3DDEVICE lpDirect3DDevice,
700 LPD3DTEXTUREHANDLE lpHandle)
702 TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface, lpDirect3DDevice, lpHandle);
703 return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
704 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice),
709 Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface,
710 LPDIRECT3DTEXTURE lpD3DTexture)
712 TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface, lpD3DTexture);
713 return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
714 COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture));
717 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
718 # define XCAST(fun) (typeof(VTABLE_IDirect3DTexture2.fun))
720 # define XCAST(fun) (void*)
723 ICOM_VTABLE(IDirect3DTexture2) VTABLE_IDirect3DTexture2 =
725 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
726 XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_2_QueryInterface,
727 XCAST(AddRef) Thunk_IDirect3DTextureImpl_2_AddRef,
728 XCAST(Release) Thunk_IDirect3DTextureImpl_2_Release,
729 XCAST(GetHandle) GL_IDirect3DTextureImpl_2_1T_GetHandle,
730 XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged,
731 XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load,
734 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
739 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
740 # define XCAST(fun) (typeof(VTABLE_IDirect3DTexture.fun))
742 # define XCAST(fun) (void*)
745 ICOM_VTABLE(IDirect3DTexture) VTABLE_IDirect3DTexture =
747 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
748 XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_1_QueryInterface,
749 XCAST(AddRef) Thunk_IDirect3DTextureImpl_1_AddRef,
750 XCAST(Release) Thunk_IDirect3DTextureImpl_1_Release,
751 XCAST(Initialize) Main_IDirect3DTextureImpl_1_Initialize,
752 XCAST(GetHandle) Thunk_IDirect3DTextureImpl_1_GetHandle,
753 XCAST(PaletteChanged) Thunk_IDirect3DTextureImpl_1_PaletteChanged,
754 XCAST(Load) Thunk_IDirect3DTextureImpl_1_Load,
755 XCAST(Unload) Main_IDirect3DTextureImpl_1_Unload,
758 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
762 HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation,
763 IDirectDrawSurfaceImpl *main, DWORD mipmap_level)
765 IDirect3DTextureGLImpl *private;
767 private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
768 if (private == NULL) return DDERR_OUTOFMEMORY;
770 private->final_release = surf->final_release;
771 private->lock_update = surf->lock_update;
772 private->unlock_update = surf->unlock_update;
773 private->mipmap_level = mipmap_level;
775 /* If at creation, we can optimize stuff and wait the first 'unlock' to upload a valid stuff to OpenGL.
776 Otherwise, it will be uploaded here (and may be invalid). */
777 if (at_creation == TRUE)
778 private->first_unlock = TRUE;
780 private->first_unlock = FALSE;
781 surf->final_release = gltex_final_release;
782 surf->lock_update = gltex_lock_update;
783 surf->unlock_update = gltex_unlock_update;
784 surf->tex_private = private;
785 surf->SetColorKey_cb = gltex_setcolorkey_cb;
787 ICOM_INIT_INTERFACE(surf, IDirect3DTexture, VTABLE_IDirect3DTexture);
788 ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
791 if (mipmap_level == 0) {
792 glGenTextures(1, &(private->tex_name));
793 if (private->tex_name == 0) ERR("Error at creation of OpenGL texture ID !\n");
794 TRACE(" GL texture created for surface %p (private data at %p and GL id %d).\n", surf, private, private->tex_name);
796 private->tex_name = ((IDirect3DTextureGLImpl *) (main->tex_private))->tex_name;
797 TRACE(" GL texture created for surface %p (private data at %p and GL id reusing id %d from surface %p (%p)).\n",
798 surf, private, private->tex_name, main, main->tex_private);
801 if ((at_creation == FALSE) &&
802 ((surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) == 0))
804 gltex_upload_texture(surf, TRUE);