//----------------------------------------------------------------------------- // Does a texture have alpha? //----------------------------------------------------------------------------- static bool DoesTextureUseNormal( const char *pTextureName, const char *pMaterialName, bool &bUsesAlpha, bool &bIsCompressed, int &nSizeInBytes ) { nSizeInBytes = 0; bUsesAlpha = false; if ( IsX360() ) { // not supporting return false; } // Special textures start with '_'.. if ( !pTextureName || ( pTextureName[0] == '_' ) || ( pTextureName[0] == 0 ) ) return false; // The texture name doubles as the relative file name // It's assumed to have already been set by this point // Compute the cache name char pCacheFileName[MATERIAL_MAX_PATH]; Q_snprintf( pCacheFileName, sizeof( pCacheFileName ), "materials/%s.vtf", pTextureName ); CUtlBuffer buf; FileHandle_t fileHandle = g_pFullFileSystem->Open( pCacheFileName, "rb" ); if ( fileHandle == FILESYSTEM_INVALID_HANDLE) { // Warning( "Material \"%s\": can't open texture \"%s\"\n", pMaterialName, pCacheFileName ); return false; } // Check the .vtf for an alpha channel IVTFTexture *pVTFTexture = CreateVTFTexture(); int nHeaderSize = VTFFileHeaderSize( VTF_MAJOR_VERSION ); buf.EnsureCapacity( nHeaderSize ); // read the header first.. it's faster!! g_pFullFileSystem->Read( buf.Base(), nHeaderSize, fileHandle ); buf.SeekPut( CUtlBuffer::SEEK_HEAD, nHeaderSize ); // Unserialize the header bool bUsesNormal = false; if ( !pVTFTexture->Unserialize( buf, true ) ) { Warning( "Error reading material \"%s\"\n", pCacheFileName ); } else { if ( pVTFTexture->Flags() & TEXTUREFLAGS_NORMAL ) { bUsesAlpha = false; bUsesNormal = true; bIsCompressed = ImageLoader::IsCompressed( pVTFTexture->Format() ) || ( pVTFTexture->Format() == IMAGE_FORMAT_A8 ); nSizeInBytes = pVTFTexture->ComputeTotalSize(); if ( pVTFTexture->Flags() & (TEXTUREFLAGS_ONEBITALPHA | TEXTUREFLAGS_EIGHTBITALPHA) ) { bUsesAlpha = true; } } } DestroyVTFTexture( pVTFTexture ); g_pFullFileSystem->Close( fileHandle ); return bUsesNormal; }