IDirect3DTexture9* Core::LoadTexture( IDirect3DDevice9* device, const tstring& file, u32* textureSize, bool* hasAlpha, D3DPOOL pool ) { IDirect3DTexture9* texture = NULL; bool alpha = false; if (!file.empty()) { if ( Helium::Path( file ).Exists() ) { D3DFORMAT textureFormat = D3DFMT_DXT1; D3DXIMAGE_INFO sourceInfo; LPDIRECT3DTEXTURE9 tempTexture; if ( D3DXCreateTextureFromFileEx( device, file.c_str(), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, NULL, D3DFMT_A8R8G8B8, pool, D3DX_DEFAULT, // filter? D3DX_FILTER_NONE, // mip filter NULL, &sourceInfo, NULL, &tempTexture ) == D3D_OK ) { // lock the first mip level, and iterate over all pixels looking for // alpha != 0 || alpha != 255 D3DLOCKED_RECT lockedRect; HRESULT locked = tempTexture->LockRect(0, &lockedRect, NULL, D3DLOCK_READONLY); D3DSURFACE_DESC desc; tempTexture->GetLevelDesc(0, &desc); for(u32 r = 0; r < desc.Height && textureFormat == D3DFMT_DXT1; r++) { u32* pixels = (u32*) (((u8*)lockedRect.pBits) + lockedRect.Pitch * r); for(u32 c = 0; c < desc.Width; c++) { u32 masked = pixels[c] & 0xFF000000; if(masked != 0xFF000000) { alpha = true; } if(masked != 0xFF000000 && masked != 0x00000000) { textureFormat = D3DFMT_DXT5; break; } } } tempTexture->UnlockRect(0); tempTexture->Release(); } int compressionRatio; switch ( textureFormat ) { case D3DFMT_DXT1: { if (alpha) { compressionRatio = 8; } else { compressionRatio = 6; } break; } case D3DFMT_DXT5: { compressionRatio = 4; break; } default: { compressionRatio = 1; HELIUM_BREAK(); break; } } if ( D3DXCreateTextureFromFileEx( device, file.c_str(), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, NULL, textureFormat, pool, D3DX_DEFAULT, D3DX_DEFAULT, NULL, &sourceInfo, NULL, &texture ) == D3D_OK ) { texture->SetAutoGenFilterType( D3DTEXF_ANISOTROPIC ); if ( textureSize ) { *textureSize = 0; for(u32 i = 0; i < texture->GetLevelCount(); i++) { D3DSURFACE_DESC desc; texture->GetLevelDesc(i, &desc); *textureSize += desc.Width * desc.Height * 4 / compressionRatio; } } } else { Log::Warning( TXT( "Unable to create texture from file '%s'\n" ), file.c_str() ); } } else { Log::Warning( TXT( "File '%s' does not exist\n" ), file.c_str() ); } } if ( hasAlpha ) { *hasAlpha = alpha; } return texture; }