1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Utility Toolkit Sources
4 // Copyright (C) 2000-2009 by Denton Woods
5 // Last modified: 01/30/2009
6 //
7 // Filename: src-ILUT/src/ilut_directx9.c
8 //
9 // Description: DirectX 9 functions for textures
10 //
11 //-----------------------------------------------------------------------------
12
13
14 #include "ilut_internal.h"
15 #ifdef ILUT_USE_DIRECTX9
16
17
18 #include <d3d9.h>
19
20 //#include <d3dx9math.h>
21 //#include <d3dx9tex.h>
22 #pragma comment(lib, "d3d9.lib")
23 #pragma comment(lib, "d3dx9.lib")
24
25
26 ILimage* MakeD3D9Compliant(IDirect3DDevice9 *Device, D3DFORMAT *DestFormat);
27 ILenum GetD3D9Compat(ILenum Format);
28 //D3DFORMAT GetD3DFormat(ILenum Format);
29 D3DFORMAT D3DGetDXTCNumDX9(ILenum DXTCFormat);
30 ILenum D3DGetDXTCFormat(D3DFORMAT DXTCNum);
31 ILboolean iD3D9CreateMipmaps(IDirect3DTexture9 *Texture, ILimage *Image);
32 IDirect3DTexture9* iD3DMakeTexture( IDirect3DDevice9 *Device, void *Data, ILuint DLen, ILuint Width, ILuint Height, D3DFORMAT Format, D3DPOOL Pool, ILuint Levels );
33
34
35 #define ILUT_TEXTUREFORMAT_D3D9_COUNT 7
36 ILboolean FormatsDX9Checked = IL_FALSE;
37 ILboolean FormatsDX9supported[ILUT_TEXTUREFORMAT_D3D9_COUNT] =
38 { IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE };
39 D3DFORMAT FormatsDX9[ILUT_TEXTUREFORMAT_D3D9_COUNT] =
40 { D3DFMT_R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_L8, D3DFMT_DXT1, D3DFMT_DXT3, D3DFMT_DXT5, D3DFMT_A16B16G16R16F};
41
42
ilutD3D9Init()43 ILboolean ilutD3D9Init()
44 {
45
46 return IL_TRUE;
47 }
48
49
CheckFormatsDX9(IDirect3DDevice9 * Device)50 void CheckFormatsDX9(IDirect3DDevice9 *Device)
51 {
52 D3DDISPLAYMODE DispMode;
53 HRESULT hr;
54 IDirect3D9 *TestD3D9;
55 ILuint i;
56
57 IDirect3DDevice9_GetDirect3D(Device, (IDirect3D9**)&TestD3D9);
58 IDirect3DDevice9_GetDisplayMode(Device, 0, &DispMode);
59
60 for (i = 0; i < ILUT_TEXTUREFORMAT_D3D9_COUNT; i++) {
61 hr = IDirect3D9_CheckDeviceFormat(TestD3D9, D3DADAPTER_DEFAULT,
62 D3DDEVTYPE_HAL, DispMode.Format, 0, D3DRTYPE_TEXTURE, FormatsDX9[i]);
63 FormatsDX9supported[i] = (ILboolean)SUCCEEDED(hr);
64 }
65
66 IDirect3D9_Release(TestD3D9);
67 FormatsDX9Checked = IL_TRUE;
68
69 return;
70 }
71
72
73 #ifndef _WIN32_WCE
ilutD3D9TexFromFile(IDirect3DDevice9 * Device,ILconst_string FileName,IDirect3DTexture9 ** Texture)74 ILboolean ILAPIENTRY ilutD3D9TexFromFile(IDirect3DDevice9 *Device, ILconst_string FileName, IDirect3DTexture9 **Texture)
75 {
76 iBindImageTemp();
77 if (!ilLoadImage(FileName))
78 return IL_FALSE;
79
80 *Texture = ilutD3D9Texture(Device);
81
82 return IL_TRUE;
83 }
84 #endif//_WIN32_WCE
85
86 #ifndef _WIN32_WCE
ilutD3D9CubeTexFromFile(IDirect3DDevice9 * Device,ILconst_string FileName,IDirect3DCubeTexture9 ** Texture)87 ILboolean ILAPIENTRY ilutD3D9CubeTexFromFile(IDirect3DDevice9 *Device,
88 ILconst_string FileName, IDirect3DCubeTexture9 **Texture)
89 {
90 iBindImageTemp();
91 if (!ilLoadImage(FileName))
92 return IL_FALSE;
93
94 *Texture = ilutD3D9CubeTexture(Device);
95
96 return IL_TRUE;
97 }
98
99 #endif//_WIN32_WCE
ilutD3D9CubeTexFromFileInMemory(IDirect3DDevice9 * Device,void * Lump,ILuint Size,IDirect3DCubeTexture9 ** Texture)100 ILboolean ILAPIENTRY ilutD3D9CubeTexFromFileInMemory(IDirect3DDevice9 *Device,
101 void *Lump, ILuint Size, IDirect3DCubeTexture9 **Texture)
102 {
103 iBindImageTemp();
104 if( !ilLoadL(IL_TYPE_UNKNOWN, Lump, Size) )
105 return IL_FALSE;
106
107 *Texture = ilutD3D9CubeTexture(Device);
108
109 return IL_TRUE;
110 }
111
ilutD3D9CubeTexFromResource(IDirect3DDevice9 * Device,HMODULE SrcModule,ILconst_string SrcResource,IDirect3DCubeTexture9 ** Texture)112 ILboolean ILAPIENTRY ilutD3D9CubeTexFromResource(IDirect3DDevice9 *Device,
113 HMODULE SrcModule, ILconst_string SrcResource, IDirect3DCubeTexture9 **Texture)
114 {
115 HRSRC Resource;
116 ILubyte *Data;
117
118 iBindImageTemp();
119
120 Resource = (HRSRC)LoadResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP));
121 Data = (ILubyte*)LockResource(Resource);
122 if (!ilLoadL(IL_TYPE_UNKNOWN, Data, SizeofResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP))))
123 return IL_FALSE;
124
125 *Texture = ilutD3D9CubeTexture(Device);
126
127 return IL_TRUE;
128 }
129
ilutD3D9CubeTexFromFileHandle(IDirect3DDevice9 * Device,ILHANDLE File,IDirect3DCubeTexture9 ** Texture)130 ILboolean ILAPIENTRY ilutD3D9CubeTexFromFileHandle(IDirect3DDevice9 *Device,
131 ILHANDLE File, IDirect3DCubeTexture9 **Texture)
132 {
133 iBindImageTemp();
134 if( !ilLoadF(IL_TYPE_UNKNOWN, File) )
135 return IL_FALSE;
136
137 *Texture = ilutD3D9CubeTexture(Device);
138
139 return IL_TRUE;
140 }
141
iToD3D9Cube(ILuint cube)142 D3DCUBEMAP_FACES iToD3D9Cube(ILuint cube)
143 {
144 switch (cube)
145 {
146 case IL_CUBEMAP_POSITIVEX:
147 return D3DCUBEMAP_FACE_POSITIVE_X;
148 case IL_CUBEMAP_NEGATIVEX:
149 return D3DCUBEMAP_FACE_NEGATIVE_X;
150 case IL_CUBEMAP_POSITIVEY:
151 return D3DCUBEMAP_FACE_POSITIVE_Y;
152 case IL_CUBEMAP_NEGATIVEY:
153 return D3DCUBEMAP_FACE_NEGATIVE_Y;
154 case IL_CUBEMAP_POSITIVEZ:
155 return D3DCUBEMAP_FACE_POSITIVE_Z;
156 case IL_CUBEMAP_NEGATIVEZ:
157 return D3DCUBEMAP_FACE_NEGATIVE_Z;
158 default:
159 return D3DCUBEMAP_FACE_POSITIVE_X; //???
160 }
161 }
162
ilutD3D9CubeTexture(IDirect3DDevice9 * Device)163 IDirect3DCubeTexture9* ILAPIENTRY ilutD3D9CubeTexture(IDirect3DDevice9 *Device)
164 {
165 IDirect3DCubeTexture9 *Texture;
166 D3DLOCKED_RECT Box;
167 D3DFORMAT Format;
168 ILimage *StartImage;
169 ILimage *Image;
170 int i;
171 Texture=NULL;
172 Image=NULL;
173 ilutCurImage = ilGetCurImage();
174 if (ilutCurImage == NULL) {
175 ilSetError(ILUT_ILLEGAL_OPERATION);
176 return NULL;
177 }
178
179 if (!FormatsDX9Checked)
180 CheckFormatsDX9(Device);
181
182 Image = MakeD3D9Compliant(Device, &Format);
183 if (Image == NULL) {
184 if (Image != ilutCurImage)
185 ilCloseImage(Image);
186 return NULL;
187 }
188
189 StartImage = ilutCurImage;
190 if (FAILED(IDirect3DDevice9_CreateCubeTexture(Device, StartImage->Width,
191 ilutGetInteger(ILUT_D3D_MIPLEVELS),0,Format, (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture, NULL)))
192 return NULL;
193 for (i = 0; i < CUBEMAP_SIDES; i++) {
194 if (ilutCurImage==NULL || ilutCurImage->CubeFlags == 0) {
195 SAFE_RELEASE(Texture)
196 return NULL;
197 }
198 Image = ilutCurImage;
199
200 Image = MakeD3D9Compliant(Device, &Format);
201 if( Image == NULL ) {
202 SAFE_RELEASE(Texture)
203 return NULL;
204 }
205 if( FAILED(IDirect3DCubeTexture9_LockRect(Texture,iToD3D9Cube(Image->CubeFlags), 0, &Box, NULL, /*D3DLOCK_DISCARD*/0))) {
206 SAFE_RELEASE(Texture)
207 return NULL;
208 }
209
210 memcpy(Box.pBits, Image->Data, Image->SizeOfData);
211 if (IDirect3DCubeTexture9_UnlockRect(Texture,iToD3D9Cube(Image->CubeFlags), 0) != D3D_OK) {
212 SAFE_RELEASE(Texture)
213 return IL_FALSE;
214 }
215 ilutCurImage=ilutCurImage->Faces;
216 }
217 ilutCurImage = StartImage;
218
219 // We don't want to have mipmaps for such a large image.
220 //if (Image != ilutCurImage)
221 // ilCloseImage(Image);
222
223 return Texture;
224 }
225
226 #ifndef _WIN32_WCE
ilutD3D9VolTexFromFile(IDirect3DDevice9 * Device,ILconst_string FileName,IDirect3DVolumeTexture9 ** Texture)227 ILboolean ILAPIENTRY ilutD3D9VolTexFromFile(IDirect3DDevice9 *Device, ILconst_string FileName, IDirect3DVolumeTexture9 **Texture) {
228 iBindImageTemp();
229 if (!ilLoadImage(FileName))
230 return IL_FALSE;
231
232 *Texture = ilutD3D9VolumeTexture(Device);
233
234 return IL_TRUE;
235 }
236 #endif//_WIN32_WCE
237
238
ilutD3D9TexFromFileInMemory(IDirect3DDevice9 * Device,void * Lump,ILuint Size,IDirect3DTexture9 ** Texture)239 ILboolean ILAPIENTRY ilutD3D9TexFromFileInMemory(IDirect3DDevice9 *Device, void *Lump, ILuint Size, IDirect3DTexture9 **Texture)
240 {
241 iBindImageTemp();
242 if (!ilLoadL(IL_TYPE_UNKNOWN, Lump, Size))
243 return IL_FALSE;
244
245 *Texture = ilutD3D9Texture(Device);
246
247 return IL_TRUE;
248 }
249
250
ilutD3D9VolTexFromFileInMemory(IDirect3DDevice9 * Device,void * Lump,ILuint Size,IDirect3DVolumeTexture9 ** Texture)251 ILboolean ILAPIENTRY ilutD3D9VolTexFromFileInMemory(IDirect3DDevice9 *Device, void *Lump, ILuint Size, IDirect3DVolumeTexture9 **Texture)
252 {
253 iBindImageTemp();
254 if (!ilLoadL(IL_TYPE_UNKNOWN, Lump, Size))
255 return IL_FALSE;
256
257 *Texture = ilutD3D9VolumeTexture(Device);
258
259 return IL_TRUE;
260 }
261
262
ilutD3D9TexFromResource(IDirect3DDevice9 * Device,HMODULE SrcModule,ILconst_string SrcResource,IDirect3DTexture9 ** Texture)263 ILboolean ILAPIENTRY ilutD3D9TexFromResource(IDirect3DDevice9 *Device, HMODULE SrcModule, ILconst_string SrcResource, IDirect3DTexture9 **Texture)
264 {
265 HRSRC Resource;
266 ILubyte *Data;
267
268 iBindImageTemp();
269
270 Resource = (HRSRC)LoadResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP));
271 Data = (ILubyte*)LockResource(Resource);
272 if (!ilLoadL(IL_TYPE_UNKNOWN, Data, SizeofResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP))))
273 return IL_FALSE;
274
275 *Texture = ilutD3D9Texture(Device);
276
277 return IL_TRUE;
278 }
279
280
ilutD3D9VolTexFromResource(IDirect3DDevice9 * Device,HMODULE SrcModule,ILconst_string SrcResource,IDirect3DVolumeTexture9 ** Texture)281 ILboolean ILAPIENTRY ilutD3D9VolTexFromResource(IDirect3DDevice9 *Device, HMODULE SrcModule, ILconst_string SrcResource, IDirect3DVolumeTexture9 **Texture)
282 {
283 HRSRC Resource;
284 ILubyte *Data;
285
286 iBindImageTemp();
287
288 Resource = (HRSRC)LoadResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP));
289 Data = (ILubyte*)LockResource(Resource);
290 if (!ilLoadL(IL_TYPE_UNKNOWN, Data, SizeofResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP))))
291 return IL_FALSE;
292
293 *Texture = ilutD3D9VolumeTexture(Device);
294
295 return IL_TRUE;
296 }
297
298
ilutD3D9TexFromFileHandle(IDirect3DDevice9 * Device,ILHANDLE File,IDirect3DTexture9 ** Texture)299 ILboolean ILAPIENTRY ilutD3D9TexFromFileHandle(IDirect3DDevice9 *Device, ILHANDLE File, IDirect3DTexture9 **Texture)
300 {
301 iBindImageTemp();
302 if (!ilLoadF(IL_TYPE_UNKNOWN, File))
303 return IL_FALSE;
304
305 *Texture = ilutD3D9Texture(Device);
306
307 return IL_TRUE;
308 }
309
310
ilutD3D9VolTexFromFileHandle(IDirect3DDevice9 * Device,ILHANDLE File,IDirect3DVolumeTexture9 ** Texture)311 ILboolean ILAPIENTRY ilutD3D9VolTexFromFileHandle(IDirect3DDevice9 *Device, ILHANDLE File, IDirect3DVolumeTexture9 **Texture)
312 {
313 iBindImageTemp();
314 if (!ilLoadF(IL_TYPE_UNKNOWN, File))
315 return IL_FALSE;
316
317 *Texture = ilutD3D9VolumeTexture(Device);
318
319 return IL_TRUE;
320 }
321
322
D3DGetDXTCNumDX9(ILenum DXTCFormat)323 D3DFORMAT D3DGetDXTCNumDX9(ILenum DXTCFormat)
324 {
325 switch (DXTCFormat)
326 {
327 case IL_DXT1:
328 return D3DFMT_DXT1;
329 case IL_DXT3:
330 return D3DFMT_DXT3;
331 case IL_DXT5:
332 return D3DFMT_DXT5;
333 }
334
335 return D3DFMT_UNKNOWN;
336 }
337
338
D3DGetDXTCFormat(D3DFORMAT DXTCNum)339 ILenum D3DGetDXTCFormat(D3DFORMAT DXTCNum)
340 {
341 switch (DXTCNum)
342 {
343 case D3DFMT_DXT1:
344 return IL_DXT1;
345 case D3DFMT_DXT3:
346 return IL_DXT3;
347 case D3DFMT_DXT5:
348 return IL_DXT5;
349 }
350
351 return D3DFMT_UNKNOWN;
352 }
353
354
iD3DMakeTexture(IDirect3DDevice9 * Device,void * Data,ILuint DLen,ILuint Width,ILuint Height,D3DFORMAT Format,D3DPOOL Pool,ILuint Levels)355 IDirect3DTexture9* iD3DMakeTexture( IDirect3DDevice9 *Device, void *Data, ILuint DLen, ILuint Width, ILuint Height, D3DFORMAT Format, D3DPOOL Pool, ILuint Levels )
356 {
357 IDirect3DTexture9 *Texture;
358 D3DLOCKED_RECT Rect;
359
360 if (FAILED(IDirect3DDevice9_CreateTexture(Device, Width, Height, Levels,
361 0, Format, Pool, &Texture, NULL)))
362 return NULL;
363 if (FAILED(IDirect3DTexture9_LockRect(Texture, 0, &Rect, NULL, 0)))
364 return NULL;
365 memcpy(Rect.pBits, Data, DLen);
366 IDirect3DTexture9_UnlockRect(Texture, 0);
367
368 return Texture;
369 }
370
ilutD3D9Texture(IDirect3DDevice9 * Device)371 IDirect3DTexture9* ILAPIENTRY ilutD3D9Texture(IDirect3DDevice9 *Device)
372 {
373 IDirect3DTexture9 *Texture;
374 // D3DLOCKED_RECT Rect;
375 D3DFORMAT Format;
376 ILimage *Image;
377 ILenum DXTCFormat;
378 ILuint Size;
379 ILubyte *Buffer;
380
381 Image = ilutCurImage = ilGetCurImage();
382 if (ilutCurImage == NULL) {
383 ilSetError(ILUT_ILLEGAL_OPERATION);
384 return NULL;
385 }
386
387 if (!FormatsDX9Checked)
388 CheckFormatsDX9(Device);
389
390 if (ilutGetBoolean(ILUT_D3D_USE_DXTC) && FormatsDX9supported[3] && FormatsDX9supported[4] && FormatsDX9supported[5]) {
391 if (ilutCurImage->DxtcData != NULL && ilutCurImage->DxtcSize != 0) {
392 ILuint dxtcFormat = ilutGetInteger(ILUT_DXTC_FORMAT);
393 Format = D3DGetDXTCNumDX9(ilutCurImage->DxtcFormat);
394 ilutSetInteger(ILUT_DXTC_FORMAT, ilutCurImage->DxtcFormat);
395
396 Texture = iD3DMakeTexture(Device, ilutCurImage->DxtcData, ilutCurImage->DxtcSize,
397 ilutCurImage->Width, ilutCurImage->Height, Format,
398 (D3DPOOL)(ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT ? D3DPOOL_SYSTEMMEM : ilutGetInteger(ILUT_D3D_POOL)), ilutGetInteger(ILUT_D3D_MIPLEVELS));
399 if (!Texture)
400 return NULL;
401 iD3D9CreateMipmaps(Texture, Image);
402 if (ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT) {
403 IDirect3DTexture9 *SysTex = Texture;
404 // copy texture to device memory
405 if (FAILED(IDirect3DDevice9_CreateTexture(Device, ilutCurImage->Width,
406 ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format,
407 D3DPOOL_DEFAULT, &Texture, NULL))) {
408 IDirect3DTexture9_Release(SysTex);
409 return NULL;
410 }
411 if (FAILED(IDirect3DDevice9_UpdateTexture(Device, (LPDIRECT3DBASETEXTURE9)SysTex, (LPDIRECT3DBASETEXTURE9)Texture))) {
412 IDirect3DTexture9_Release(SysTex);
413 return NULL;
414 }
415 IDirect3DTexture9_Release(SysTex);
416 }
417 ilutSetInteger(ILUT_DXTC_FORMAT, dxtcFormat);
418
419 goto success;
420 }
421
422 if (ilutGetBoolean(ILUT_D3D_GEN_DXTC)) {
423 DXTCFormat = ilutGetInteger(ILUT_DXTC_FORMAT);
424
425 /*
426 Image = MakeD3D9Compliant(Device, &Format);
427 if (Image == NULL) {
428 if (Image != ilutCurImage)
429 ilCloseImage(Image);
430 return NULL;
431 }
432 */
433
434 Size = ilGetDXTCData(NULL, 0, DXTCFormat);
435 if (Size != 0) {
436 Buffer = (ILubyte*)ialloc(Size);
437 if (Buffer == NULL)
438 return NULL;
439 Size = ilGetDXTCData(Buffer, Size, DXTCFormat);
440 if (Size == 0) {
441 ifree(Buffer);
442 return NULL;
443 }
444
445 Format = D3DGetDXTCNumDX9(DXTCFormat);
446 Texture = iD3DMakeTexture(Device, Buffer, Size,
447 ilutCurImage->Width, ilutCurImage->Height, Format,
448 (D3DPOOL)(ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT ? D3DPOOL_SYSTEMMEM : ilutGetInteger(ILUT_D3D_POOL)), ilutGetInteger(ILUT_D3D_MIPLEVELS));
449 if (!Texture)
450 return NULL;
451 iD3D9CreateMipmaps(Texture, Image);
452 if (ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT) {
453 IDirect3DTexture9 *SysTex = Texture;
454
455 if (FAILED(IDirect3DDevice9_CreateTexture(Device, ilutCurImage->Width,
456 ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format,
457 D3DPOOL_DEFAULT, &Texture, NULL))) {
458 IDirect3DTexture9_Release(SysTex);
459 return NULL;
460 }
461 if (FAILED(IDirect3DDevice9_UpdateTexture(Device, (LPDIRECT3DBASETEXTURE9)SysTex, (LPDIRECT3DBASETEXTURE9)Texture))) {
462 IDirect3DTexture9_Release(SysTex);
463 return NULL;
464 }
465 IDirect3DTexture9_Release(SysTex);
466 }
467
468 goto success;
469 }
470 }
471 }
472
473 Image = MakeD3D9Compliant(Device, &Format);
474 if (Image == NULL) {
475 if (Image != ilutCurImage)
476 ilCloseImage(Image);
477 return NULL;
478 }
479
480 Texture = iD3DMakeTexture(Device, Image->Data, Image->SizeOfPlane,
481 Image->Width, Image->Height, Format,
482 (D3DPOOL)(ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT ? D3DPOOL_SYSTEMMEM : ilutGetInteger(ILUT_D3D_POOL)), ilutGetInteger(ILUT_D3D_MIPLEVELS));
483 if (!Texture)
484 return NULL;
485 iD3D9CreateMipmaps(Texture, Image);
486 if (ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT) {
487 IDirect3DTexture9 *SysTex = Texture;
488 // create texture in system memory
489 if (FAILED(IDirect3DDevice9_CreateTexture(Device, Image->Width,
490 Image->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format,
491 (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture, NULL))) {
492 IDirect3DTexture9_Release(SysTex);
493 return NULL;
494 }
495 if (FAILED(IDirect3DDevice9_UpdateTexture(Device, (LPDIRECT3DBASETEXTURE9)SysTex, (LPDIRECT3DBASETEXTURE9)Texture))) {
496 IDirect3DTexture9_Release(SysTex);
497 return NULL;
498 }
499 IDirect3DTexture9_Release(SysTex);
500 }
501 // if (Image != ilutCurImage)
502 // ilCloseImage(Image);
503
504 success:
505
506 if (Image != ilutCurImage)
507 ilCloseImage(Image);
508
509 return Texture;
510 }
511
512
ilutD3D9VolumeTexture(IDirect3DDevice9 * Device)513 IDirect3DVolumeTexture9* ILAPIENTRY ilutD3D9VolumeTexture(IDirect3DDevice9 *Device)
514 {
515 IDirect3DVolumeTexture9 *Texture;
516 D3DLOCKED_BOX Box;
517 D3DFORMAT Format;
518 ILimage *Image;
519
520 ilutCurImage = ilGetCurImage();
521 if (ilutCurImage == NULL) {
522 ilSetError(ILUT_ILLEGAL_OPERATION);
523 return NULL;
524 }
525
526 if (!FormatsDX9Checked)
527 CheckFormatsDX9(Device);
528
529 Image = MakeD3D9Compliant(Device, &Format);
530 if (Image == NULL)
531 return NULL;
532 if (FAILED(IDirect3DDevice9_CreateVolumeTexture(Device, Image->Width, Image->Height,
533 Image->Depth, 1, 0, Format, (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture, NULL)))
534 return NULL;
535 if (FAILED(IDirect3DVolumeTexture9_LockBox(Texture, 0, &Box, NULL, 0)))
536 return NULL;
537
538 memcpy(Box.pBits, Image->Data, Image->SizeOfData);
539 if (!IDirect3DVolumeTexture9_UnlockBox(Texture, 0))
540 return IL_FALSE;
541
542 // We don't want to have mipmaps for such a large image.
543
544 if (Image != ilutCurImage)
545 ilCloseImage(Image);
546
547 return Texture;
548 }
549
550
551
MakeD3D9Compliant(IDirect3DDevice9 * Device,D3DFORMAT * DestFormat)552 ILimage *MakeD3D9Compliant(IDirect3DDevice9 *Device, D3DFORMAT *DestFormat)
553 {
554 ILuint color;
555 ILimage *Converted, *Scaled, *CurImage;
556 ILuint nConversionType, ilutFormat;
557 ILboolean bForceIntegerFormat = ilutGetBoolean(ILUT_FORCE_INTEGER_FORMAT);
558
559 Device;
560 ilutFormat = ilutCurImage->Format;
561 nConversionType = ilutCurImage->Type;
562
563 if (!ilutCurImage)
564 return NULL;
565
566 switch (ilutCurImage->Type)
567 {
568 case IL_UNSIGNED_BYTE:
569 case IL_BYTE:
570 case IL_SHORT:
571 case IL_UNSIGNED_SHORT:
572 case IL_INT:
573 case IL_UNSIGNED_INT:
574 *DestFormat = D3DFMT_A8R8G8B8;
575 nConversionType = IL_UNSIGNED_BYTE;
576 ilutFormat = IL_BGRA;
577 break;
578 case IL_FLOAT:
579 case IL_DOUBLE:
580 case IL_HALF:
581 if (bForceIntegerFormat || (!FormatsDX9supported[6]))
582 {
583 *DestFormat = D3DFMT_A8R8G8B8;
584 nConversionType = IL_UNSIGNED_BYTE;
585 ilutFormat = IL_BGRA;
586 }
587 else
588 {
589 *DestFormat = D3DFMT_A16B16G16R16F;
590 nConversionType = IL_HALF;
591 ilutFormat = IL_RGBA;
592
593 //
594 }
595 break;
596 }
597
598 // Images must be in BGRA format.
599 if (((ilutCurImage->Format != ilutFormat))
600 || (ilutCurImage->Type != nConversionType))
601 {
602 Converted = iConvertImage(ilutCurImage, ilutFormat, nConversionType);
603 if (Converted == NULL)
604 return NULL;
605 }
606 else
607 {
608 Converted = ilutCurImage;
609 }
610
611 // perform alpha key on images if requested
612 color=ilutGetInteger(ILUT_D3D_ALPHA_KEY_COLOR);
613 if((color>=0) && (nConversionType == IL_UNSIGNED_BYTE))
614 {
615 ILubyte *data;
616 ILubyte *maxdata;
617 ILuint t;
618
619 data=(Converted->Data);
620 maxdata=(Converted->Data+Converted->SizeOfData);
621 while(data<maxdata)
622 {
623 t= (data[2]<<16) + (data[1]<<8) + (data[0]) ;
624
625 if((t&0x00ffffff)==(color&0x00ffffff))
626 {
627 data[0]=0;
628 data[1]=0;
629 data[2]=0;
630 data[3]=0;
631 }
632 data+=4;
633 }
634 }
635
636 // Images must have their origin in the upper left.
637 if (Converted->Origin != IL_ORIGIN_UPPER_LEFT)
638 {
639 CurImage = ilutCurImage;
640 ilSetCurImage(Converted);
641 iluFlipImage();
642 ilSetCurImage(CurImage);
643 }
644
645 // Images must have powers-of-2 dimensions.
646 if (ilNextPower2(ilutCurImage->Width) != ilutCurImage->Width ||
647 ilNextPower2(ilutCurImage->Height) != ilutCurImage->Height ||
648 ilNextPower2(ilutCurImage->Depth) != ilutCurImage->Depth) {
649 Scaled = iluScale_(Converted, ilNextPower2(ilutCurImage->Width),
650 ilNextPower2(ilutCurImage->Height), ilNextPower2(ilutCurImage->Depth));
651 if (Converted != ilutCurImage) {
652 ilCloseImage(Converted);
653 }
654 if (Scaled == NULL) {
655 return NULL;
656 }
657 Converted = Scaled;
658 }
659
660 return Converted;
661 }
662
663
iD3D9CreateMipmaps(IDirect3DTexture9 * Texture,ILimage * Image)664 ILboolean iD3D9CreateMipmaps(IDirect3DTexture9 *Texture, ILimage *Image)
665 {
666 D3DLOCKED_RECT Rect;
667 D3DSURFACE_DESC Desc;
668 ILuint NumMips, srcMips, Width, Height, i;
669 ILimage *CurImage, *MipImage, *Temp;
670 ILenum DXTCFormat;
671 ILuint Size;
672 ILubyte *Buffer;
673 ILboolean useDXTC = IL_FALSE;
674
675 NumMips = IDirect3DTexture9_GetLevelCount(Texture);
676 Width = Image->Width;
677 Height = Image->Height;
678
679 if (NumMips == 1)
680 return IL_TRUE;
681
682 CurImage = ilGetCurImage();
683 MipImage = Image;
684 iGetIntegervImage(MipImage, IL_NUM_MIPMAPS, (ILint*) &srcMips);
685 if ( srcMips != NumMips-1) {
686 MipImage = ilCopyImage_(Image);
687 ilSetCurImage(MipImage);
688 if (!iluBuildMipmaps()) {
689 ilCloseImage(MipImage);
690 ilSetCurImage(CurImage);
691 return IL_FALSE;
692 }
693 }
694 // ilSetCurImage(CurImage);
695 Temp = MipImage->Mipmaps;
696
697 if (ilutGetBoolean(ILUT_D3D_USE_DXTC) && FormatsDX9supported[3] && FormatsDX9supported[4] && FormatsDX9supported[5])
698 useDXTC = IL_TRUE;
699
700 // Counts the base texture as 1.
701 for (i = 1; i < NumMips && Temp != NULL; i++) {
702 ilSetCurImage(Temp);
703 if (FAILED(IDirect3DTexture9_LockRect(Texture, i, &Rect, NULL, 0)))
704 return IL_FALSE;
705
706 Width = IL_MAX(1, Width / 2);
707 Height = IL_MAX(1, Height / 2);
708
709 IDirect3DTexture9_GetLevelDesc(Texture, i, &Desc);
710 if (Desc.Width != Width || Desc.Height != Height) {
711 IDirect3DTexture9_UnlockRect(Texture, i);
712 return IL_FALSE;
713 }
714
715 if (useDXTC) {
716 if (Temp->DxtcData != NULL && Temp->DxtcSize != 0) {
717 memcpy(Rect.pBits, Temp->DxtcData, Temp->DxtcSize);
718 } else if (ilutGetBoolean(ILUT_D3D_GEN_DXTC)) {
719 DXTCFormat = ilutGetInteger(ILUT_DXTC_FORMAT);
720
721 Size = ilGetDXTCData(NULL, 0, DXTCFormat);
722 if (Size != 0) {
723 Buffer = (ILubyte*)ialloc(Size);
724 if (Buffer == NULL) {
725 IDirect3DTexture9_UnlockRect(Texture, i);
726 return IL_FALSE;
727 }
728 Size = ilGetDXTCData(Buffer, Size, DXTCFormat);
729 if (Size == 0) {
730 ifree(Buffer);
731 IDirect3DTexture9_UnlockRect(Texture, i);
732 return IL_FALSE;
733 }
734 memcpy(Rect.pBits, Buffer, Size);
735 } else {
736 IDirect3DTexture9_UnlockRect(Texture, i);
737 return IL_FALSE;
738 }
739 } else {
740 IDirect3DTexture9_UnlockRect(Texture, i);
741 return IL_FALSE;
742 }
743 } else
744 memcpy(Rect.pBits, Temp->Data, Temp->SizeOfData);
745
746 IDirect3DTexture9_UnlockRect(Texture, i);
747 Temp = Temp->Mipmaps;
748 }
749
750 if (MipImage != Image)
751 ilCloseImage(MipImage);
752 ilSetCurImage(CurImage);
753
754 return IL_TRUE;
755 }
756
757
758 //
759 // SaveSurfaceToFile.cpp
760 //
761 // Copyright (c) 2001 David Galeano
762 //
763 // Permission to use, copy, modify and distribute this software
764 // is hereby granted, provided that both the copyright notice and
765 // this permission notice appear in all copies of the software,
766 // derivative works or modified versions.
767 //
768 // THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
769 // CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
770 // WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
771 //
772
ilutD3D9LoadSurface(IDirect3DDevice9 * Device,IDirect3DSurface9 * Surface)773 ILAPI ILboolean ILAPIENTRY ilutD3D9LoadSurface(IDirect3DDevice9 *Device, IDirect3DSurface9 *Surface)
774 {
775 HRESULT hr;
776 D3DSURFACE_DESC d3dsd;
777 LPDIRECT3DSURFACE9 SurfaceCopy;
778 D3DLOCKED_RECT d3dLR;
779 ILboolean bHasAlpha;
780 ILubyte *Image, *ImageAux, *Data;
781 ILuint y, x;
782 ILushort dwColor;
783
784 IDirect3DSurface9_GetDesc(Surface, &d3dsd);
785
786 bHasAlpha = (ILboolean)(d3dsd.Format == D3DFMT_A8R8G8B8 || d3dsd.Format == D3DFMT_A1R5G5B5);
787
788 if (bHasAlpha) {
789 if (!ilTexImage(d3dsd.Width, d3dsd.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL)) {
790 return IL_FALSE;
791 }
792 }
793 else {
794 if (!ilTexImage(d3dsd.Width, d3dsd.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) {
795 return IL_FALSE;
796 }
797 }
798
799 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(Device, d3dsd.Width, d3dsd.Height, d3dsd.Format, D3DPOOL_SCRATCH, &SurfaceCopy, NULL);
800 if (FAILED(hr)) {
801 ilSetError(ILUT_ILLEGAL_OPERATION);
802 return IL_FALSE;
803 }
804
805 hr = IDirect3DDevice9_StretchRect(Device, Surface, NULL, SurfaceCopy, NULL, D3DTEXF_NONE);
806 if (FAILED(hr)) {
807 ilSetError(ILUT_ILLEGAL_OPERATION);
808 return IL_FALSE;
809 }
810
811 hr = IDirect3DSurface9_LockRect(SurfaceCopy, &d3dLR, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY);
812 if (FAILED(hr)) {
813 IDirect3DSurface9_Release(SurfaceCopy);
814 ilSetError(ILUT_ILLEGAL_OPERATION);
815 return IL_FALSE;
816 }
817
818 Image = (ILubyte*)d3dLR.pBits;
819 Data = ilutCurImage->Data;
820
821 for (y = 0; y < d3dsd.Height; y++) {
822 if (d3dsd.Format == D3DFMT_X8R8G8B8) {
823 ImageAux = Image;
824 for (x = 0; x < d3dsd.Width; x++) {
825 Data[0] = ImageAux[0];
826 Data[1] = ImageAux[1];
827 Data[2] = ImageAux[2];
828
829 Data += 3;
830 ImageAux += 4;
831 }
832 }
833 else if (d3dsd.Format == D3DFMT_A8R8G8B8) {
834 memcpy(Data, Image, d3dsd.Width * 4);
835 }
836 else if (d3dsd.Format == D3DFMT_R5G6B5) {
837 ImageAux = Image;
838 for (x = 0; x < d3dsd.Width; x++) {
839 dwColor = *((ILushort*)ImageAux);
840
841 Data[0] = (ILubyte)((dwColor&0x001f)<<3);
842 Data[1] = (ILubyte)(((dwColor&0x7e0)>>5)<<2);
843 Data[2] = (ILubyte)(((dwColor&0xf800)>>11)<<3);
844
845 Data += 3;
846 ImageAux += 2;
847 }
848 }
849 else if (d3dsd.Format == D3DFMT_X1R5G5B5) {
850 ImageAux = Image;
851 for (x = 0; x < d3dsd.Width; x++) {
852 dwColor = *((ILushort*)ImageAux);
853
854 Data[0] = (ILubyte)((dwColor&0x001f)<<3);
855 Data[1] = (ILubyte)(((dwColor&0x3e0)>>5)<<3);
856 Data[2] = (ILubyte)(((dwColor&0x7c00)>>10)<<3);
857
858 Data += 3;
859 ImageAux += 2;
860 }
861 }
862 else if (d3dsd.Format == D3DFMT_A1R5G5B5) {
863 ImageAux = Image;
864 for (x = 0; x < d3dsd.Width; x++) {
865 dwColor = *((ILushort*)ImageAux);
866
867 Data[0] = (ILubyte)((dwColor&0x001f)<<3);
868 Data[1] = (ILubyte)(((dwColor&0x3e0)>>5)<<3);
869 Data[2] = (ILubyte)(((dwColor&0x7c00)>>10)<<3);
870 Data[3] = (ILubyte)(((dwColor&0x8000)>>15)*255);
871
872 Data += 4;
873 ImageAux += 2;
874 }
875 }
876
877 Image += d3dLR.Pitch;
878 }
879
880 IDirect3DSurface9_UnlockRect(SurfaceCopy);
881 IDirect3DSurface9_Release(SurfaceCopy);
882
883 return IL_TRUE;
884 }
885
886 #endif//ILUT_USE_DIRECTX9
887