1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Utility Toolkit Sources
4 // Copyright (C) 2000-2008 by Denton Woods
5 // Last modified: 12/25/2001
6 //
7 // Filename: src-ILUT/src/ilut_directx.c
8 //
9 // Description: DirectX 8 functions for textures
10 //
11 //-----------------------------------------------------------------------------
12
13 #include "ilut_internal.h"
14 #ifdef ILUT_USE_DIRECTX8
15
16 #include <d3d8.h>
17 //#include <d3dx8tex.h>
18 //pragma comment(lib, "d3d8.lib")
19 //pragma comment(lib, "d3dx8.lib")
20
21 ILimage* MakeD3D8Compliant(IDirect3DDevice8 *Device, D3DFORMAT *DestFormat);
22 ILenum GetD3D8Compat(ILenum Format);
23 D3DFORMAT GetD3DFormat(ILenum Format);
24 ILboolean iD3D8CreateMipmaps(IDirect3DTexture8 *Texture, ILimage *Image);
25
26 ILboolean FormatsDX8Checked = IL_FALSE;
27 ILboolean FormatsDX8supported[6] =
28 { IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE };
29 D3DFORMAT FormatsDX8[6] =
30 { D3DFMT_R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_L8, D3DFMT_DXT1, D3DFMT_DXT3, D3DFMT_DXT5 };
31
32
ilutD3D8Init()33 ILboolean ilutD3D8Init()
34 {
35
36 return IL_TRUE;
37 }
38
39
CheckFormatsDX8(IDirect3DDevice8 * Device)40 ILvoid CheckFormatsDX8(IDirect3DDevice8 *Device)
41 {
42 D3DDISPLAYMODE DispMode;
43 HRESULT hr;
44 IDirect3D8 *TestD3D8;
45 ILuint i;
46
47 IDirect3DDevice8_GetDirect3D(Device, (IDirect3D8**)&TestD3D8);
48 IDirect3DDevice8_GetDisplayMode(Device, &DispMode);
49
50 for (i = 0; i < 6; i++) {
51 hr = IDirect3D8_CheckDeviceFormat(TestD3D8, D3DADAPTER_DEFAULT,
52 D3DDEVTYPE_HAL, DispMode.Format, 0, D3DRTYPE_TEXTURE, FormatsDX8[i]);
53 FormatsDX8supported[i] = SUCCEEDED(hr);
54 }
55
56 IDirect3D8_Release(TestD3D8);
57 FormatsDX8Checked = IL_TRUE;
58
59 return;
60 }
61
62
63 #ifndef _WIN32_WCE
ilutD3D8TexFromFile(IDirect3DDevice8 * Device,char * FileName,IDirect3DTexture8 ** Texture)64 ILboolean ILAPIENTRY ilutD3D8TexFromFile(IDirect3DDevice8 *Device, char *FileName, IDirect3DTexture8 **Texture)
65 {
66 iBindImageTemp();
67 if (!ilLoadImage(FileName))
68 return IL_FALSE;
69
70 *Texture = ilutD3D8Texture(Device);
71
72 return IL_TRUE;
73 }
74 #endif//_WIN32_WCE
75
76
77 #ifndef _WIN32_WCE
ilutD3D8VolTexFromFile(IDirect3DDevice8 * Device,char * FileName,IDirect3DVolumeTexture8 ** Texture)78 ILboolean ILAPIENTRY ilutD3D8VolTexFromFile(IDirect3DDevice8 *Device, char *FileName, IDirect3DVolumeTexture8 **Texture)
79 {
80 iBindImageTemp();
81 if (!ilLoadImage(FileName))
82 return IL_FALSE;
83
84 *Texture = ilutD3D8VolumeTexture(Device);
85
86 return IL_TRUE;
87 }
88 #endif//_WIN32_WCE
89
90
ilutD3D8TexFromFileInMemory(IDirect3DDevice8 * Device,ILvoid * Lump,ILuint Size,IDirect3DTexture8 ** Texture)91 ILboolean ILAPIENTRY ilutD3D8TexFromFileInMemory(IDirect3DDevice8 *Device, ILvoid *Lump, ILuint Size, IDirect3DTexture8 **Texture)
92 {
93 iBindImageTemp();
94 if (!ilLoadL(IL_TYPE_UNKNOWN, Lump, Size))
95 return IL_FALSE;
96
97 *Texture = ilutD3D8Texture(Device);
98
99 return IL_TRUE;
100 }
101
102
ilutD3D8VolTexFromFileInMemory(IDirect3DDevice8 * Device,ILvoid * Lump,ILuint Size,IDirect3DVolumeTexture8 ** Texture)103 ILboolean ILAPIENTRY ilutD3D8VolTexFromFileInMemory(IDirect3DDevice8 *Device, ILvoid *Lump, ILuint Size, IDirect3DVolumeTexture8 **Texture)
104 {
105 iBindImageTemp();
106 if (!ilLoadL(IL_TYPE_UNKNOWN, Lump, Size))
107 return IL_FALSE;
108
109 *Texture = ilutD3D8VolumeTexture(Device);
110
111 return IL_TRUE;
112 }
113
114
ilutD3D8TexFromResource(IDirect3DDevice8 * Device,HMODULE SrcModule,char * SrcResource,IDirect3DTexture8 ** Texture)115 ILboolean ILAPIENTRY ilutD3D8TexFromResource(IDirect3DDevice8 *Device, HMODULE SrcModule, char *SrcResource, IDirect3DTexture8 **Texture)
116 {
117 HRSRC Resource;
118 ILubyte *Data;
119
120 iBindImageTemp();
121
122 Resource = (HRSRC)LoadResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP));
123 Data = (ILubyte*)LockResource(Resource);
124 if (!ilLoadL(IL_TYPE_UNKNOWN, Data, SizeofResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP))))
125 return IL_FALSE;
126
127 *Texture = ilutD3D8Texture(Device);
128
129 return IL_TRUE;
130 }
131
132
ilutD3D8VolTexFromResource(IDirect3DDevice8 * Device,HMODULE SrcModule,char * SrcResource,IDirect3DVolumeTexture8 ** Texture)133 ILboolean ILAPIENTRY ilutD3D8VolTexFromResource(IDirect3DDevice8 *Device, HMODULE SrcModule, char *SrcResource, IDirect3DVolumeTexture8 **Texture)
134 {
135 HRSRC Resource;
136 ILubyte *Data;
137
138 iBindImageTemp();
139
140 Resource = (HRSRC)LoadResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP));
141 Data = (ILubyte*)LockResource(Resource);
142 if (!ilLoadL(IL_TYPE_UNKNOWN, Data, SizeofResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP))))
143 return IL_FALSE;
144
145 *Texture = ilutD3D8VolumeTexture(Device);
146
147 return IL_TRUE;
148 }
149
150
ilutD3D8TexFromFileHandle(IDirect3DDevice8 * Device,ILHANDLE File,IDirect3DTexture8 ** Texture)151 ILboolean ILAPIENTRY ilutD3D8TexFromFileHandle(IDirect3DDevice8 *Device, ILHANDLE File, IDirect3DTexture8 **Texture)
152 {
153 iBindImageTemp();
154 if (!ilLoadF(IL_TYPE_UNKNOWN, File))
155 return IL_FALSE;
156
157 *Texture = ilutD3D8Texture(Device);
158
159 return IL_TRUE;
160 }
161
162
ilutD3D8VolTexFromFileHandle(IDirect3DDevice8 * Device,ILHANDLE File,IDirect3DVolumeTexture8 ** Texture)163 ILboolean ILAPIENTRY ilutD3D8VolTexFromFileHandle(IDirect3DDevice8 *Device, ILHANDLE File, IDirect3DVolumeTexture8 **Texture)
164 {
165 iBindImageTemp();
166 if (!ilLoadF(IL_TYPE_UNKNOWN, File))
167 return IL_FALSE;
168
169 *Texture = ilutD3D8VolumeTexture(Device);
170
171 return IL_TRUE;
172 }
173
174
D3DGetDXTCNumDX8(ILenum DXTCFormat)175 D3DFORMAT D3DGetDXTCNumDX8(ILenum DXTCFormat)
176 {
177 switch (DXTCFormat)
178 {
179 case IL_DXT1:
180 return D3DFMT_DXT1;
181 case IL_DXT3:
182 return D3DFMT_DXT3;
183 case IL_DXT5:
184 return D3DFMT_DXT5;
185 }
186
187 return D3DFMT_UNKNOWN;
188 }
189
190
ilutD3D8Texture(IDirect3DDevice8 * Device)191 IDirect3DTexture8* ILAPIENTRY ilutD3D8Texture(IDirect3DDevice8 *Device)
192 {
193 IDirect3DTexture8 *Texture;
194 D3DLOCKED_RECT Rect;
195 D3DFORMAT Format;
196 ILimage *Image;
197 ILenum DXTCFormat;
198 ILuint Size;
199 ILubyte *Buffer;
200
201 Image = ilutCurImage = ilGetCurImage();
202 if (ilutCurImage == NULL) {
203 ilSetError(ILUT_ILLEGAL_OPERATION);
204 return NULL;
205 }
206
207 if (!FormatsDX8Checked)
208 CheckFormatsDX8(Device);
209
210 if (ilutGetBoolean(ILUT_D3D_USE_DXTC) && FormatsDX8supported[3] && FormatsDX8supported[4] && FormatsDX8supported[5]) {
211 if (ilutCurImage->DxtcData != NULL && ilutCurImage->DxtcSize != 0) {
212 Format = D3DGetDXTCNumDX8(ilutCurImage->DxtcFormat);
213
214 if (FAILED(IDirect3DDevice8_CreateTexture(Device, ilutCurImage->Width,
215 ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format,
216 (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture)))
217 return NULL;
218 if (FAILED(IDirect3DTexture8_LockRect(Texture, 0, &Rect, NULL, 0)))
219 return NULL;
220 memcpy(Rect.pBits, ilutCurImage->DxtcData, ilutCurImage->DxtcSize);
221 goto success;
222 }
223
224 if (ilutGetBoolean(ILUT_D3D_GEN_DXTC)) {
225 DXTCFormat = ilutGetInteger(ILUT_DXTC_FORMAT);
226
227 Size = ilGetDXTCData(NULL, 0, DXTCFormat);
228 if (Size != 0) {
229 Buffer = (ILubyte*)ialloc(Size);
230 if (Buffer == NULL)
231 return NULL;
232 Size = ilGetDXTCData(Buffer, Size, DXTCFormat);
233 if (Size == 0) {
234 ifree(Buffer);
235 return NULL;
236 }
237
238 Format = D3DGetDXTCNumDX8(DXTCFormat);
239 if (FAILED(IDirect3DDevice8_CreateTexture(Device, ilutCurImage->Width,
240 ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format,
241 (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture))) {
242 ifree(Buffer);
243 return NULL;
244 }
245 if (FAILED(IDirect3DTexture8_LockRect(Texture, 0, &Rect, NULL, 0))) {
246 ifree(Buffer);
247 return NULL;
248 }
249 memcpy(Rect.pBits, Buffer, Size);
250 ifree(Buffer);
251 goto success;
252 }
253 }
254 }
255
256 Image = MakeD3D8Compliant(Device, &Format);
257 if (Image == NULL) {
258 if (Image != ilutCurImage)
259 ilCloseImage(Image);
260 return NULL;
261 }
262 if (FAILED(IDirect3DDevice8_CreateTexture(Device, Image->Width, Image->Height,
263 ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture))) {
264 if (Image != ilutCurImage)
265 ilCloseImage(Image);
266 return NULL;
267 }
268 if (FAILED(IDirect3DTexture8_LockRect(Texture, 0, &Rect, NULL, 0)))
269 return NULL;
270 memcpy(Rect.pBits, Image->Data, Image->SizeOfPlane);
271
272 success:
273 IDirect3DTexture8_UnlockRect(Texture, 0);
274 // Just let D3DX filter for us.
275 //D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_FILTER_BOX);
276 iD3D8CreateMipmaps(Texture, Image);
277
278 if (Image != ilutCurImage)
279 ilCloseImage(Image);
280
281 return Texture;
282 }
283
284
ilutD3D8VolumeTexture(IDirect3DDevice8 * Device)285 IDirect3DVolumeTexture8* ILAPIENTRY ilutD3D8VolumeTexture(IDirect3DDevice8 *Device)
286 {
287 IDirect3DVolumeTexture8 *Texture;
288 D3DLOCKED_BOX Box;
289 D3DFORMAT Format;
290 ILimage *Image;
291
292 ilutCurImage = ilGetCurImage();
293 if (ilutCurImage == NULL) {
294 ilSetError(ILUT_ILLEGAL_OPERATION);
295 return NULL;
296 }
297
298 if (!FormatsDX8Checked)
299 CheckFormatsDX8(Device);
300
301 Image = MakeD3D8Compliant(Device, &Format);
302 if (Image == NULL)
303 return NULL;
304 if (FAILED(IDirect3DDevice8_CreateVolumeTexture(Device, Image->Width, Image->Height,
305 Image->Depth, 1, 0, Format, (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture)))
306 return NULL;
307 if (FAILED(IDirect3DVolumeTexture8_LockBox(Texture, 0, &Box, NULL, 0)))
308 return NULL;
309
310 memcpy(Box.pBits, Image->Data, Image->SizeOfData);
311 if (!IDirect3DVolumeTexture8_UnlockBox(Texture, 0))
312 return IL_FALSE;
313
314 // We don't want to have mipmaps for such a large image.
315
316 if (Image != ilutCurImage)
317 ilCloseImage(Image);
318
319 return Texture;
320 }
321
322
MakeD3D8Compliant(IDirect3DDevice8 * Device,D3DFORMAT * DestFormat)323 ILimage *MakeD3D8Compliant(IDirect3DDevice8 *Device, D3DFORMAT *DestFormat)
324 {
325 ILimage *Converted, *Scaled, *CurImage;
326
327 *DestFormat = D3DFMT_A8R8G8B8;
328
329 // Images must be in BGRA format.
330 if (ilutCurImage->Format != IL_BGRA) {
331 Converted = iConvertImage(ilutCurImage, IL_BGRA, IL_UNSIGNED_BYTE);
332 if (Converted == NULL)
333 return NULL;
334 }
335 else {
336 Converted = ilutCurImage;
337 }
338
339 // Images must have their origin in the upper left.
340 if (Converted->Origin != IL_ORIGIN_UPPER_LEFT) {
341 CurImage = ilutCurImage;
342 ilSetCurImage(Converted);
343 iluFlipImage();
344 ilSetCurImage(CurImage);
345 }
346
347 // Images must have powers-of-2 dimensions.
348 if (ilNextPower2(ilutCurImage->Width) != ilutCurImage->Width ||
349 ilNextPower2(ilutCurImage->Height) != ilutCurImage->Height ||
350 ilNextPower2(ilutCurImage->Depth) != ilutCurImage->Depth) {
351 Scaled = iluScale_(Converted, ilNextPower2(ilutCurImage->Width),
352 ilNextPower2(ilutCurImage->Height), ilNextPower2(ilutCurImage->Depth));
353 if (Converted != ilutCurImage) {
354 ilCloseImage(Converted);
355 }
356 if (Scaled == NULL) {
357 return NULL;
358 }
359 Converted = Scaled;
360 }
361
362 return Converted;
363 }
364
365
iD3D8CreateMipmaps(IDirect3DTexture8 * Texture,ILimage * Image)366 ILboolean iD3D8CreateMipmaps(IDirect3DTexture8 *Texture, ILimage *Image)
367 {
368 D3DLOCKED_RECT Rect;
369 D3DSURFACE_DESC Desc;
370 ILuint NumMips, Width, Height, i;
371 ILimage *CurImage, *MipImage, *Temp;
372
373 NumMips = IDirect3DTexture8_GetLevelCount(Texture);
374 Width = Image->Width;
375 Height = Image->Height;
376
377 CurImage = ilGetCurImage();
378 MipImage = ilCopyImage_(CurImage);
379 ilSetCurImage(MipImage);
380 if (!iluBuildMipmaps()) {
381 ilCloseImage(MipImage);
382 ilSetCurImage(CurImage);
383 return IL_FALSE;
384 }
385 ilSetCurImage(CurImage);
386 Temp = MipImage->Mipmaps;
387
388 // Counts the base texture as 1.
389 for (i = 1; i < NumMips && Temp != NULL; i++) {
390 if (FAILED(IDirect3DTexture8_LockRect(Texture, i, &Rect, NULL, 0)))
391 return IL_FALSE;
392
393 Width = IL_MAX(1, Width / 2);
394 Height = IL_MAX(1, Height / 2);
395
396 IDirect3DTexture8_GetLevelDesc(Texture, i, &Desc);
397 if (Desc.Width != Width || Desc.Height != Height) {
398 IDirect3DTexture8_UnlockRect(Texture, i);
399 return IL_FALSE;
400 }
401
402 memcpy(Rect.pBits, Temp->Data, Temp->SizeOfData);
403
404 IDirect3DTexture8_UnlockRect(Texture, i);
405 Temp = Temp->Next;
406 }
407
408 ilCloseImage(MipImage);
409
410 return IL_TRUE;
411 }
412
413
414 //
415 // SaveSurfaceToFile.cpp
416 //
417 // Copyright (c) 2001 David Galeano
418 //
419 // Permission to use, copy, modify and distribute this software
420 // is hereby granted, provided that both the copyright notice and
421 // this permission notice appear in all copies of the software,
422 // derivative works or modified versions.
423 //
424 // THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
425 // CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
426 // WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
427 //
428
ilutD3D8LoadSurface(IDirect3DDevice8 * Device,IDirect3DSurface8 * Surface)429 ILAPI ILboolean ILAPIENTRY ilutD3D8LoadSurface(IDirect3DDevice8 *Device, IDirect3DSurface8 *Surface)
430 {
431 HRESULT hr;
432 D3DSURFACE_DESC d3dsd;
433 LPDIRECT3DSURFACE8 SurfaceCopy;
434 D3DLOCKED_RECT d3dLR;
435 ILboolean bHasAlpha;
436 ILubyte *Image, *ImageAux, *Data;
437 ILuint y, x;
438 ILushort dwColor;
439
440 IDirect3DSurface8_GetDesc(Surface, &d3dsd);
441
442 bHasAlpha = (d3dsd.Format == D3DFMT_A8R8G8B8 || d3dsd.Format == D3DFMT_A1R5G5B5);
443
444 if (bHasAlpha) {
445 if (!ilTexImage(d3dsd.Width, d3dsd.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL)) {
446 return IL_FALSE;
447 }
448 }
449 else {
450 if (!ilTexImage(d3dsd.Width, d3dsd.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) {
451 return IL_FALSE;
452 }
453 }
454
455 hr = IDirect3DDevice8_CreateImageSurface(Device, d3dsd.Width, d3dsd.Height, d3dsd.Format, &SurfaceCopy);
456 if (FAILED(hr)) {
457 ilSetError(ILUT_ILLEGAL_OPERATION);
458 return IL_FALSE;
459 }
460
461 hr = IDirect3DDevice8_CopyRects(Device, Surface, NULL, 0, SurfaceCopy, NULL);
462 if (FAILED(hr)) {
463 ilSetError(ILUT_ILLEGAL_OPERATION);
464 return IL_FALSE;
465 }
466
467 hr = IDirect3DSurface8_LockRect(SurfaceCopy, &d3dLR, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY);
468 if (FAILED(hr)) {
469 IDirect3DSurface8_Release(SurfaceCopy);
470 ilSetError(ILUT_ILLEGAL_OPERATION);
471 return IL_FALSE;
472 }
473
474 Image = (ILubyte*)d3dLR.pBits;
475 Data = ilutCurImage->Data;
476
477 for (y = 0; y < d3dsd.Height; y++) {
478 if (d3dsd.Format == D3DFMT_X8R8G8B8) {
479 ImageAux = Image;
480 for (x = 0; x < d3dsd.Width; x++) {
481 Data[0] = ImageAux[0];
482 Data[1] = ImageAux[1];
483 Data[2] = ImageAux[2];
484
485 Data += 3;
486 ImageAux += 4;
487 }
488 }
489 else if (d3dsd.Format == D3DFMT_A8R8G8B8) {
490 memcpy(Data, Image, d3dsd.Width * 4);
491 }
492 else if (d3dsd.Format == D3DFMT_R5G6B5) {
493 ImageAux = Image;
494 for (x = 0; x < d3dsd.Width; x++) {
495 dwColor = *((ILushort*)ImageAux);
496
497 Data[0] = (ILubyte)((dwColor&0x001f)<<3);
498 Data[1] = (ILubyte)(((dwColor&0x7e0)>>5)<<2);
499 Data[2] = (ILubyte)(((dwColor&0xf800)>>11)<<3);
500
501 Data += 3;
502 ImageAux += 2;
503 }
504 }
505 else if (d3dsd.Format == D3DFMT_X1R5G5B5) {
506 ImageAux = Image;
507 for (x = 0; x < d3dsd.Width; x++) {
508 dwColor = *((ILushort*)ImageAux);
509
510 Data[0] = (ILubyte)((dwColor&0x001f)<<3);
511 Data[1] = (ILubyte)(((dwColor&0x3e0)>>5)<<3);
512 Data[2] = (ILubyte)(((dwColor&0x7c00)>>10)<<3);
513
514 Data += 3;
515 ImageAux += 2;
516 }
517 }
518 else if (d3dsd.Format == D3DFMT_A1R5G5B5) {
519 ImageAux = Image;
520 for (x = 0; x < d3dsd.Width; x++) {
521 dwColor = *((ILushort*)ImageAux);
522
523 Data[0] = (ILubyte)((dwColor&0x001f)<<3);
524 Data[1] = (ILubyte)(((dwColor&0x3e0)>>5)<<3);
525 Data[2] = (ILubyte)(((dwColor&0x7c00)>>10)<<3);
526 Data[3] = (ILubyte)(((dwColor&0x8000)>>15)*255);
527
528 Data += 4;
529 ImageAux += 2;
530 }
531 }
532
533 Image += d3dLR.Pitch;
534 }
535
536 IDirect3DSurface8_UnlockRect(SurfaceCopy);
537 IDirect3DSurface8_Release(SurfaceCopy);
538
539 return IL_TRUE;
540 }
541
542 #endif//ILUT_USE_DIRECTX8
543