4 This files contains the implementation of interface Direct3DTexture2. */
11 #include "wine/obj_base.h"
18 #include "d3d_private.h"
22 /* Define this if you want to save to a file all the textures used by a game
23 (can be funny to see how they managed to cram all the pictures in
27 static IDirect3DTexture2_VTable texture2_vtable;
28 static IDirect3DTexture_VTable texture_vtable;
30 /*******************************************************************************
31 * Texture2 Creation functions
33 LPDIRECT3DTEXTURE2 d3dtexture2_create(LPDIRECTDRAWSURFACE4 surf)
35 LPDIRECT3DTEXTURE2 mat;
37 mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2));
39 mat->lpvtbl = &texture2_vtable;
45 /*******************************************************************************
46 * Texture Creation functions
48 LPDIRECT3DTEXTURE d3dtexture_create(LPDIRECTDRAWSURFACE4 surf)
50 LPDIRECT3DTEXTURE mat;
52 mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture));
54 mat->lpvtbl = (IDirect3DTexture2_VTable*) &texture_vtable;
61 /*******************************************************************************
62 * IDirect3DTexture2 methods
65 static HRESULT WINAPI IDirect3DTexture2_QueryInterface(LPDIRECT3DTEXTURE2 this,
71 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
72 FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
79 static ULONG WINAPI IDirect3DTexture2_AddRef(LPDIRECT3DTEXTURE2 this)
81 TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
88 static ULONG WINAPI IDirect3DTexture2_Release(LPDIRECT3DTEXTURE2 this)
90 FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
93 /* Delete texture from OpenGL */
94 glDeleteTextures(1, &(this->tex_name));
97 this->surface->lpvtbl->fnRelease(this->surface);
99 HeapFree(GetProcessHeap(),0,this);
106 /*** IDirect3DTexture methods ***/
107 static HRESULT WINAPI IDirect3DTexture_GetHandle(LPDIRECT3DTEXTURE this,
108 LPDIRECT3DDEVICE lpD3DDevice,
109 LPD3DTEXTUREHANDLE lpHandle)
111 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DDevice, lpHandle);
113 *lpHandle = (DWORD) this;
115 /* Now, bind a new texture */
116 lpD3DDevice->set_context(lpD3DDevice);
117 this->D3Ddevice = (void *) lpD3DDevice;
118 if (this->tex_name == 0)
119 glGenTextures(1, &(this->tex_name));
121 TRACE(ddraw, "OpenGL texture handle is : %d\n", this->tex_name);
126 static HRESULT WINAPI IDirect3DTexture_Initialize(LPDIRECT3DTEXTURE this,
127 LPDIRECT3DDEVICE lpD3DDevice,
128 LPDIRECTDRAWSURFACE lpSurface)
130 TRACE(ddraw, "(%p)->(%p,%p)\n", this, lpD3DDevice, lpSurface);
132 return DDERR_ALREADYINITIALIZED;
135 static HRESULT WINAPI IDirect3DTexture_Unload(LPDIRECT3DTEXTURE this)
137 FIXME(ddraw, "(%p)->(): stub\n", this);
142 /*** IDirect3DTexture2 methods ***/
143 static HRESULT WINAPI IDirect3DTexture2_GetHandle(LPDIRECT3DTEXTURE2 this,
144 LPDIRECT3DDEVICE2 lpD3DDevice2,
145 LPD3DTEXTUREHANDLE lpHandle)
147 TRACE(ddraw, "(%p)->(%p,%p)\n", this, lpD3DDevice2, lpHandle);
149 /* For 32 bits OSes, handles = pointers */
150 *lpHandle = (DWORD) this;
152 /* Now, bind a new texture */
153 lpD3DDevice2->set_context(lpD3DDevice2);
154 this->D3Ddevice = (void *) lpD3DDevice2;
155 if (this->tex_name == 0)
156 glGenTextures(1, &(this->tex_name));
158 TRACE(ddraw, "OpenGL texture handle is : %d\n", this->tex_name);
164 static HRESULT WINAPI IDirect3DTexture2_PaletteChanged(LPDIRECT3DTEXTURE2 this,
168 FIXME(ddraw, "(%p)->(%8ld,%8ld): stub\n", this, dwStart, dwCount);
173 /* NOTE : if you experience crashes in this function, you must have a buggy
174 version of Mesa. See the file d3dtexture.c for a cure */
175 static HRESULT WINAPI IDirect3DTexture2_Load(LPDIRECT3DTEXTURE2 this,
176 LPDIRECT3DTEXTURE2 lpD3DTexture2)
178 DDSURFACEDESC *src_d, *dst_d;
179 TRACE(ddraw, "(%p)->(%p)\n", this, lpD3DTexture2);
181 TRACE(ddraw, "Copied to surface %p, surface %p\n", this->surface, lpD3DTexture2->surface);
183 /* Suppress the ALLOCONLOAD flag */
184 this->surface->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
186 /* Copy one surface on the other */
187 dst_d = &(this->surface->s.surface_desc);
188 src_d = &(lpD3DTexture2->surface->s.surface_desc);
190 if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
191 /* Should also check for same pixel format, lPitch, ... */
192 ERR(ddraw, "Error in surface sizes\n");
193 return D3DERR_TEXTURE_LOAD_FAILED;
195 /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) this->D3Ddevice; */
196 /* I should put a macro for the calculus of bpp */
197 int bpp = (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ?
198 1 /* 8 bit of palette index */:
199 src_d->ddpfPixelFormat.x.dwRGBBitCount / 8 /* RGB bits for each colors */ );
200 GLuint current_texture;
202 /* Not sure if this is usefull ! */
203 memcpy(dst_d->y.lpSurface, src_d->y.lpSurface, src_d->dwWidth * src_d->dwHeight * bpp);
205 /* Now, load the texture */
206 /* d3dd->set_context(d3dd); We need to set the context somehow.... */
207 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
209 /* If the GetHandle was not done, get the texture name here */
210 if (this->tex_name == 0)
211 glGenTextures(1, &(this->tex_name));
212 glBindTexture(GL_TEXTURE_2D, this->tex_name);
214 if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
218 LPDIRECTDRAWPALETTE pal = this->surface->s.palette;
223 ERR(ddraw, "Palettized texture Loading with a NULL palette !\n");
224 return D3DERR_TEXTURE_LOAD_FAILED;
227 /* Get the surface's palette */
228 for (i = 0; i < 256; i++) {
229 table[i][0] = pal->palents[i].peRed;
230 table[i][1] = pal->palents[i].peGreen;
231 table[i][2] = pal->palents[i].peBlue;
232 if ((this->surface->s.surface_desc.dwFlags & DDSD_CKSRCBLT) &&
233 (i >= this->surface->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) &&
234 (i <= this->surface->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
246 sprintf(buf, "%d.pnm", this->tex_name);
247 f = fopen(buf, "wb");
248 fprintf(f, "P6\n%d %d\n255\n", src_d->dwWidth, src_d->dwHeight);
249 for (y = 0; y < src_d->dwHeight; y++) {
250 for (x = 0; x < src_d->dwWidth; x++) {
251 unsigned char c = ((unsigned char *) src_d->y.lpSurface)[y * src_d->dwWidth + x];
252 fputc(table[c][0], f);
253 fputc(table[c][1], f);
254 fputc(table[c][2], f);
260 /* Use Paletted Texture Extension */
261 glColorTableEXT(GL_TEXTURE_2D, /* target */
262 GL_RGBA, /* internal format */
263 256, /* table size */
264 GL_RGBA, /* table format */
265 GL_UNSIGNED_BYTE, /* table type */
266 table); /* the color table */
268 glTexImage2D(GL_TEXTURE_2D, /* target */
270 GL_COLOR_INDEX8_EXT, /* internal format */
271 src_d->dwWidth, src_d->dwHeight, /* width, height */
273 GL_COLOR_INDEX, /* texture format */
274 GL_UNSIGNED_BYTE, /* texture type */
275 src_d->y.lpSurface); /* the texture */
276 } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
280 if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 8) {
281 /* **********************
282 GL_UNSIGNED_BYTE_3_3_2
283 ********************** */
284 glTexImage2D(GL_TEXTURE_2D,
287 src_d->dwWidth, src_d->dwHeight,
290 GL_UNSIGNED_BYTE_3_3_2,
292 } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 16) {
293 if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000000) {
300 sprintf(buf, "%d.pnm", this->tex_name);
301 f = fopen(buf, "wb");
302 fprintf(f, "P6\n%d %d\n255\n", src_d->dwWidth, src_d->dwHeight);
303 for (y = 0; y < src_d->dwHeight; y++) {
304 for (x = 0; x < src_d->dwWidth; x++) {
305 unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];
306 fputc((c & 0xF800) >> 8, f);
307 fputc((c & 0x07E0) >> 3, f);
308 fputc((c & 0x001F) << 3, f);
314 glTexImage2D(GL_TEXTURE_2D,
317 src_d->dwWidth, src_d->dwHeight,
320 GL_UNSIGNED_SHORT_5_6_5,
322 } else if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x00000001) {
329 sprintf(buf, "%d.pnm", this->tex_name);
330 f = fopen(buf, "wb");
331 fprintf(f, "P6\n%d %d\n255\n", src_d->dwWidth, src_d->dwHeight);
332 for (y = 0; y < src_d->dwHeight; y++) {
333 for (x = 0; x < src_d->dwWidth; x++) {
334 unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];
335 fputc((c & 0xF800) >> 8, f);
336 fputc((c & 0x07C0) >> 3, f);
337 fputc((c & 0x003E) << 2, f);
344 glTexImage2D(GL_TEXTURE_2D,
347 src_d->dwWidth, src_d->dwHeight,
350 GL_UNSIGNED_SHORT_5_5_5_1,
352 } else if (src_d->ddpfPixelFormat.xy.dwRGBAlphaBitMask == 0x0000000F) {
353 glTexImage2D(GL_TEXTURE_2D,
356 src_d->dwWidth, src_d->dwHeight,
359 GL_UNSIGNED_SHORT_4_4_4_4,
362 ERR(ddraw, "Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
364 } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 24) {
365 glTexImage2D(GL_TEXTURE_2D,
368 src_d->dwWidth, src_d->dwHeight,
373 } else if (src_d->ddpfPixelFormat.x.dwRGBBitCount == 32) {
374 glTexImage2D(GL_TEXTURE_2D,
377 src_d->dwWidth, src_d->dwHeight,
383 ERR(ddraw, "Unhandled texture format (bad RGB count)\n");
386 ERR(ddraw, "Unhandled texture format (neither RGB nor INDEX)\n");
389 glBindTexture(GL_TEXTURE_2D, current_texture);
396 /*******************************************************************************
397 * IDirect3DTexture2 VTable
399 static IDirect3DTexture2_VTable texture2_vtable = {
400 /*** IUnknown methods ***/
401 IDirect3DTexture2_QueryInterface,
402 IDirect3DTexture2_AddRef,
403 IDirect3DTexture2_Release,
404 /*** IDirect3DTexture methods ***/
405 IDirect3DTexture2_GetHandle,
406 IDirect3DTexture2_PaletteChanged,
407 IDirect3DTexture2_Load
410 /*******************************************************************************
411 * IDirect3DTexture VTable
413 static IDirect3DTexture_VTable texture_vtable = {
414 /*** IUnknown methods ***/
415 IDirect3DTexture2_QueryInterface,
416 IDirect3DTexture2_AddRef,
417 IDirect3DTexture2_Release,
418 /*** IDirect3DTexture methods ***/
419 IDirect3DTexture_Initialize,
420 IDirect3DTexture_GetHandle,
421 IDirect3DTexture2_PaletteChanged,
422 IDirect3DTexture2_Load,
423 IDirect3DTexture_Unload
426 #else /* HAVE_MESAGL */
428 /* These function should never be called if MesaGL is not present */
429 LPDIRECT3DTEXTURE2 d3dtexture2_create(LPDIRECTDRAWSURFACE4 surf) {
430 ERR(ddraw, "Should not be called...\n");
434 LPDIRECT3DTEXTURE d3dtexture_create(LPDIRECTDRAWSURFACE4 surf) {
435 ERR(ddraw, "Should not be called...\n");
439 #endif /* HAVE_MESAGL */