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
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 texture
->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
;
149 BOOL upload_done
= FALSE
;
151 GLenum format
= GL_RGBA
, pixel_format
= GL_UNSIGNED_BYTE
; /* This is only to prevent warnings.. */
152 VOID
*surface
= NULL
;
154 DDSURFACEDESC
*src_d
= (DDSURFACEDESC
*)&(This
->surface_desc
);
156 TRACE(" uploading texture to GL id %d (initial = %d).\n", glThis
->tex_name
, init_upload
);
158 glGetIntegerv(GL_TEXTURE_BINDING_2D
, ¤t_texture
);
159 glBindTexture(GL_TEXTURE_2D
, glThis
->tex_name
);
161 /* Texture snooping for the curious :-) */
164 if (src_d
->ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
) {
168 IDirectDrawPaletteImpl
* pal
= This
->palette
;
173 if (color_table_queried
== FALSE
) {
175 ((Mesa_DeviceCapabilities
*) ((x11_dd_private
*) This
->surface
->s
.ddraw
->d
->private)->device_capabilities
)->ptr_ColorTableEXT
;
180 ERR("Palettized texture Loading with a NULL palette !\n");
181 glBindTexture(GL_TEXTURE_2D
, current_texture
);
182 return D3DERR_INVALIDPALETTE
;
184 /* Get the surface's palette */
185 for (i
= 0; i
< 256; i
++) {
186 table
[i
][0] = pal
->palents
[i
].peRed
;
187 table
[i
][1] = pal
->palents
[i
].peGreen
;
188 table
[i
][2] = pal
->palents
[i
].peBlue
;
189 if ((src_d
->dwFlags
& DDSD_CKSRCBLT
) &&
190 (i
>= src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
) &&
191 (i
<= src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
197 if (ptr_ColorTableEXT
!= NULL
) {
198 /* use Paletted Texture Extension */
199 ptr_ColorTableEXT(GL_TEXTURE_2D
, /* target */
200 GL_RGBA
, /* internal format */
201 256, /* table size */
202 GL_RGBA
, /* table format */
203 GL_UNSIGNED_BYTE
, /* table type */
204 table
); /* the color table */
206 glTexImage2D(GL_TEXTURE_2D
, /* target */
207 This
->mipmap_level
, /* level */
208 GL_COLOR_INDEX8_EXT
, /* internal format */
209 src_d
->dwWidth
, src_d
->dwHeight
, /* width, height */
211 GL_COLOR_INDEX
, /* texture format */
212 GL_UNSIGNED_BYTE
, /* texture type */
213 src_d
->lpSurface
); /* the texture */
218 BYTE
*src
= (BYTE
*) src_d
->lpSurface
, *dst
;
220 surface
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, src_d
->dwWidth
* src_d
->dwHeight
* sizeof(DWORD
));
221 dst
= (BYTE
*) surface
;
223 for (i
= 0; i
< src_d
->dwHeight
* src_d
->dwWidth
; i
++) {
225 *dst
++ = table
[color
][0];
226 *dst
++ = table
[color
][1];
227 *dst
++ = table
[color
][2];
228 *dst
++ = table
[color
][3];
232 pixel_format
= GL_UNSIGNED_BYTE
;
234 } else if (src_d
->ddpfPixelFormat
.dwFlags
& DDPF_RGB
) {
238 if (src_d
->ddpfPixelFormat
.u1
.dwRGBBitCount
== 8) {
239 /* **********************
240 GL_UNSIGNED_BYTE_3_3_2
241 ********************** */
243 pixel_format
= GL_UNSIGNED_BYTE_3_3_2
;
244 } else if (src_d
->ddpfPixelFormat
.u1
.dwRGBBitCount
== 16) {
245 if (src_d
->ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
== 0x00000000) {
247 pixel_format
= GL_UNSIGNED_SHORT_5_6_5
;
248 } else if (src_d
->ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
== 0x00000001) {
250 pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
251 } else if (src_d
->ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
== 0x0000000F) {
253 pixel_format
= GL_UNSIGNED_SHORT_4_4_4_4
;
254 } else if (src_d
->ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
== 0x0000F000) {
255 /* Move the four Alpha bits... */
257 WORD
*src
= (WORD
*) src_d
->lpSurface
, *dst
;
259 surface
= (WORD
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, src_d
->dwWidth
* src_d
->dwHeight
* sizeof(WORD
));
262 for (i
= 0; i
< src_d
->dwHeight
* src_d
->dwWidth
; i
++) {
263 *dst
++ = (((*src
& 0xFFF0) >> 4) |
264 ((*src
& 0x000F) << 12));
269 pixel_format
= GL_UNSIGNED_SHORT_4_4_4_4
;
270 } else if (src_d
->ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
== 0x00008000) {
271 /* Converting the 1555 format in 5551 packed */
273 WORD
*src
= (WORD
*) src_d
->lpSurface
, *dst
;
275 surface
= (WORD
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, src_d
->dwWidth
* src_d
->dwHeight
* sizeof(WORD
));
276 dst
= (WORD
*) surface
;
277 for (i
= 0; i
< src_d
->dwHeight
* src_d
->dwWidth
; i
++) {
278 *dst
++ = (((*src
& 0x8000) >> 15) |
279 ((*src
& 0x7FFF) << 1));
284 pixel_format
= GL_UNSIGNED_SHORT_5_5_5_1
;
286 ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
289 } else if (src_d
->ddpfPixelFormat
.u1
.dwRGBBitCount
== 24) {
291 pixel_format
= GL_UNSIGNED_BYTE
;
292 } else if (src_d
->ddpfPixelFormat
.u1
.dwRGBBitCount
== 32) {
294 pixel_format
= GL_UNSIGNED_BYTE
;
296 ERR("Unhandled texture format (bad RGB count)\n");
300 ERR("Unhandled texture format (neither RGB nor INDEX)\n");
304 if ((upload_done
== FALSE
) && (error
== FALSE
)) {
306 glTexImage2D(GL_TEXTURE_2D
,
309 src_d
->dwWidth
, src_d
->dwHeight
,
313 surface
== NULL
? src_d
->lpSurface
: surface
);
315 glTexSubImage2D(GL_TEXTURE_2D
,
318 src_d
->dwWidth
, src_d
->dwHeight
,
321 surface
== NULL
? src_d
->lpSurface
: surface
);
322 if (surface
) HeapFree(GetProcessHeap(), 0, surface
);
325 glBindTexture(GL_TEXTURE_2D
, current_texture
);
330 Main_IDirect3DTextureImpl_1_Initialize(LPDIRECT3DTEXTURE iface
,
331 LPDIRECT3DDEVICE lpDirect3DDevice
,
332 LPDIRECTDRAWSURFACE lpDDSurface
)
334 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
335 FIXME("(%p/%p)->(%p,%p) no-op...\n", This
, iface
, lpDirect3DDevice
, lpDDSurface
);
340 Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface
,
344 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
345 FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This
, iface
, dwStart
, dwCount
);
350 Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface
)
352 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
353 FIXME("(%p/%p)->(): stub!\n", This
, iface
);
358 Main_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface
,
359 LPDIRECT3DDEVICE2 lpDirect3DDevice2
,
360 LPD3DTEXTUREHANDLE lpHandle
)
362 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
363 FIXME("(%p/%p)->(%p,%p): stub!\n", This
, iface
, lpDirect3DDevice2
, lpHandle
);
368 Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface
,
369 LPDIRECT3DTEXTURE2 lpD3DTexture2
)
371 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
372 FIXME("(%p/%p)->(%p): stub!\n", This
, iface
, lpD3DTexture2
);
377 gltex_final_release(IDirectDrawSurfaceImpl
*This
)
379 IDirect3DTextureGLImpl
*glThis
= (IDirect3DTextureGLImpl
*) This
->tex_private
;
382 TRACE(" deleting texture with GL id %d.\n", glThis
->tex_name
);
384 /* And delete texture handle */
386 if (glThis
->tex_name
!= 0)
387 glDeleteTextures(1, &(glThis
->tex_name
));
390 /* And if this texture was the current one, remove it at the device level */
391 if (This
->d3ddevice
!= NULL
)
392 if (This
->d3ddevice
->current_texture
[0] == This
)
393 This
->d3ddevice
->current_texture
[0] = NULL
;
395 /* All this should be part of main surface management not just a hack for texture.. */
396 if (glThis
->loaded
) {
397 mem_used
= This
->surface_desc
.dwHeight
*
398 This
->surface_desc
.u1
.lPitch
;
399 This
->ddraw_owner
->free_memory(This
->ddraw_owner
, mem_used
);
402 glThis
->final_release(This
);
406 gltex_lock_update(IDirectDrawSurfaceImpl
* This
, LPCRECT pRect
, DWORD dwFlags
)
408 IDirect3DTextureGLImpl
*glThis
= (IDirect3DTextureGLImpl
*) This
->tex_private
;
410 glThis
->lock_update(This
, pRect
, dwFlags
);
414 gltex_unlock_update(IDirectDrawSurfaceImpl
* This
, LPCRECT pRect
)
416 IDirect3DTextureGLImpl
*glThis
= (IDirect3DTextureGLImpl
*) This
->tex_private
;
419 gltex_upload_texture(This
, glThis
->first_unlock
);
421 glThis
->first_unlock
= FALSE
;
423 glThis
->unlock_update(This
, pRect
);
427 GL_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface
,
428 LPDIRECT3DDEVICE2 lpDirect3DDevice2
,
429 LPD3DTEXTUREHANDLE lpHandle
)
431 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
432 IDirect3DTextureGLImpl
*glThis
= (IDirect3DTextureGLImpl
*) This
->tex_private
;
433 IDirect3DDeviceImpl
*lpDeviceImpl
= ICOM_OBJECT(IDirect3DDeviceImpl
, IDirect3DDevice2
, lpDirect3DDevice2
);
435 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpDirect3DDevice2
, lpHandle
);
437 /* The handle is simply the pointer to the implementation structure */
438 *lpHandle
= (D3DTEXTUREHANDLE
) This
;
440 TRACE(" returning handle %08lx.\n", *lpHandle
);
442 /* Now, bind a new texture */
443 This
->d3ddevice
= lpDeviceImpl
;
445 /* Associate the texture with the device and perform the appropriate AddRef/Release */
446 /* FIXME: Is there only one or several textures associated with the device ? */
447 if (lpDeviceImpl
->current_texture
[0] != NULL
)
448 IDirectDrawSurface7_Release(ICOM_INTERFACE(lpDeviceImpl
->current_texture
[0], IDirectDrawSurface7
));
449 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This
, IDirectDrawSurface7
));
450 lpDeviceImpl
->current_texture
[0] = This
;
452 TRACE("OpenGL texture handle is : %d\n", glThis
->tex_name
);
458 GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface
,
459 LPDIRECT3DTEXTURE2 lpD3DTexture2
)
461 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
462 IDirect3DTextureGLImpl
*glThis
= (IDirect3DTextureGLImpl
*) This
->tex_private
;
463 IDirectDrawSurfaceImpl
*lpD3DTextureImpl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, lpD3DTexture2
);
465 DDSURFACEDESC
*src_d
, *dst_d
;
466 HRESULT ret_value
= D3D_OK
;
468 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpD3DTexture2
);
470 if (glThis
!= NULL
) {
471 if (glThis
->loaded
== FALSE
) {
472 /* Only check memory for not already loaded texture... */
473 mem_used
= This
->surface_desc
.dwHeight
*
474 This
->surface_desc
.u1
.lPitch
;
475 if (This
->ddraw_owner
->allocate_memory(This
->ddraw_owner
, mem_used
) < 0) {
476 TRACE(" out of virtual memory... Warning application.\n");
477 return D3DERR_TEXTURE_LOAD_FAILED
;
480 glThis
->loaded
= TRUE
;
483 TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl
, This
);
485 if ( This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ALLOCONLOAD
)
486 /* If the surface is not allocated and its location is not yet specified,
487 force it to video memory */
488 if ( !(This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_SYSTEMMEMORY
|DDSCAPS_VIDEOMEMORY
)) )
489 This
->surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
491 /* Suppress the ALLOCONLOAD flag */
492 This
->surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_ALLOCONLOAD
;
493 This
->palette
= lpD3DTextureImpl
->palette
;
495 /* Copy one surface on the other */
496 dst_d
= (DDSURFACEDESC
*)&(This
->surface_desc
);
497 src_d
= (DDSURFACEDESC
*)&(lpD3DTextureImpl
->surface_desc
);
499 if ((src_d
->dwWidth
!= dst_d
->dwWidth
) || (src_d
->dwHeight
!= dst_d
->dwHeight
)) {
500 /* Should also check for same pixel format, u1.lPitch, ... */
501 ERR("Error in surface sizes\n");
502 return D3DERR_TEXTURE_LOAD_FAILED
;
504 /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
505 /* I should put a macro for the calculus of bpp */
507 /* Copy also the ColorKeying stuff */
508 if (src_d
->dwFlags
& DDSD_CKSRCBLT
) {
509 dst_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
= src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
;
510 dst_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
= src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
;
513 /* Copy the main memry texture into the surface that corresponds to the OpenGL
515 memcpy(dst_d
->lpSurface
, src_d
->lpSurface
, src_d
->u1
.lPitch
* src_d
->dwHeight
);
517 if (glThis
!= NULL
) {
518 /* If the GetHandle was not done, it is an error... */
519 if (glThis
->tex_name
== 0) ERR("Unbound GL texture !!!\n");
523 /* Now, load the texture */
524 /* d3dd->set_context(d3dd); We need to set the context somehow.... */
526 ret_value
= gltex_upload_texture(This
, glThis
->first_unlock
);
527 glThis
->first_unlock
= FALSE
;
537 Thunk_IDirect3DTextureImpl_2_QueryInterface(LPDIRECT3DTEXTURE2 iface
,
541 TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface
, debugstr_guid(riid
), obp
);
542 return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, IDirectDrawSurface7
, iface
),
548 Thunk_IDirect3DTextureImpl_2_AddRef(LPDIRECT3DTEXTURE2 iface
)
550 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface
);
551 return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, IDirectDrawSurface7
, iface
));
555 Thunk_IDirect3DTextureImpl_2_Release(LPDIRECT3DTEXTURE2 iface
)
557 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface
);
558 return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, IDirectDrawSurface7
, iface
));
562 Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface
,
566 TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface
, debugstr_guid(riid
), obp
);
567 return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirectDrawSurface7
, iface
),
573 Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface
)
575 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface
);
576 return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirectDrawSurface7
, iface
));
580 Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface
)
582 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface
);
583 return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirectDrawSurface7
, iface
));
587 Thunk_IDirect3DTextureImpl_1_PaletteChanged(LPDIRECT3DTEXTURE iface
,
591 TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface
, dwStart
, dwCount
);
592 return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirect3DTexture2
, iface
),
598 Thunk_IDirect3DTextureImpl_1_GetHandle(LPDIRECT3DTEXTURE iface
,
599 LPDIRECT3DDEVICE lpDirect3DDevice
,
600 LPD3DTEXTUREHANDLE lpHandle
)
602 TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface
, lpDirect3DDevice
, lpHandle
);
603 return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirect3DTexture2
, iface
),
604 COM_INTERFACE_CAST(IDirect3DDeviceImpl
, IDirect3DDevice
, IDirect3DDevice2
, lpDirect3DDevice
),
609 Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface
,
610 LPDIRECT3DTEXTURE lpD3DTexture
)
612 TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface
, lpD3DTexture
);
613 return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirect3DTexture2
, iface
),
614 COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirect3DTexture2
, lpD3DTexture
));
617 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
618 # define XCAST(fun) (typeof(VTABLE_IDirect3DTexture2.fun))
620 # define XCAST(fun) (void*)
623 ICOM_VTABLE(IDirect3DTexture2
) VTABLE_IDirect3DTexture2
=
625 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
626 XCAST(QueryInterface
) Thunk_IDirect3DTextureImpl_2_QueryInterface
,
627 XCAST(AddRef
) Thunk_IDirect3DTextureImpl_2_AddRef
,
628 XCAST(Release
) Thunk_IDirect3DTextureImpl_2_Release
,
629 XCAST(GetHandle
) GL_IDirect3DTextureImpl_2_1T_GetHandle
,
630 XCAST(PaletteChanged
) Main_IDirect3DTextureImpl_2_1T_PaletteChanged
,
631 XCAST(Load
) GL_IDirect3DTextureImpl_2_1T_Load
,
634 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
639 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
640 # define XCAST(fun) (typeof(VTABLE_IDirect3DTexture.fun))
642 # define XCAST(fun) (void*)
645 ICOM_VTABLE(IDirect3DTexture
) VTABLE_IDirect3DTexture
=
647 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
648 XCAST(QueryInterface
) Thunk_IDirect3DTextureImpl_1_QueryInterface
,
649 XCAST(AddRef
) Thunk_IDirect3DTextureImpl_1_AddRef
,
650 XCAST(Release
) Thunk_IDirect3DTextureImpl_1_Release
,
651 XCAST(Initialize
) Main_IDirect3DTextureImpl_1_Initialize
,
652 XCAST(GetHandle
) Thunk_IDirect3DTextureImpl_1_GetHandle
,
653 XCAST(PaletteChanged
) Thunk_IDirect3DTextureImpl_1_PaletteChanged
,
654 XCAST(Load
) Thunk_IDirect3DTextureImpl_1_Load
,
655 XCAST(Unload
) Main_IDirect3DTextureImpl_1_Unload
,
658 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
662 HRESULT
d3dtexture_create(IDirect3DImpl
*d3d
, IDirectDrawSurfaceImpl
*surf
, BOOLEAN at_creation
,
663 IDirectDrawSurfaceImpl
*main
)
665 IDirect3DGLImpl
*gl_d3d
= (IDirect3DGLImpl
*) d3d
;
667 /* First, initialize the texture vtables... */
668 ICOM_INIT_INTERFACE(surf
, IDirect3DTexture
, VTABLE_IDirect3DTexture
);
669 ICOM_INIT_INTERFACE(surf
, IDirect3DTexture2
, VTABLE_IDirect3DTexture2
);
671 /* Only create all the private stuff if we actually have an OpenGL context.. */
672 if (gl_d3d
->current_device
!= NULL
) {
673 IDirect3DTextureGLImpl
*private;
675 private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DTextureGLImpl
));
676 if (private == NULL
) return DDERR_OUTOFMEMORY
;
678 private->final_release
= surf
->final_release
;
679 private->lock_update
= surf
->lock_update
;
680 private->unlock_update
= surf
->unlock_update
;
682 /* If at creation, we can optimize stuff and wait the first 'unlock' to upload a valid stuff to OpenGL.
683 Otherwise, it will be uploaded here (and may be invalid). */
684 if (at_creation
== TRUE
)
685 private->first_unlock
= TRUE
;
687 private->first_unlock
= FALSE
;
688 surf
->final_release
= gltex_final_release
;
689 surf
->lock_update
= gltex_lock_update
;
690 surf
->unlock_update
= gltex_unlock_update
;
691 surf
->tex_private
= private;
692 surf
->aux_setcolorkey_cb
= gltex_setcolorkey_cb
;
695 if (surf
->mipmap_level
== 0) {
696 glGenTextures(1, &(private->tex_name
));
697 if (private->tex_name
== 0) ERR("Error at creation of OpenGL texture ID !\n");
698 TRACE(" GL texture created for surface %p (private data at %p and GL id %d).\n", surf
, private, private->tex_name
);
700 private->tex_name
= ((IDirect3DTextureGLImpl
*) (main
->tex_private
))->tex_name
;
701 TRACE(" GL texture created for surface %p (private data at %p and GL id reusing id %d from surface %p (%p)).\n",
702 surf
, private, private->tex_name
, main
, main
->tex_private
);
705 if ((at_creation
== FALSE
) &&
706 ((surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ALLOCONLOAD
) == 0))
708 gltex_upload_texture(surf
, TRUE
);