@ -210,6 +210,7 @@ int main(int argc, char **argv)
args . setDescription ( " Build a huge interface texture from several small elements to optimize video memory usage. " ) ;
args . addArg ( " s " , " subset " , " existing_uv_txt_name " , " Build a subset of an existing interface definition while preserving the existing texture ids, to support freeing up VRAM by switching to the subset without rebuilding the entire interface. " ) ;
args . addArg ( " x " , " extract " , " " , " Extract all interface elements from <output_filename> to <input_path>. " ) ;
args . addAdditionalArg ( " output_filename " , " PNG or TGA file to generate " , true ) ;
args . addAdditionalArg ( " input_path " , " Path that containts interfaces elements " , false ) ;
@ -225,6 +226,9 @@ int main(int argc, char **argv)
existingUVfilename = args . getArg ( " s " ) . front ( ) ;
}
// extract all interface elements
bool extractElements = args . haveArg ( " x " ) ;
std : : vector < std : : string > inputDirs = args . getAdditionalArg ( " input_path " ) ;
string fmtName = args . getAdditionalArg ( " output_filename " ) . front ( ) ;
@ -232,6 +236,111 @@ int main(int argc, char **argv)
// append PNG extension if no one provided
if ( fmtName . rfind ( ' . ' ) = = string : : npos ) fmtName + = " .png " ;
if ( extractElements )
{
if ( inputDirs . empty ( ) )
{
outString ( toString ( " ERROR: No input directories specified " ) ) ;
return - 1 ;
}
// name of UV file
existingUVfilename = fmtName . substr ( 0 , fmtName . rfind ( ' . ' ) ) ;
existingUVfilename + = " .txt " ;
// Load existing UV file
CIFile iFile ;
string filename = CPath : : lookup ( existingUVfilename , false ) ;
if ( filename . empty ( ) | | ! iFile . open ( filename ) )
{
outString ( toString ( " ERROR: Unable to open %s " , existingUVfilename . c_str ( ) ) ) ;
return - 1 ;
}
// Load existing bitmap file
CIFile bitmapFile ;
if ( ! bitmapFile . open ( fmtName ) )
{
outString ( toString ( " ERROR: Unable to open %s " , fmtName . c_str ( ) ) ) ;
return - 1 ;
}
// load bitmap
CBitmap textureBitmap ;
uint8 colors = textureBitmap . load ( bitmapFile ) ;
// file already loaded in memory, close it
bitmapFile . close ( ) ;
if ( colors ! = 32 )
{
outString ( toString ( " ERROR: %s is not a RGBA bitmap " , existingUVfilename . c_str ( ) ) ) ;
return - 1 ;
}
// make sure transparent pixels are black
textureBitmap . makeTransparentPixelsBlack ( ) ;
float textureWidth = ( float ) textureBitmap . getWidth ( ) ;
float textureHeight = ( float ) textureBitmap . getHeight ( ) ;
char bufTmp [ 256 ] , tgaName [ 256 ] ;
string sTGAname ;
float uvMinU , uvMinV , uvMaxU , uvMaxV ;
while ( ! iFile . eof ( ) )
{
iFile . getline ( bufTmp , 256 ) ;
if ( sscanf ( bufTmp , " %s %f %f %f %f " , tgaName , & uvMinU , & uvMinV , & uvMaxU , & uvMaxV ) ! = 5 )
{
nlwarning ( " Can't parse %s " , bufTmp ) ;
continue ;
}
float xf = uvMinU * textureWidth ;
float yf = uvMinV * textureHeight ;
float widthf = ( uvMaxU - uvMinU ) * textureWidth ;
float heightf = ( uvMaxV - uvMinV ) * textureHeight ;
uint x = ( uint ) xf ;
uint y = ( uint ) yf ;
uint width = ( uint ) widthf ;
uint height = ( uint ) heightf ;
if ( ( float ) x ! = xf | | ( float ) y ! = yf | | ( float ) width ! = widthf | | ( float ) height ! = heightf )
{
nlwarning ( " Wrong round " ) ;
}
if ( width & & height )
{
// create bitmap
CBitmap bitmap ;
bitmap . resize ( width , height ) ;
bitmap . blit ( textureBitmap , x , y , width , height , 0 , 0 ) ;
sTGAname = inputDirs . front ( ) + " / " + tgaName ;
if ( writeFileDependingOnFilename ( sTGAname , bitmap ) )
{
outString ( toString ( " Writing file %s " , sTGAname . c_str ( ) ) ) ;
}
else
{
outString ( toString ( " Unable to writing file %s " , sTGAname . c_str ( ) ) ) ;
}
}
else
{
outString ( toString ( " Bitmap with wrong size " ) ) ;
}
}
return 0 ;
}
vector < string > AllMapNames ;
vector < string > : : iterator it = inputDirs . begin ( ) , itEnd = inputDirs . end ( ) ;