IDirect3DTexture8* ILAPIENTRY ilutD3D8Texture(IDirect3DDevice8 *Device) { IDirect3DTexture8 *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 (!FormatsDX8Checked) CheckFormatsDX8(Device); if (ilutGetBoolean(ILUT_D3D_USE_DXTC) && FormatsDX8supported[3] && FormatsDX8supported[4] && FormatsDX8supported[5]) { if (ilutCurImage->DxtcData != NULL && ilutCurImage->DxtcSize != 0) { Format = D3DGetDXTCNumDX8(ilutCurImage->DxtcFormat); if (FAILED(IDirect3DDevice8_CreateTexture(Device, ilutCurImage->Width, ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, ilutGetInteger(ILUT_D3D_POOL), &Texture))) return NULL; if (FAILED(IDirect3DTexture8_LockRect(Texture, 0, &Rect, NULL, 0))) return NULL; memcpy(Rect.pBits, ilutCurImage->DxtcData, ilutCurImage->DxtcSize); goto success; } 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) return NULL; Size = ilGetDXTCData(Buffer, Size, DXTCFormat); if (Size == 0) { ifree(Buffer); return NULL; } Format = D3DGetDXTCNumDX8(DXTCFormat); if (FAILED(IDirect3DDevice8_CreateTexture(Device, ilutCurImage->Width, ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, ilutGetInteger(ILUT_D3D_POOL), &Texture))) { ifree(Buffer); return NULL; } if (FAILED(IDirect3DTexture8_LockRect(Texture, 0, &Rect, NULL, 0))) { ifree(Buffer); return NULL; } memcpy(Rect.pBits, Buffer, Size); ifree(Buffer); goto success; } } } Image = MakeD3D8Compliant(Device, &Format); if (Image == NULL) { if (Image != ilutCurImage) ilCloseImage(Image); return NULL; } if (FAILED(IDirect3DDevice8_CreateTexture(Device, Image->Width, Image->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, ilutGetInteger(ILUT_D3D_POOL), &Texture))) { if (Image != ilutCurImage) ilCloseImage(Image); return NULL; } if (FAILED(IDirect3DTexture8_LockRect(Texture, 0, &Rect, NULL, 0))) return NULL; memcpy(Rect.pBits, Image->Data, Image->SizeOfPlane); success: IDirect3DTexture8_UnlockRect(Texture, 0); // Just let D3DX filter for us. //D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_FILTER_BOX); iD3D8CreateMipmaps(Texture, Image); if (Image != ilutCurImage) ilCloseImage(Image); return Texture; }
ILboolean iD3D9CreateMipmaps(IDirect3DTexture9 *Texture, ILimage *Image) { D3DLOCKED_RECT Rect; D3DSURFACE_DESC Desc; ILuint NumMips, 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; if (MipImage->NumMips != 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->Next; } if (MipImage != Image) ilCloseImage(MipImage); ilSetCurImage(CurImage); return IL_TRUE; }
ILimage *MakeD3D10Compliant(ID3D10Device *Device, DXGI_FORMAT *DestFormat) { 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 = DXGI_FORMAT_R8G8B8A8_UINT; nConversionType = IL_UNSIGNED_BYTE; ilutFormat = IL_RGBA; break; case IL_FLOAT: case IL_DOUBLE: case IL_HALF: if (bForceIntegerFormat || (!FormatsDX10supported[6])) { *DestFormat = DXGI_FORMAT_R8G8B8A8_UINT; nConversionType = IL_UNSIGNED_BYTE; ilutFormat = IL_RGBA; } else { *DestFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; 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; } // Images must have their origin in the upper left. if (Converted->Origin != 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), 1); //@TODO: 1 should be ilNextPower2(ilutCurImage->Depth) if (Converted != ilutCurImage) { ilCloseImage(Converted); } if (Scaled == NULL) { return NULL; } Converted = Scaled; } return Converted; }
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, 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, 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, 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, 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; }