@ -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 . 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 ( " 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 ( " output_filename " , " PNG or TGA file to generate " , true ) ;
args . addAdditionalArg ( " input_path " , " Path that containts interfaces elements " , false ) ;
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 ( ) ;
existingUVfilename = args . getArg ( " s " ) . front ( ) ;
}
}
// extract all interface elements
bool extractElements = args . haveArg ( " x " ) ;
std : : vector < std : : string > inputDirs = args . getAdditionalArg ( " input_path " ) ;
std : : vector < std : : string > inputDirs = args . getAdditionalArg ( " input_path " ) ;
string fmtName = args . getAdditionalArg ( " output_filename " ) . front ( ) ;
string fmtName = args . getAdditionalArg ( " output_filename " ) . front ( ) ;
@ -232,6 +236,111 @@ int main(int argc, char **argv)
// append PNG extension if no one provided
// append PNG extension if no one provided
if ( fmtName . rfind ( ' . ' ) = = string : : npos ) fmtName + = " .png " ;
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 > AllMapNames ;
vector < string > : : iterator it = inputDirs . begin ( ) , itEnd = inputDirs . end ( ) ;
vector < string > : : iterator it = inputDirs . begin ( ) , itEnd = inputDirs . end ( ) ;
@ -350,6 +459,9 @@ int main(int argc, char **argv)
UVMax [ i ] . V = UVMax [ i ] . V / ( float ) GlobalTexture . getHeight ( ) ;
UVMax [ i ] . V = UVMax [ i ] . V / ( float ) GlobalTexture . getHeight ( ) ;
}
}
// make sure transparent pixels are black
GlobalTexture . makeTransparentPixelsBlack ( ) ;
// Write global texture file
// Write global texture file
if ( writeFileDependingOnFilename ( fmtName , GlobalTexture ) )
if ( writeFileDependingOnFilename ( fmtName , GlobalTexture ) )
{
{
@ -365,7 +477,7 @@ int main(int argc, char **argv)
{
{
fmtName = fmtName . substr ( 0 , fmtName . rfind ( ' . ' ) ) ;
fmtName = fmtName . substr ( 0 , fmtName . rfind ( ' . ' ) ) ;
fmtName + = " .txt " ;
fmtName + = " .txt " ;
FILE * f = nlfopen ( fmtName , " w t " ) ;
FILE * f = nlfopen ( fmtName , " w b " ) ;
if ( f ! = NULL )
if ( f ! = NULL )
{
{
for ( sint i = 0 ; i < mapSize ; + + i )
for ( sint i = 0 ; i < mapSize ; + + i )
@ -399,7 +511,7 @@ int main(int argc, char **argv)
// Write subset UV text file
// Write subset UV text file
fmtName = fmtName . substr ( 0 , fmtName . rfind ( ' . ' ) ) ;
fmtName = fmtName . substr ( 0 , fmtName . rfind ( ' . ' ) ) ;
fmtName + = " .txt " ;
fmtName + = " .txt " ;
FILE * f = nlfopen ( fmtName , " w t " ) ;
FILE * f = nlfopen ( fmtName , " w b " ) ;
if ( f = = NULL )
if ( f = = NULL )
{
{
@ -419,18 +531,28 @@ int main(int argc, char **argv)
continue ;
continue ;
}
}
sTGAname = toLower ( string ( tgaName ) ) ;
// search position of extension
std : : string tgaExt = CFile : : getExtension ( sTGAname ) ;
// remove extension
sTGAname = CFile : : getFilenameWithoutExtension ( sTGAname ) ;
sint i ;
sint i ;
sTGAname = toLower ( string ( tgaName ) ) ;
string findTGAName ;
string findTGAName ;
for ( i = 0 ; i < mapSize ; + + i )
for ( i = 0 ; i < mapSize ; + + i )
{
{
// get the string whitout path
// get the string whitout path
findTGAName = toLower ( CFile : : getFilename ( AllMapNames [ i ] ) ) ;
findTGAName = toLower ( CFile : : getFilename WithoutExtension ( AllMapNames [ i ] ) ) ;
if ( findTGAName = = sTGAname )
if ( findTGAName = = sTGAname )
break ;
break ;
}
}
// append extension
sTGAname + = " . " + tgaExt ;
if ( i = = mapSize )
if ( i = = mapSize )
{
{
// not present in subset: offset existing uv's to (0,0), preserving size
// not present in subset: offset existing uv's to (0,0), preserving size
@ -439,8 +561,7 @@ int main(int argc, char **argv)
else
else
{
{
// present in subset: use new uv's
// present in subset: use new uv's
fprintf ( f , " %s %.12f %.12f %.12f %.12f \n " , sTGAname . c_str ( ) , UVMin [ i ] . U , UVMin [ i ] . V ,
fprintf ( f , " %s %.12f %.12f %.12f %.12f \n " , sTGAname . c_str ( ) , UVMin [ i ] . U , UVMin [ i ] . V , UVMax [ i ] . U , UVMax [ i ] . V ) ;
UVMax [ i ] . U , UVMax [ i ] . V ) ;
}
}
}
}
fclose ( f ) ;
fclose ( f ) ;