CefRefPtr<CefResourceHandler> VTFSchemeHandlerFactory::Create(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& scheme_name, CefRefPtr<CefRequest> request) { CefRefPtr<CefResourceHandler> pResourceHandler = NULL; CefURLParts parts; CefParseURL(request->GetURL(), parts); std::string strVtfPath = CefString(&parts.path); char vtfPath[MAX_PATH]; V_snprintf( vtfPath, sizeof( vtfPath ), "materials/%s", strVtfPath.c_str() ); V_FixupPathName( vtfPath, sizeof( vtfPath ), vtfPath ); if (!filesystem->FileExists(vtfPath)) { Warning( "VTFSchemeHandlerFactory: invalid vtf %s\n", vtfPath ); return NULL; } CUtlBuffer imageDataBuffer( 0, filesystem->Size(vtfPath), 0 ); if( !filesystem->ReadFile( vtfPath, NULL, imageDataBuffer ) ) { Warning( "VTFSchemeHandlerFactory: failed to read vtf %s\n", vtfPath ); return NULL; } IVTFTexture *pVTFTexture = CreateVTFTexture(); if( pVTFTexture->Unserialize( imageDataBuffer ) ) { pVTFTexture->ConvertImageFormat( IMAGE_FORMAT_RGB888, false, false ); if( pVTFTexture->Format() == IMAGE_FORMAT_RGB888 ) { uint8 *pImageData = pVTFTexture->ImageData(); CUtlBuffer buf; VTFHandler_ConvertImageToJPG( buf, pImageData, pVTFTexture->Width(), pVTFTexture->Height() ); if( buf.Size() > 0 ) { CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(static_cast<void*>(buf.Base()), buf.Size()); pResourceHandler = new CefStreamResourceHandler("image/jpeg", stream); } } else { Warning( "VTFSchemeHandlerFactory: unable to convert vtf %s to rgb format\n", vtfPath ); } } DestroyVTFTexture( pVTFTexture ); return pResourceHandler; }
//----------------------------------------------------------------------------- // Does a texture have alpha? //----------------------------------------------------------------------------- static bool DoesTextureUseAlpha( const char *pTextureName, const char *pMaterialName ) { if ( IsX360() ) { // not supporting return false; } // Special textures start with '_'.. if ( pTextureName[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 bUsesAlpha = false; if (!pVTFTexture->Unserialize( buf, true )) { Warning( "Error reading material \"%s\"\n", pCacheFileName ); g_pFullFileSystem->Close(fileHandle); } else { if ( pVTFTexture->Flags() & (TEXTUREFLAGS_ONEBITALPHA | TEXTUREFLAGS_EIGHTBITALPHA) ) { bUsesAlpha = true; } } DestroyVTFTexture( pVTFTexture ); g_pFullFileSystem->Close( fileHandle ); return bUsesAlpha; }
CMacroTextureData* LoadMacroTextureFile( const char *pFilename ) { FileHandle_t hFile = g_pFileSystem->Open( pFilename, "rb" ); if ( hFile == FILESYSTEM_INVALID_HANDLE ) return NULL; // Read the file in. CUtlVector<char> tempData; tempData.SetSize( g_pFileSystem->Size( hFile ) ); g_pFileSystem->Read( tempData.Base(), tempData.Count(), hFile ); g_pFileSystem->Close( hFile ); // Now feed the data into a CUtlBuffer (great...) CUtlBuffer buf; buf.Put( tempData.Base(), tempData.Count() ); // Now make a texture out of it. IVTFTexture *pTex = CreateVTFTexture(); if ( !pTex->Unserialize( buf ) ) Error( "IVTFTexture::Unserialize( %s ) failed.", pFilename ); pTex->ConvertImageFormat( IMAGE_FORMAT_RGBA8888, false ); // Get it in a format we like. // Now convert to a CMacroTextureData. CMacroTextureData *pData = new CMacroTextureData; pData->m_Width = pTex->Width(); pData->m_Height = pTex->Height(); pData->m_ImageData.EnsureCapacity( pData->m_Width * pData->m_Height * 4 ); memcpy( pData->m_ImageData.Base(), pTex->ImageData(), pData->m_Width * pData->m_Height * 4 ); DestroyVTFTexture( pTex ); Msg( "-- LoadMacroTextureFile: %s\n", pFilename ); return pData; }
int main( int argc, char **argv ) { SpewOutputFunc( VTF2TGAOutputFunc ); CommandLine()->CreateCmdLine( argc, argv ); MathLib_Init( 2.2f, 2.2f, 0.0f, 1.0f, false, false, false, false ); InitDefaultFileSystem(); const char *pVTFFileName = CommandLine()->ParmValue( "-i" ); const char *pTGAFileName = CommandLine()->ParmValue( "-o" ); bool bGenerateMipLevels = CommandLine()->CheckParm( "-mip" ) != NULL; if ( !pVTFFileName ) { Usage(); } if ( !pTGAFileName ) { pTGAFileName = pVTFFileName; } char pCurrentDirectory[MAX_PATH]; if ( _getcwd( pCurrentDirectory, sizeof(pCurrentDirectory) ) == NULL ) { fprintf( stderr, "Unable to get the current directory\n" ); return -1; } Q_StripTrailingSlash( pCurrentDirectory ); char pBuf[MAX_PATH]; if ( !Q_IsAbsolutePath( pTGAFileName ) ) { Q_snprintf( pBuf, sizeof(pBuf), "%s\\%s", pCurrentDirectory, pTGAFileName ); } else { Q_strncpy( pBuf, pTGAFileName, sizeof(pBuf) ); } Q_FixSlashes( pBuf ); char pOutFileNameBase[MAX_PATH]; Q_StripExtension( pBuf, pOutFileNameBase, MAX_PATH ); char pActualVTFFileName[MAX_PATH]; Q_strncpy( pActualVTFFileName, pVTFFileName, MAX_PATH ); if ( !Q_strstr( pActualVTFFileName, ".vtf" ) ) { Q_strcat( pActualVTFFileName, ".vtf", MAX_PATH ); } FILE *vtfFp = fopen( pActualVTFFileName, "rb" ); if( !vtfFp ) { Error( "Can't open %s\n", pActualVTFFileName ); exit( -1 ); } fseek( vtfFp, 0, SEEK_END ); int srcVTFLength = ftell( vtfFp ); fseek( vtfFp, 0, SEEK_SET ); CUtlBuffer buf; buf.EnsureCapacity( srcVTFLength ); int nBytesRead = fread( buf.Base(), 1, srcVTFLength, vtfFp ); fclose( vtfFp ); buf.SeekPut( CUtlBuffer::SEEK_HEAD, nBytesRead ); IVTFTexture *pTex = CreateVTFTexture(); if (!pTex->Unserialize( buf )) { Error( "*** Error reading in .VTF file %s\n", pActualVTFFileName ); exit(-1); } Msg( "vtf width: %d\n", pTex->Width() ); Msg( "vtf height: %d\n", pTex->Height() ); Msg( "vtf numFrames: %d\n", pTex->FrameCount() ); Msg( "TEXTUREFLAGS_POINTSAMPLE=%s\n", ( pTex->Flags() & TEXTUREFLAGS_POINTSAMPLE ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_TRILINEAR=%s\n", ( pTex->Flags() & TEXTUREFLAGS_TRILINEAR ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_CLAMPS=%s\n", ( pTex->Flags() & TEXTUREFLAGS_CLAMPS ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_CLAMPT=%s\n", ( pTex->Flags() & TEXTUREFLAGS_CLAMPT ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_CLAMPU=%s\n", ( pTex->Flags() & TEXTUREFLAGS_CLAMPU ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_BORDER=%s\n", ( pTex->Flags() & TEXTUREFLAGS_BORDER ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_ANISOTROPIC=%s\n", ( pTex->Flags() & TEXTUREFLAGS_ANISOTROPIC ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_HINT_DXT5=%s\n", ( pTex->Flags() & TEXTUREFLAGS_HINT_DXT5 ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_SRGB=%s\n", ( pTex->Flags() & TEXTUREFLAGS_SRGB ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_NORMAL=%s\n", ( pTex->Flags() & TEXTUREFLAGS_NORMAL ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_NOMIP=%s\n", ( pTex->Flags() & TEXTUREFLAGS_NOMIP ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_NOLOD=%s\n", ( pTex->Flags() & TEXTUREFLAGS_NOLOD ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_ALL_MIPS=%s\n", ( pTex->Flags() & TEXTUREFLAGS_ALL_MIPS ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_PROCEDURAL=%s\n", ( pTex->Flags() & TEXTUREFLAGS_PROCEDURAL ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_ONEBITALPHA=%s\n", ( pTex->Flags() & TEXTUREFLAGS_ONEBITALPHA ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_EIGHTBITALPHA=%s\n", ( pTex->Flags() & TEXTUREFLAGS_EIGHTBITALPHA ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_ENVMAP=%s\n", ( pTex->Flags() & TEXTUREFLAGS_ENVMAP ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_RENDERTARGET=%s\n", ( pTex->Flags() & TEXTUREFLAGS_RENDERTARGET ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_DEPTHRENDERTARGET=%s\n", ( pTex->Flags() & TEXTUREFLAGS_DEPTHRENDERTARGET ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_NODEBUGOVERRIDE=%s\n", ( pTex->Flags() & TEXTUREFLAGS_NODEBUGOVERRIDE ) ? "true" : "false" ); Msg( "TEXTUREFLAGS_SINGLECOPY=%s\n", ( pTex->Flags() & TEXTUREFLAGS_SINGLECOPY ) ? "true" : "false" ); Vector vecReflectivity = pTex->Reflectivity(); Msg( "vtf reflectivity: %f %f %f\n", vecReflectivity[0], vecReflectivity[1], vecReflectivity[2] ); Msg( "transparency: " ); if( pTex->Flags() & TEXTUREFLAGS_EIGHTBITALPHA ) { Msg( "eightbitalpha\n" ); } else if( pTex->Flags() & TEXTUREFLAGS_ONEBITALPHA ) { Msg( "onebitalpha\n" ); } else { Msg( "noalpha\n" ); } ImageFormat srcFormat = pTex->Format(); Msg( "vtf format: %s\n", ImageLoader::GetName( srcFormat ) ); int iTGANameLen = Q_strlen( pOutFileNameBase ); int iFaceCount = pTex->FaceCount(); int nFrameCount = pTex->FrameCount(); bool bIsCubeMap = pTex->IsCubeMap(); int iLastMipLevel = bGenerateMipLevels ? pTex->MipCount() - 1 : 0; for( int iFrame = 0; iFrame < nFrameCount; ++iFrame ) { for ( int iMipLevel = 0; iMipLevel <= iLastMipLevel; ++iMipLevel ) { int iWidth, iHeight, iDepth; pTex->ComputeMipLevelDimensions( iMipLevel, &iWidth, &iHeight, &iDepth ); for (int iCubeFace = 0; iCubeFace < iFaceCount; ++iCubeFace) { for ( int z = 0; z < iDepth; ++z ) { // Construct output filename char *pTempNameBuf = (char *)stackalloc( iTGANameLen + 13 ); Q_strncpy( pTempNameBuf, pOutFileNameBase, iTGANameLen + 1 ); char *pExt = Q_strrchr( pTempNameBuf, '.' ); if ( pExt ) { pExt = 0; } if ( bIsCubeMap ) { Assert( pTex->Depth() == 1 ); // shouldn't this be 1 instead of 0? static const char *pCubeFaceName[7] = { "rt", "lf", "bk", "ft", "up", "dn", "sph" }; Q_strcat( pTempNameBuf, pCubeFaceName[iCubeFace], iTGANameLen + 13 ); } if ( nFrameCount > 1 ) { char pTemp[4]; Q_snprintf( pTemp, 4, "%03d", iFrame ); Q_strcat( pTempNameBuf, pTemp, iTGANameLen + 13 ); } if ( iLastMipLevel != 0 ) { char pTemp[8]; Q_snprintf( pTemp, 8, "_mip%d", iMipLevel ); Q_strcat( pTempNameBuf, pTemp, iTGANameLen + 13 ); } if ( pTex->Depth() > 1 ) { char pTemp[6]; Q_snprintf( pTemp, 6, "_z%03d", z ); Q_strcat( pTempNameBuf, pTemp, iTGANameLen + 13 ); } if( srcFormat == IMAGE_FORMAT_RGBA16161616F ) { Q_strcat( pTempNameBuf, ".pfm", iTGANameLen + 13 ); } else { Q_strcat( pTempNameBuf, ".tga", iTGANameLen + 13 ); } unsigned char *pSrcImage = pTex->ImageData( iFrame, iCubeFace, iMipLevel, 0, 0, z ); ImageFormat dstFormat; if( srcFormat == IMAGE_FORMAT_RGBA16161616F ) { dstFormat = IMAGE_FORMAT_RGB323232F; } else { if( ImageLoader::IsTransparent( srcFormat ) || (srcFormat == IMAGE_FORMAT_ATI1N ) || (srcFormat == IMAGE_FORMAT_ATI2N )) { dstFormat = IMAGE_FORMAT_BGRA8888; } else { dstFormat = IMAGE_FORMAT_BGR888; } } // dstFormat = IMAGE_FORMAT_RGBA8888; // dstFormat = IMAGE_FORMAT_RGB888; // dstFormat = IMAGE_FORMAT_BGRA8888; // dstFormat = IMAGE_FORMAT_BGR888; // dstFormat = IMAGE_FORMAT_BGRA5551; // dstFormat = IMAGE_FORMAT_BGR565; // dstFormat = IMAGE_FORMAT_BGRA4444; // printf( "dstFormat: %s\n", ImageLoader::GetName( dstFormat ) ); unsigned char *pDstImage = new unsigned char[ImageLoader::GetMemRequired( iWidth, iHeight, 1, dstFormat, false )]; if( !ImageLoader::ConvertImageFormat( pSrcImage, srcFormat, pDstImage, dstFormat, iWidth, iHeight, 0, 0 ) ) { Error( "Error converting from %s to %s\n", ImageLoader::GetName( srcFormat ), ImageLoader::GetName( dstFormat ) ); exit( -1 ); } if( dstFormat != IMAGE_FORMAT_RGB323232F ) { if( ImageLoader::IsTransparent( dstFormat ) && ( dstFormat != IMAGE_FORMAT_RGBA8888 ) ) { unsigned char *tmpImage = pDstImage; pDstImage = new unsigned char[ImageLoader::GetMemRequired( iWidth, iHeight, 1, IMAGE_FORMAT_RGBA8888, false )]; if( !ImageLoader::ConvertImageFormat( tmpImage, dstFormat, pDstImage, IMAGE_FORMAT_RGBA8888, iWidth, iHeight, 0, 0 ) ) { Error( "Error converting from %s to %s\n", ImageLoader::GetName( dstFormat ), ImageLoader::GetName( IMAGE_FORMAT_RGBA8888 ) ); } dstFormat = IMAGE_FORMAT_RGBA8888; } else if( !ImageLoader::IsTransparent( dstFormat ) && ( dstFormat != IMAGE_FORMAT_RGB888 ) ) { unsigned char *tmpImage = pDstImage; pDstImage = new unsigned char[ImageLoader::GetMemRequired( iWidth, iHeight, 1, IMAGE_FORMAT_RGB888, false )]; if( !ImageLoader::ConvertImageFormat( tmpImage, dstFormat, pDstImage, IMAGE_FORMAT_RGB888, iWidth, iHeight, 0, 0 ) ) { Error( "Error converting from %s to %s\n", ImageLoader::GetName( dstFormat ), ImageLoader::GetName( IMAGE_FORMAT_RGB888 ) ); } dstFormat = IMAGE_FORMAT_RGB888; } CUtlBuffer outBuffer; TGAWriter::WriteToBuffer( pDstImage, outBuffer, iWidth, iHeight, dstFormat, dstFormat ); if ( !g_pFullFileSystem->WriteFile( pTempNameBuf, NULL, outBuffer ) ) { fprintf( stderr, "unable to write %s\n", pTempNameBuf ); } } else { PFMWrite( ( float * )pDstImage, pTempNameBuf, iWidth, iHeight ); } } } } } // leak leak leak leak leak, leak leak, leak leak (Blue Danube) return 0; }