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