//----------------------------------------------------------------------------- // // ImageLib Utility Toolkit Sources // Copyright (C) 2000-2017 by Denton Woods // Last modified: 01/30/2009 // // Filename: src-ILUT/src/ilut_directx9.c // // Description: DirectX 9 functions for textures // //----------------------------------------------------------------------------- #include "ilut_internal.h" #ifdef ILUT_USE_DIRECTX9 #include //#include //#include #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") ILimage* MakeD3D9Compliant(IDirect3DDevice9 *Device, D3DFORMAT *DestFormat); ILenum GetD3D9Compat(ILenum Format); //D3DFORMAT GetD3DFormat(ILenum Format); D3DFORMAT D3DGetDXTCNumDX9(ILenum DXTCFormat); ILenum D3DGetDXTCFormat(D3DFORMAT DXTCNum); ILboolean iD3D9CreateMipmaps(IDirect3DTexture9 *Texture, ILimage *Image); IDirect3DTexture9* iD3DMakeTexture( IDirect3DDevice9 *Device, void *Data, ILuint DLen, ILuint Width, ILuint Height, D3DFORMAT Format, D3DPOOL Pool, ILuint Levels ); #define ILUT_TEXTUREFORMAT_D3D9_COUNT 7 ILboolean FormatsDX9Checked = IL_FALSE; ILboolean FormatsDX9supported[ILUT_TEXTUREFORMAT_D3D9_COUNT] = { IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE }; D3DFORMAT FormatsDX9[ILUT_TEXTUREFORMAT_D3D9_COUNT] = { D3DFMT_R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_L8, D3DFMT_DXT1, D3DFMT_DXT3, D3DFMT_DXT5, D3DFMT_A16B16G16R16F}; ILboolean ilutD3D9Init() { return IL_TRUE; } void CheckFormatsDX9(IDirect3DDevice9 *Device) { D3DDISPLAYMODE DispMode; HRESULT hr; IDirect3D9 *TestD3D9; ILuint i; IDirect3DDevice9_GetDirect3D(Device, (IDirect3D9**)&TestD3D9); IDirect3DDevice9_GetDisplayMode(Device, 0, &DispMode); for (i = 0; i < ILUT_TEXTUREFORMAT_D3D9_COUNT; i++) { hr = IDirect3D9_CheckDeviceFormat(TestD3D9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, DispMode.Format, 0, D3DRTYPE_TEXTURE, FormatsDX9[i]); FormatsDX9supported[i] = (ILboolean)SUCCEEDED(hr); } IDirect3D9_Release(TestD3D9); FormatsDX9Checked = IL_TRUE; return; } #ifndef _WIN32_WCE ILboolean ILAPIENTRY ilutD3D9TexFromFile(IDirect3DDevice9 *Device, ILconst_string FileName, IDirect3DTexture9 **Texture) { iBindImageTemp(); if (!ilLoadImage(FileName)) return IL_FALSE; *Texture = ilutD3D9Texture(Device); return IL_TRUE; } #endif//_WIN32_WCE #ifndef _WIN32_WCE ILboolean ILAPIENTRY ilutD3D9CubeTexFromFile(IDirect3DDevice9 *Device, ILconst_string FileName, IDirect3DCubeTexture9 **Texture) { iBindImageTemp(); if (!ilLoadImage(FileName)) return IL_FALSE; *Texture = ilutD3D9CubeTexture(Device); return IL_TRUE; } #endif//_WIN32_WCE ILboolean ILAPIENTRY ilutD3D9CubeTexFromFileInMemory(IDirect3DDevice9 *Device, void *Lump, ILuint Size, IDirect3DCubeTexture9 **Texture) { iBindImageTemp(); if( !ilLoadL(IL_TYPE_UNKNOWN, Lump, Size) ) return IL_FALSE; *Texture = ilutD3D9CubeTexture(Device); return IL_TRUE; } ILboolean ILAPIENTRY ilutD3D9CubeTexFromResource(IDirect3DDevice9 *Device, HMODULE SrcModule, ILconst_string SrcResource, IDirect3DCubeTexture9 **Texture) { HRSRC Resource; ILubyte *Data; iBindImageTemp(); Resource = (HRSRC)LoadResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP)); Data = (ILubyte*)LockResource(Resource); if (!ilLoadL(IL_TYPE_UNKNOWN, Data, SizeofResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP)))) return IL_FALSE; *Texture = ilutD3D9CubeTexture(Device); return IL_TRUE; } ILboolean ILAPIENTRY ilutD3D9CubeTexFromFileHandle(IDirect3DDevice9 *Device, ILHANDLE File, IDirect3DCubeTexture9 **Texture) { iBindImageTemp(); if( !ilLoadF(IL_TYPE_UNKNOWN, File) ) return IL_FALSE; *Texture = ilutD3D9CubeTexture(Device); return IL_TRUE; } D3DCUBEMAP_FACES iToD3D9Cube(ILuint cube) { switch (cube) { case IL_CUBEMAP_POSITIVEX: return D3DCUBEMAP_FACE_POSITIVE_X; case IL_CUBEMAP_NEGATIVEX: return D3DCUBEMAP_FACE_NEGATIVE_X; case IL_CUBEMAP_POSITIVEY: return D3DCUBEMAP_FACE_POSITIVE_Y; case IL_CUBEMAP_NEGATIVEY: return D3DCUBEMAP_FACE_NEGATIVE_Y; case IL_CUBEMAP_POSITIVEZ: return D3DCUBEMAP_FACE_POSITIVE_Z; case IL_CUBEMAP_NEGATIVEZ: return D3DCUBEMAP_FACE_NEGATIVE_Z; default: return D3DCUBEMAP_FACE_POSITIVE_X; //??? } } IDirect3DCubeTexture9* ILAPIENTRY ilutD3D9CubeTexture(IDirect3DDevice9 *Device) { IDirect3DCubeTexture9 *Texture; D3DLOCKED_RECT Box; D3DFORMAT Format; ILimage *StartImage; ILimage *Image; int i; Texture=NULL; Image=NULL; ilutCurImage = ilGetCurImage(); if (ilutCurImage == NULL) { ilSetError(ILUT_ILLEGAL_OPERATION); return NULL; } if (!FormatsDX9Checked) CheckFormatsDX9(Device); Image = MakeD3D9Compliant(Device, &Format); if (Image == NULL) { if (Image != ilutCurImage) ilCloseImage(Image); return NULL; } StartImage = ilutCurImage; if (FAILED(IDirect3DDevice9_CreateCubeTexture(Device, StartImage->Width, ilutGetInteger(ILUT_D3D_MIPLEVELS),0,Format, (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture, NULL))) return NULL; for (i = 0; i < CUBEMAP_SIDES; i++) { if (ilutCurImage==NULL || ilutCurImage->CubeFlags == 0) { SAFE_RELEASE(Texture) return NULL; } Image = ilutCurImage; Image = MakeD3D9Compliant(Device, &Format); if( Image == NULL ) { SAFE_RELEASE(Texture) return NULL; } if( FAILED(IDirect3DCubeTexture9_LockRect(Texture,iToD3D9Cube(Image->CubeFlags), 0, &Box, NULL, /*D3DLOCK_DISCARD*/0))) { SAFE_RELEASE(Texture) return NULL; } memcpy(Box.pBits, Image->Data, Image->SizeOfData); if (IDirect3DCubeTexture9_UnlockRect(Texture,iToD3D9Cube(Image->CubeFlags), 0) != D3D_OK) { SAFE_RELEASE(Texture) return IL_FALSE; } ilutCurImage=ilutCurImage->Faces; } ilutCurImage = StartImage; // We don't want to have mipmaps for such a large image. //if (Image != ilutCurImage) // ilCloseImage(Image); return Texture; } #ifndef _WIN32_WCE ILboolean ILAPIENTRY ilutD3D9VolTexFromFile(IDirect3DDevice9 *Device, ILconst_string FileName, IDirect3DVolumeTexture9 **Texture) { iBindImageTemp(); if (!ilLoadImage(FileName)) return IL_FALSE; *Texture = ilutD3D9VolumeTexture(Device); return IL_TRUE; } #endif//_WIN32_WCE ILboolean ILAPIENTRY ilutD3D9TexFromFileInMemory(IDirect3DDevice9 *Device, void *Lump, ILuint Size, IDirect3DTexture9 **Texture) { iBindImageTemp(); if (!ilLoadL(IL_TYPE_UNKNOWN, Lump, Size)) return IL_FALSE; *Texture = ilutD3D9Texture(Device); return IL_TRUE; } ILboolean ILAPIENTRY ilutD3D9VolTexFromFileInMemory(IDirect3DDevice9 *Device, void *Lump, ILuint Size, IDirect3DVolumeTexture9 **Texture) { iBindImageTemp(); if (!ilLoadL(IL_TYPE_UNKNOWN, Lump, Size)) return IL_FALSE; *Texture = ilutD3D9VolumeTexture(Device); return IL_TRUE; } ILboolean ILAPIENTRY ilutD3D9TexFromResource(IDirect3DDevice9 *Device, HMODULE SrcModule, ILconst_string SrcResource, IDirect3DTexture9 **Texture) { HRSRC Resource; ILubyte *Data; iBindImageTemp(); Resource = (HRSRC)LoadResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP)); Data = (ILubyte*)LockResource(Resource); if (!ilLoadL(IL_TYPE_UNKNOWN, Data, SizeofResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP)))) return IL_FALSE; *Texture = ilutD3D9Texture(Device); return IL_TRUE; } ILboolean ILAPIENTRY ilutD3D9VolTexFromResource(IDirect3DDevice9 *Device, HMODULE SrcModule, ILconst_string SrcResource, IDirect3DVolumeTexture9 **Texture) { HRSRC Resource; ILubyte *Data; iBindImageTemp(); Resource = (HRSRC)LoadResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP)); Data = (ILubyte*)LockResource(Resource); if (!ilLoadL(IL_TYPE_UNKNOWN, Data, SizeofResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP)))) return IL_FALSE; *Texture = ilutD3D9VolumeTexture(Device); return IL_TRUE; } ILboolean ILAPIENTRY ilutD3D9TexFromFileHandle(IDirect3DDevice9 *Device, ILHANDLE File, IDirect3DTexture9 **Texture) { iBindImageTemp(); if (!ilLoadF(IL_TYPE_UNKNOWN, File)) return IL_FALSE; *Texture = ilutD3D9Texture(Device); return IL_TRUE; } ILboolean ILAPIENTRY ilutD3D9VolTexFromFileHandle(IDirect3DDevice9 *Device, ILHANDLE File, IDirect3DVolumeTexture9 **Texture) { iBindImageTemp(); if (!ilLoadF(IL_TYPE_UNKNOWN, File)) return IL_FALSE; *Texture = ilutD3D9VolumeTexture(Device); return IL_TRUE; } D3DFORMAT D3DGetDXTCNumDX9(ILenum DXTCFormat) { switch (DXTCFormat) { case IL_DXT1: return D3DFMT_DXT1; case IL_DXT3: return D3DFMT_DXT3; case IL_DXT5: return D3DFMT_DXT5; } return D3DFMT_UNKNOWN; } ILenum D3DGetDXTCFormat(D3DFORMAT DXTCNum) { switch (DXTCNum) { case D3DFMT_DXT1: return IL_DXT1; case D3DFMT_DXT3: return IL_DXT3; case D3DFMT_DXT5: return IL_DXT5; } return D3DFMT_UNKNOWN; } IDirect3DTexture9* iD3DMakeTexture( IDirect3DDevice9 *Device, void *Data, ILuint DLen, ILuint Width, ILuint Height, D3DFORMAT Format, D3DPOOL Pool, ILuint Levels ) { IDirect3DTexture9 *Texture; D3DLOCKED_RECT Rect; if (FAILED(IDirect3DDevice9_CreateTexture(Device, Width, Height, Levels, 0, Format, Pool, &Texture, NULL))) return NULL; if (FAILED(IDirect3DTexture9_LockRect(Texture, 0, &Rect, NULL, 0))) return NULL; memcpy(Rect.pBits, Data, DLen); IDirect3DTexture9_UnlockRect(Texture, 0); return Texture; } IDirect3DTexture9* ILAPIENTRY ilutD3D9Texture(IDirect3DDevice9 *Device) { IDirect3DTexture9 *Texture; // D3DLOCKED_RECT Rect; D3DFORMAT Format; ILimage *Image; ILenum DXTCFormat; ILuint Size; ILubyte *Buffer; Image = ilutCurImage = ilGetCurImage(); if (ilutCurImage == NULL) { ilSetError(ILUT_ILLEGAL_OPERATION); return NULL; } if (!FormatsDX9Checked) CheckFormatsDX9(Device); if (ilutGetBoolean(ILUT_D3D_USE_DXTC) && FormatsDX9supported[3] && FormatsDX9supported[4] && FormatsDX9supported[5]) { if (ilutCurImage->DxtcData != NULL && ilutCurImage->DxtcSize != 0) { ILuint dxtcFormat = ilutGetInteger(ILUT_DXTC_FORMAT); Format = D3DGetDXTCNumDX9(ilutCurImage->DxtcFormat); ilutSetInteger(ILUT_DXTC_FORMAT, ilutCurImage->DxtcFormat); Texture = iD3DMakeTexture(Device, ilutCurImage->DxtcData, ilutCurImage->DxtcSize, ilutCurImage->Width, ilutCurImage->Height, Format, (D3DPOOL)(ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT ? D3DPOOL_SYSTEMMEM : ilutGetInteger(ILUT_D3D_POOL)), ilutGetInteger(ILUT_D3D_MIPLEVELS)); if (!Texture) return NULL; iD3D9CreateMipmaps(Texture, Image); if (ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT) { IDirect3DTexture9 *SysTex = Texture; // copy texture to device memory if (FAILED(IDirect3DDevice9_CreateTexture(Device, ilutCurImage->Width, ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, D3DPOOL_DEFAULT, &Texture, NULL))) { IDirect3DTexture9_Release(SysTex); return NULL; } if (FAILED(IDirect3DDevice9_UpdateTexture(Device, (LPDIRECT3DBASETEXTURE9)SysTex, (LPDIRECT3DBASETEXTURE9)Texture))) { IDirect3DTexture9_Release(SysTex); return NULL; } IDirect3DTexture9_Release(SysTex); } ilutSetInteger(ILUT_DXTC_FORMAT, dxtcFormat); goto success; } if (ilutGetBoolean(ILUT_D3D_GEN_DXTC)) { DXTCFormat = ilutGetInteger(ILUT_DXTC_FORMAT); /* Image = MakeD3D9Compliant(Device, &Format); if (Image == NULL) { if (Image != ilutCurImage) ilCloseImage(Image); return NULL; } */ Size = ilGetDXTCData(NULL, 0, DXTCFormat); if (Size != 0) { Buffer = (ILubyte*)ialloc(Size); if (Buffer == NULL) return NULL; Size = ilGetDXTCData(Buffer, Size, DXTCFormat); if (Size == 0) { ifree(Buffer); return NULL; } Format = D3DGetDXTCNumDX9(DXTCFormat); Texture = iD3DMakeTexture(Device, Buffer, Size, ilutCurImage->Width, ilutCurImage->Height, Format, (D3DPOOL)(ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT ? D3DPOOL_SYSTEMMEM : ilutGetInteger(ILUT_D3D_POOL)), ilutGetInteger(ILUT_D3D_MIPLEVELS)); if (!Texture) return NULL; iD3D9CreateMipmaps(Texture, Image); if (ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT) { IDirect3DTexture9 *SysTex = Texture; if (FAILED(IDirect3DDevice9_CreateTexture(Device, ilutCurImage->Width, ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, D3DPOOL_DEFAULT, &Texture, NULL))) { IDirect3DTexture9_Release(SysTex); return NULL; } if (FAILED(IDirect3DDevice9_UpdateTexture(Device, (LPDIRECT3DBASETEXTURE9)SysTex, (LPDIRECT3DBASETEXTURE9)Texture))) { IDirect3DTexture9_Release(SysTex); return NULL; } IDirect3DTexture9_Release(SysTex); } goto success; } } } Image = MakeD3D9Compliant(Device, &Format); if (Image == NULL) { if (Image != ilutCurImage) ilCloseImage(Image); return NULL; } Texture = iD3DMakeTexture(Device, Image->Data, Image->SizeOfPlane, Image->Width, Image->Height, Format, (D3DPOOL)(ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT ? D3DPOOL_SYSTEMMEM : ilutGetInteger(ILUT_D3D_POOL)), ilutGetInteger(ILUT_D3D_MIPLEVELS)); if (!Texture) return NULL; iD3D9CreateMipmaps(Texture, Image); if (ilutGetInteger(ILUT_D3D_POOL) == D3DPOOL_DEFAULT) { IDirect3DTexture9 *SysTex = Texture; // create texture in system memory if (FAILED(IDirect3DDevice9_CreateTexture(Device, Image->Width, Image->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture, NULL))) { IDirect3DTexture9_Release(SysTex); return NULL; } if (FAILED(IDirect3DDevice9_UpdateTexture(Device, (LPDIRECT3DBASETEXTURE9)SysTex, (LPDIRECT3DBASETEXTURE9)Texture))) { IDirect3DTexture9_Release(SysTex); return NULL; } IDirect3DTexture9_Release(SysTex); } // if (Image != ilutCurImage) // ilCloseImage(Image); success: if (Image != ilutCurImage) ilCloseImage(Image); return Texture; } IDirect3DVolumeTexture9* ILAPIENTRY ilutD3D9VolumeTexture(IDirect3DDevice9 *Device) { IDirect3DVolumeTexture9 *Texture; D3DLOCKED_BOX Box; D3DFORMAT Format; ILimage *Image; ilutCurImage = ilGetCurImage(); if (ilutCurImage == NULL) { ilSetError(ILUT_ILLEGAL_OPERATION); return NULL; } if (!FormatsDX9Checked) CheckFormatsDX9(Device); Image = MakeD3D9Compliant(Device, &Format); if (Image == NULL) return NULL; if (FAILED(IDirect3DDevice9_CreateVolumeTexture(Device, Image->Width, Image->Height, Image->Depth, 1, 0, Format, (D3DPOOL)ilutGetInteger(ILUT_D3D_POOL), &Texture, NULL))) return NULL; if (FAILED(IDirect3DVolumeTexture9_LockBox(Texture, 0, &Box, NULL, 0))) return NULL; memcpy(Box.pBits, Image->Data, Image->SizeOfData); if (!IDirect3DVolumeTexture9_UnlockBox(Texture, 0)) return IL_FALSE; // We don't want to have mipmaps for such a large image. if (Image != ilutCurImage) ilCloseImage(Image); return Texture; } ILimage *MakeD3D9Compliant(IDirect3DDevice9 *Device, D3DFORMAT *DestFormat) { ILuint color; ILimage *Converted, *Scaled, *CurImage; ILuint nConversionType, ilutFormat; ILboolean bForceIntegerFormat = ilutGetBoolean(ILUT_FORCE_INTEGER_FORMAT); Device; ilutFormat = ilutCurImage->Format; nConversionType = ilutCurImage->Type; if (!ilutCurImage) return NULL; switch (ilutCurImage->Type) { case IL_UNSIGNED_BYTE: case IL_BYTE: case IL_SHORT: case IL_UNSIGNED_SHORT: case IL_INT: case IL_UNSIGNED_INT: *DestFormat = D3DFMT_A8R8G8B8; nConversionType = IL_UNSIGNED_BYTE; ilutFormat = IL_BGRA; break; case IL_FLOAT: case IL_DOUBLE: case IL_HALF: if (bForceIntegerFormat || (!FormatsDX9supported[6])) { *DestFormat = D3DFMT_A8R8G8B8; nConversionType = IL_UNSIGNED_BYTE; ilutFormat = IL_BGRA; } else { *DestFormat = D3DFMT_A16B16G16R16F; nConversionType = IL_HALF; ilutFormat = IL_RGBA; // } break; } // Images must be in BGRA format. if (((ilutCurImage->Format != ilutFormat)) || (ilutCurImage->Type != nConversionType)) { Converted = iConvertImage(ilutCurImage, ilutFormat, nConversionType); if (Converted == NULL) return NULL; } else { Converted = ilutCurImage; } // perform alpha key on images if requested color=ilutGetInteger(ILUT_D3D_ALPHA_KEY_COLOR); if((color>=0) && (nConversionType == IL_UNSIGNED_BYTE)) { ILubyte *data; ILubyte *maxdata; ILuint t; data=(Converted->Data); maxdata=(Converted->Data+Converted->SizeOfData); while(dataOrigin != IL_ORIGIN_UPPER_LEFT) { CurImage = ilutCurImage; ilSetCurImage(Converted); iluFlipImage(); ilSetCurImage(CurImage); } // Images must have powers-of-2 dimensions. if (ilNextPower2(ilutCurImage->Width) != ilutCurImage->Width || ilNextPower2(ilutCurImage->Height) != ilutCurImage->Height || ilNextPower2(ilutCurImage->Depth) != ilutCurImage->Depth) { Scaled = iluScale_(Converted, ilNextPower2(ilutCurImage->Width), ilNextPower2(ilutCurImage->Height), ilNextPower2(ilutCurImage->Depth)); if (Converted != ilutCurImage) { ilCloseImage(Converted); } if (Scaled == NULL) { return NULL; } Converted = Scaled; } return Converted; } ILboolean iD3D9CreateMipmaps(IDirect3DTexture9 *Texture, ILimage *Image) { D3DLOCKED_RECT Rect; D3DSURFACE_DESC Desc; ILuint NumMips, srcMips, Width, Height, i; ILimage *CurImage, *MipImage, *Temp; ILenum DXTCFormat; ILuint Size; ILubyte *Buffer; ILboolean useDXTC = IL_FALSE; NumMips = IDirect3DTexture9_GetLevelCount(Texture); Width = Image->Width; Height = Image->Height; if (NumMips == 1) return IL_TRUE; CurImage = ilGetCurImage(); MipImage = Image; iGetIntegervImage(MipImage, IL_NUM_MIPMAPS, (ILint*) &srcMips); if ( srcMips != NumMips-1) { MipImage = ilCopyImage_(Image); ilSetCurImage(MipImage); if (!iluBuildMipmaps()) { ilCloseImage(MipImage); ilSetCurImage(CurImage); return IL_FALSE; } } // ilSetCurImage(CurImage); Temp = MipImage->Mipmaps; if (ilutGetBoolean(ILUT_D3D_USE_DXTC) && FormatsDX9supported[3] && FormatsDX9supported[4] && FormatsDX9supported[5]) useDXTC = IL_TRUE; // Counts the base texture as 1. for (i = 1; i < NumMips && Temp != NULL; i++) { ilSetCurImage(Temp); if (FAILED(IDirect3DTexture9_LockRect(Texture, i, &Rect, NULL, 0))) return IL_FALSE; Width = IL_MAX(1, Width / 2); Height = IL_MAX(1, Height / 2); IDirect3DTexture9_GetLevelDesc(Texture, i, &Desc); if (Desc.Width != Width || Desc.Height != Height) { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } if (useDXTC) { if (Temp->DxtcData != NULL && Temp->DxtcSize != 0) { memcpy(Rect.pBits, Temp->DxtcData, Temp->DxtcSize); } else if (ilutGetBoolean(ILUT_D3D_GEN_DXTC)) { DXTCFormat = ilutGetInteger(ILUT_DXTC_FORMAT); Size = ilGetDXTCData(NULL, 0, DXTCFormat); if (Size != 0) { Buffer = (ILubyte*)ialloc(Size); if (Buffer == NULL) { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } Size = ilGetDXTCData(Buffer, Size, DXTCFormat); if (Size == 0) { ifree(Buffer); IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } memcpy(Rect.pBits, Buffer, Size); } else { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } } else { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } } else memcpy(Rect.pBits, Temp->Data, Temp->SizeOfData); IDirect3DTexture9_UnlockRect(Texture, i); Temp = Temp->Mipmaps; } if (MipImage != Image) ilCloseImage(MipImage); ilSetCurImage(CurImage); return IL_TRUE; } // // SaveSurfaceToFile.cpp // // Copyright (c) 2001 David Galeano // // Permission to use, copy, modify and distribute this software // is hereby granted, provided that both the copyright notice and // this permission notice appear in all copies of the software, // derivative works or modified versions. // // THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" // CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES // WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. // ILAPI ILboolean ILAPIENTRY ilutD3D9LoadSurface(IDirect3DDevice9 *Device, IDirect3DSurface9 *Surface) { HRESULT hr; D3DSURFACE_DESC d3dsd; LPDIRECT3DSURFACE9 SurfaceCopy; D3DLOCKED_RECT d3dLR; ILboolean bHasAlpha; ILubyte *Image, *ImageAux, *Data; ILuint y, x; ILushort dwColor; IDirect3DSurface9_GetDesc(Surface, &d3dsd); bHasAlpha = (ILboolean)(d3dsd.Format == D3DFMT_A8R8G8B8 || d3dsd.Format == D3DFMT_A1R5G5B5); if (bHasAlpha) { if (!ilTexImage(d3dsd.Width, d3dsd.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; } } else { if (!ilTexImage(d3dsd.Width, d3dsd.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; } } hr = IDirect3DDevice9_CreateOffscreenPlainSurface(Device, d3dsd.Width, d3dsd.Height, d3dsd.Format, D3DPOOL_SCRATCH, &SurfaceCopy, NULL); if (FAILED(hr)) { ilSetError(ILUT_ILLEGAL_OPERATION); return IL_FALSE; } hr = IDirect3DDevice9_StretchRect(Device, Surface, NULL, SurfaceCopy, NULL, D3DTEXF_NONE); if (FAILED(hr)) { ilSetError(ILUT_ILLEGAL_OPERATION); return IL_FALSE; } hr = IDirect3DSurface9_LockRect(SurfaceCopy, &d3dLR, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY); if (FAILED(hr)) { IDirect3DSurface9_Release(SurfaceCopy); ilSetError(ILUT_ILLEGAL_OPERATION); return IL_FALSE; } Image = (ILubyte*)d3dLR.pBits; Data = ilutCurImage->Data; for (y = 0; y < d3dsd.Height; y++) { if (d3dsd.Format == D3DFMT_X8R8G8B8) { ImageAux = Image; for (x = 0; x < d3dsd.Width; x++) { Data[0] = ImageAux[0]; Data[1] = ImageAux[1]; Data[2] = ImageAux[2]; Data += 3; ImageAux += 4; } } else if (d3dsd.Format == D3DFMT_A8R8G8B8) { memcpy(Data, Image, d3dsd.Width * 4); } else if (d3dsd.Format == D3DFMT_R5G6B5) { ImageAux = Image; for (x = 0; x < d3dsd.Width; x++) { dwColor = *((ILushort*)ImageAux); Data[0] = (ILubyte)((dwColor&0x001f)<<3); Data[1] = (ILubyte)(((dwColor&0x7e0)>>5)<<2); Data[2] = (ILubyte)(((dwColor&0xf800)>>11)<<3); Data += 3; ImageAux += 2; } } else if (d3dsd.Format == D3DFMT_X1R5G5B5) { ImageAux = Image; for (x = 0; x < d3dsd.Width; x++) { dwColor = *((ILushort*)ImageAux); Data[0] = (ILubyte)((dwColor&0x001f)<<3); Data[1] = (ILubyte)(((dwColor&0x3e0)>>5)<<3); Data[2] = (ILubyte)(((dwColor&0x7c00)>>10)<<3); Data += 3; ImageAux += 2; } } else if (d3dsd.Format == D3DFMT_A1R5G5B5) { ImageAux = Image; for (x = 0; x < d3dsd.Width; x++) { dwColor = *((ILushort*)ImageAux); Data[0] = (ILubyte)((dwColor&0x001f)<<3); Data[1] = (ILubyte)(((dwColor&0x3e0)>>5)<<3); Data[2] = (ILubyte)(((dwColor&0x7c00)>>10)<<3); Data[3] = (ILubyte)(((dwColor&0x8000)>>15)*255); Data += 4; ImageAux += 2; } } Image += d3dLR.Pitch; } IDirect3DSurface9_UnlockRect(SurfaceCopy); IDirect3DSurface9_Release(SurfaceCopy); return IL_TRUE; } #endif//ILUT_USE_DIRECTX9