4 This files contains the implementation of interface Direct3DTexture2. */
11 #include "wine/obj_base.h"
15 #include "debugtools.h"
17 #include "mesa_private.h"
19 #define D3DDPRIVATE(x) mesa_d3dd_private*odev=(mesa_d3dd_private*)(x)->private
20 #define D3DTPRIVATE(x) mesa_d3dt_private*dtpriv=(mesa_d3dt_private*)(x)->private
22 DEFAULT_DEBUG_CHANNEL(ddraw
)
24 /* Define this if you want to save to a file all the textures used by a game
25 (can be funny to see how they managed to cram all the pictures in
32 #define SNOOP_PALETTED() \
38 sprintf(buf, "%ld.pnm", dtpriv->tex_name); \
39 f = fopen(buf, "wb"); \
40 fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \
41 for (y = 0; y < src_d->dwHeight; y++) { \
42 for (x = 0; x < src_d->dwWidth; x++) { \
43 unsigned char c = ((unsigned char *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \
44 fputc(table[c][0], f); \
45 fputc(table[c][1], f); \
46 fputc(table[c][2], f); \
52 #define SNOOP_5650() \
58 sprintf(buf, "%ld.pnm", dtpriv->tex_name); \
59 f = fopen(buf, "wb"); \
60 fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \
61 for (y = 0; y < src_d->dwHeight; y++) { \
62 for (x = 0; x < src_d->dwWidth; x++) { \
63 unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \
64 fputc((c & 0xF800) >> 8, f); \
65 fputc((c & 0x07E0) >> 3, f); \
66 fputc((c & 0x001F) << 3, f); \
72 #define SNOOP_5551() \
78 sprintf(buf, "%ld.pnm", dtpriv->tex_name); \
79 f = fopen(buf, "wb"); \
80 fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \
81 for (y = 0; y < src_d->dwHeight; y++) { \
82 for (x = 0; x < src_d->dwWidth; x++) { \
83 unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \
84 fputc((c & 0xF800) >> 8, f); \
85 fputc((c & 0x07C0) >> 3, f); \
86 fputc((c & 0x003E) << 2, f); \
92 #define SNOOP_PALETTED()
97 static ICOM_VTABLE(IDirect3DTexture2
) texture2_vtable
;
98 static ICOM_VTABLE(IDirect3DTexture
) texture_vtable
;
100 /*******************************************************************************
101 * Texture2 Creation functions
103 LPDIRECT3DTEXTURE2
d3dtexture2_create(IDirectDrawSurface4Impl
* surf
)
105 IDirect3DTexture2Impl
* tex
;
107 tex
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirect3DTexture2Impl
));
109 ICOM_VTBL(tex
) = &texture2_vtable
;
112 return (LPDIRECT3DTEXTURE2
)tex
;
115 /*******************************************************************************
116 * Texture Creation functions
118 LPDIRECT3DTEXTURE
d3dtexture_create(IDirectDrawSurface4Impl
* surf
)
120 IDirect3DTexture2Impl
* tex
;
122 tex
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirect3DTexture2Impl
));
124 ICOM_VTBL(tex
) = (ICOM_VTABLE(IDirect3DTexture2
)*)&texture_vtable
;
127 return (LPDIRECT3DTEXTURE
)tex
;
130 /*******************************************************************************
131 * IDirectSurface callback methods
133 HRESULT WINAPI
SetColorKey_cb(IDirect3DTexture2Impl
*texture
, DWORD dwFlags
, LPDDCOLORKEY ckey
)
135 DDSURFACEDESC
*tex_d
;
136 D3DTPRIVATE(texture
);
138 GLuint current_texture
;
140 TRACE("(%p) : colorkey callback\n", texture
);
142 /* Get the texture description */
143 tex_d
= &(texture
->surface
->s
.surface_desc
);
144 bpp
= (tex_d
->ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
?
145 1 /* 8 bit of palette index */:
146 tex_d
->ddpfPixelFormat
.u
.dwRGBBitCount
/ 8 /* RGB bits for each colors */ );
148 /* Now, save the current texture */
150 glGetIntegerv(GL_TEXTURE_BINDING_2D
, ¤t_texture
);
152 /* If the GetHandle was not done yet, it's an error */
153 if (dtpriv
->tex_name
== 0) {
154 ERR("Unloaded texture !\n");
158 glBindTexture(GL_TEXTURE_2D
, dtpriv
->tex_name
);
160 if (tex_d
->ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
) {
161 FIXME("Todo Paletted\n");
162 } else if (tex_d
->ddpfPixelFormat
.dwFlags
& DDPF_RGB
) {
163 if (tex_d
->ddpfPixelFormat
.u
.dwRGBBitCount
== 8) {
164 FIXME("Todo 3_3_2_0\n");
165 } else if (tex_d
->ddpfPixelFormat
.u
.dwRGBBitCount
== 16) {
166 if (tex_d
->ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
== 0x00000000) {
167 /* Now transform the 5_6_5 into a 5_5_5_1 surface to support color keying */
168 unsigned short *dest
= (unsigned short *) HeapAlloc(GetProcessHeap(),
170 tex_d
->dwWidth
* tex_d
->dwHeight
* bpp
);
171 unsigned short *src
= (unsigned short *) tex_d
->u1
.lpSurface
;
174 for (y
= 0; y
< tex_d
->dwHeight
; y
++) {
175 for (x
= 0; x
< tex_d
->dwWidth
; x
++) {
176 unsigned short cpixel
= src
[x
+ y
* tex_d
->dwWidth
];
178 if ((dwFlags
& DDCKEY_SRCBLT
) &&
179 (cpixel
>= ckey
->dwColorSpaceLowValue
) &&
180 (cpixel
<= ckey
->dwColorSpaceHighValue
)) /* No alpha bit => this pixel is transparent */
181 dest
[x
+ y
* tex_d
->dwWidth
] = (cpixel
& ~0x003F) | ((cpixel
& 0x001F) << 1) | 0x0000;
182 else /* Alpha bit is set => this pixel will be seen */
183 dest
[x
+ y
* tex_d
->dwWidth
] = (cpixel
& ~0x003F) | ((cpixel
& 0x001F) << 1) | 0x0001;
187 glTexImage2D(GL_TEXTURE_2D
,
190 tex_d
->dwWidth
, tex_d
->dwHeight
,
193 GL_UNSIGNED_SHORT_5_5_5_1
,
196 /* Frees the temporary surface */
197 HeapFree(GetProcessHeap(),0,dest
);
198 } else if (tex_d
->ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
== 0x00000001) {
199 FIXME("Todo 5_5_5_1\n");
200 } else if (tex_d
->ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
== 0x0000000F) {
201 FIXME("Todo 4_4_4_4\n");
203 ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
205 } else if (tex_d
->ddpfPixelFormat
.u
.dwRGBBitCount
== 24) {
206 FIXME("Todo 8_8_8_0\n");
207 } else if (tex_d
->ddpfPixelFormat
.u
.dwRGBBitCount
== 32) {
208 FIXME("Todo 8_8_8_8\n");
210 ERR("Unhandled texture format (bad RGB count)\n");
213 ERR("Unhandled texture format (neither RGB nor INDEX)\n");
220 /*******************************************************************************
221 * IDirect3DTexture2 methods
224 HRESULT WINAPI
IDirect3DTexture2Impl_QueryInterface(LPDIRECT3DTEXTURE2 iface
,
228 ICOM_THIS(IDirect3DTexture2Impl
,iface
);
230 FIXME("(%p)->(%s,%p): stub\n", This
, debugstr_guid(riid
),ppvObj
);
237 ULONG WINAPI
IDirect3DTexture2Impl_AddRef(LPDIRECT3DTEXTURE2 iface
)
239 ICOM_THIS(IDirect3DTexture2Impl
,iface
);
240 TRACE("(%p)->()incrementing from %lu.\n", This
, This
->ref
);
242 return ++(This
->ref
);
247 ULONG WINAPI
IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface
)
249 ICOM_THIS(IDirect3DTexture2Impl
,iface
);
251 FIXME("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
253 if (!--(This
->ref
)) {
254 /* Delete texture from OpenGL */
256 glDeleteTextures(1, &(dtpriv
->tex_name
));
259 /* Release surface */
260 IDirectDrawSurface4_Release((IDirectDrawSurface4
*)This
->surface
);
262 HeapFree(GetProcessHeap(),0,This
);
269 /*** IDirect3DTexture methods ***/
270 HRESULT WINAPI
IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface
,
271 LPDIRECT3DDEVICE lpD3DDevice
,
272 LPD3DTEXTUREHANDLE lpHandle
)
274 ICOM_THIS(IDirect3DTexture2Impl
,iface
);
276 IDirect3DDeviceImpl
* ilpD3DDevice
=(IDirect3DDeviceImpl
*)lpD3DDevice
;
277 FIXME("(%p)->(%p,%p): stub\n", This
, ilpD3DDevice
, lpHandle
);
279 *lpHandle
= (D3DTEXTUREHANDLE
) This
;
281 /* Now, bind a new texture */
283 ilpD3DDevice
->set_context(ilpD3DDevice
);
284 This
->D3Ddevice
= (void *) ilpD3DDevice
;
285 if (dtpriv
->tex_name
== 0)
286 glGenTextures(1, &(dtpriv
->tex_name
));
289 TRACE("OpenGL texture handle is : %d\n", dtpriv
->tex_name
);
294 HRESULT WINAPI
IDirect3DTextureImpl_Initialize(LPDIRECT3DTEXTURE iface
,
295 LPDIRECT3DDEVICE lpD3DDevice
,
296 LPDIRECTDRAWSURFACE lpSurface
)
298 ICOM_THIS(IDirect3DTexture2Impl
,iface
);
299 TRACE("(%p)->(%p,%p)\n", This
, lpD3DDevice
, lpSurface
);
301 return DDERR_ALREADYINITIALIZED
;
304 HRESULT WINAPI
IDirect3DTextureImpl_Unload(LPDIRECT3DTEXTURE iface
)
306 ICOM_THIS(IDirect3DTexture2Impl
,iface
);
307 FIXME("(%p)->(): stub\n", This
);
312 /*** IDirect3DTexture2 methods ***/
313 HRESULT WINAPI
IDirect3DTexture2Impl_GetHandle(LPDIRECT3DTEXTURE2 iface
,
314 LPDIRECT3DDEVICE2 lpD3DDevice2
,
315 LPD3DTEXTUREHANDLE lpHandle
)
317 ICOM_THIS(IDirect3DTexture2Impl
,iface
);
319 IDirect3DDevice2Impl
* ilpD3DDevice2
=(IDirect3DDevice2Impl
*)lpD3DDevice2
;
320 TRACE("(%p)->(%p,%p)\n", This
, ilpD3DDevice2
, lpHandle
);
322 /* For 32 bits OSes, handles = pointers */
323 *lpHandle
= (D3DTEXTUREHANDLE
) This
;
325 /* Now, bind a new texture */
327 ilpD3DDevice2
->set_context(ilpD3DDevice2
);
328 This
->D3Ddevice
= (void *) ilpD3DDevice2
;
329 if (dtpriv
->tex_name
== 0)
330 glGenTextures(1, &(dtpriv
->tex_name
));
333 TRACE("OpenGL texture handle is : %d\n", dtpriv
->tex_name
);
339 HRESULT WINAPI
IDirect3DTexture2Impl_PaletteChanged(
340 LPDIRECT3DTEXTURE2 iface
, DWORD dwStart
, DWORD dwCount
342 ICOM_THIS(IDirect3DTexture2Impl
,iface
);
343 FIXME("(%p)->(%8ld,%8ld): stub\n", This
, dwStart
, dwCount
);
348 /* NOTE : if you experience crashes in this function, you must have a buggy
349 version of Mesa. See the file d3dtexture.c for a cure */
350 HRESULT WINAPI
IDirect3DTexture2Impl_Load(
351 LPDIRECT3DTEXTURE2 iface
, LPDIRECT3DTEXTURE2 lpD3DTexture2
353 ICOM_THIS(IDirect3DTexture2Impl
,iface
);
355 IDirect3DTexture2Impl
* ilpD3DTexture2
=(IDirect3DTexture2Impl
*)lpD3DTexture2
;
356 DDSURFACEDESC
*src_d
, *dst_d
;
357 TRACE("(%p)->(%p)\n", This
, ilpD3DTexture2
);
359 TRACE("Copied surface %p to surface %p\n", ilpD3DTexture2
->surface
, This
->surface
);
361 /* Suppress the ALLOCONLOAD flag */
362 This
->surface
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_ALLOCONLOAD
;
364 /* Copy one surface on the other */
365 dst_d
= &(This
->surface
->s
.surface_desc
);
366 src_d
= &(ilpD3DTexture2
->surface
->s
.surface_desc
);
368 /* Install the callbacks to the destination surface */
369 This
->surface
->s
.texture
= This
;
370 This
->surface
->s
.SetColorKey_cb
= SetColorKey_cb
;
372 if ((src_d
->dwWidth
!= dst_d
->dwWidth
) || (src_d
->dwHeight
!= dst_d
->dwHeight
)) {
373 /* Should also check for same pixel format, lPitch, ... */
374 ERR("Error in surface sizes\n");
375 return D3DERR_TEXTURE_LOAD_FAILED
;
377 /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
378 /* I should put a macro for the calculus of bpp */
379 int bpp
= (src_d
->ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
?
380 1 /* 8 bit of palette index */:
381 src_d
->ddpfPixelFormat
.u
.dwRGBBitCount
/ 8 /* RGB bits for each colors */ );
382 GLuint current_texture
;
384 /* Copy the main memry texture into the surface that corresponds to the OpenGL
386 memcpy(dst_d
->u1
.lpSurface
, src_d
->u1
.lpSurface
, src_d
->dwWidth
* src_d
->dwHeight
* bpp
);
390 /* Now, load the texture */
391 /* d3dd->set_context(d3dd); We need to set the context somehow.... */
392 glGetIntegerv(GL_TEXTURE_BINDING_2D
, ¤t_texture
);
394 /* If the GetHandle was not done, get the texture name here */
395 if (dtpriv
->tex_name
== 0)
396 glGenTextures(1, &(dtpriv
->tex_name
));
397 glBindTexture(GL_TEXTURE_2D
, dtpriv
->tex_name
);
399 if (src_d
->ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
) {
403 IDirectDrawPaletteImpl
* pal
= This
->surface
->s
.palette
;
408 ERR("Palettized texture Loading with a NULL palette !\n");
410 return D3DERR_TEXTURE_LOAD_FAILED
;
413 /* Get the surface's palette */
414 for (i
= 0; i
< 256; i
++) {
415 table
[i
][0] = pal
->palents
[i
].peRed
;
416 table
[i
][1] = pal
->palents
[i
].peGreen
;
417 table
[i
][2] = pal
->palents
[i
].peBlue
;
418 if ((This
->surface
->s
.surface_desc
.dwFlags
& DDSD_CKSRCBLT
) &&
419 (i
>= This
->surface
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) &&
420 (i
<= This
->surface
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
426 /* Texture snooping */
429 #if defined(HAVE_GL_COLOR_TABLE) && defined(HAVE_GL_PALETTED_TEXTURE)
430 /* use Paletted Texture Extension */
431 glColorTableEXT(GL_TEXTURE_2D
, /* target */
432 GL_RGBA
, /* internal format */
433 256, /* table size */
434 GL_RGBA
, /* table format */
435 GL_UNSIGNED_BYTE
, /* table type */
436 table
); /* the color table */
438 glTexImage2D(GL_TEXTURE_2D
, /* target */
440 GL_COLOR_INDEX8_EXT
, /* internal format */
441 src_d
->dwWidth
, src_d
->dwHeight
, /* width, height */
443 GL_COLOR_INDEX
, /* texture format */
444 GL_UNSIGNED_BYTE
, /* texture type */
445 src_d
->u1
.lpSurface
); /* the texture */
447 } else if (src_d
->ddpfPixelFormat
.dwFlags
& DDPF_RGB
) {
451 if (src_d
->ddpfPixelFormat
.u
.dwRGBBitCount
== 8) {
452 /* **********************
453 GL_UNSIGNED_BYTE_3_3_2
454 ********************** */
455 glTexImage2D(GL_TEXTURE_2D
,
458 src_d
->dwWidth
, src_d
->dwHeight
,
461 GL_UNSIGNED_BYTE_3_3_2
,
462 src_d
->u1
.lpSurface
);
463 } else if (src_d
->ddpfPixelFormat
.u
.dwRGBBitCount
== 16) {
464 if (src_d
->ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
== 0x00000000) {
466 /* Texture snooping */
469 glTexImage2D(GL_TEXTURE_2D
,
472 src_d
->dwWidth
, src_d
->dwHeight
,
475 GL_UNSIGNED_SHORT_5_6_5
,
476 src_d
->u1
.lpSurface
);
477 } else if (src_d
->ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
== 0x00000001) {
478 /* Texture snooping */
481 glTexImage2D(GL_TEXTURE_2D
,
484 src_d
->dwWidth
, src_d
->dwHeight
,
487 GL_UNSIGNED_SHORT_5_5_5_1
,
488 src_d
->u1
.lpSurface
);
489 } else if (src_d
->ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
== 0x0000000F) {
490 glTexImage2D(GL_TEXTURE_2D
,
493 src_d
->dwWidth
, src_d
->dwHeight
,
496 GL_UNSIGNED_SHORT_4_4_4_4
,
497 src_d
->u1
.lpSurface
);
499 ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
501 } else if (src_d
->ddpfPixelFormat
.u
.dwRGBBitCount
== 24) {
502 glTexImage2D(GL_TEXTURE_2D
,
505 src_d
->dwWidth
, src_d
->dwHeight
,
509 src_d
->u1
.lpSurface
);
510 } else if (src_d
->ddpfPixelFormat
.u
.dwRGBBitCount
== 32) {
511 glTexImage2D(GL_TEXTURE_2D
,
514 src_d
->dwWidth
, src_d
->dwHeight
,
518 src_d
->u1
.lpSurface
);
520 ERR("Unhandled texture format (bad RGB count)\n");
523 ERR("Unhandled texture format (neither RGB nor INDEX)\n");
526 glBindTexture(GL_TEXTURE_2D
, current_texture
);
535 /*******************************************************************************
536 * IDirect3DTexture2 VTable
538 ICOM_VTABLE(IDirect3DTexture2
) mesa_texture2_vtable
=
540 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
541 /*** IUnknown methods ***/
542 IDirect3DTexture2Impl_QueryInterface
,
543 IDirect3DTexture2Impl_AddRef
,
544 IDirect3DTexture2Impl_Release
,
545 /*** IDirect3DTexture methods ***/
546 IDirect3DTexture2Impl_GetHandle
,
547 IDirect3DTexture2Impl_PaletteChanged
,
548 IDirect3DTexture2Impl_Load
551 /*******************************************************************************
552 * IDirect3DTexture VTable
554 ICOM_VTABLE(IDirect3DTexture
) mesa_texture_vtable
=
556 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
557 /*** IUnknown methods ***/
558 IDirect3DTexture2Impl_QueryInterface
,
559 IDirect3DTexture2Impl_AddRef
,
560 IDirect3DTexture2Impl_Release
,
561 /*** IDirect3DTexture methods ***/
562 IDirect3DTextureImpl_Initialize
,
563 IDirect3DTextureImpl_GetHandle
,
564 IDirect3DTexture2Impl_PaletteChanged
,
565 IDirect3DTexture2Impl_Load
,
566 IDirect3DTextureImpl_Unload