2008-09-25 22:39:57 +08:00
# include <osg/ArgumentParser>
# include <osg/ApplicationUsage>
# include <osgDB/ReadFile>
# include <osgDB/FileNameUtils>
2008-11-07 23:08:08 +08:00
# include <osgDB/fstream>
2008-09-25 22:39:57 +08:00
# include <iostream>
2015-04-13 18:43:56 +08:00
// Search in str for all occurrences of spat and replace them with rpat.
2009-11-27 23:39:07 +08:00
void searchAndReplace ( std : : string & str , const std : : string & spat , const std : : string & rpat )
{
std : : string : : size_type pos = 0 ;
while ( ( pos = str . find ( spat , pos ) ) ! = std : : string : : npos )
{
str . replace ( pos , spat . length ( ) , rpat ) ;
2011-05-27 19:07:04 +08:00
pos + = rpat . length ( ) ;
2009-11-27 23:39:07 +08:00
}
}
2008-09-25 22:39:57 +08:00
void writeShader ( osg : : Shader * shader , const std : : string & cppFileName , const std : : string & variableName )
{
2008-11-07 23:08:08 +08:00
osgDB : : ofstream fout ( cppFileName . c_str ( ) ) ;
2008-09-25 22:39:57 +08:00
if ( ! fout )
{
std : : cout < < " Error: could not open file ` " < < cppFileName < < " ` for writing. " < < std : : endl ;
}
std : : string shaderSource = shader - > getShaderSource ( ) ;
2009-11-27 23:39:07 +08:00
searchAndReplace ( shaderSource , " \r \n " , " \n " ) ;
searchAndReplace ( shaderSource , " \r " , " \n " ) ;
2011-05-12 20:28:43 +08:00
searchAndReplace ( shaderSource , " \" " , " \\ \" " ) ;
2014-01-21 01:03:29 +08:00
2008-09-25 22:39:57 +08:00
std : : string variableString = std : : string ( " char " ) + variableName + std : : string ( " [] = " ) ;
2014-01-21 01:03:29 +08:00
2008-09-25 22:39:57 +08:00
std : : string : : size_type startOfLine = 0 ;
std : : string : : size_type endOfLine = shaderSource . find_first_of ( ' \n ' , startOfLine ) ;
2014-01-21 01:03:29 +08:00
if ( endOfLine = = std : : string : : npos )
2008-09-25 22:39:57 +08:00
{
fout < < variableString < < shaderSource < < " \\ n \" ; " < < std : : endl ;
}
else
{
std : : string padding ( variableString . size ( ) , ' ' ) ;
fout < < variableString < < " \" " < < shaderSource . substr ( startOfLine , endOfLine - startOfLine ) < < " \\ n \" " < < std : : endl ;
startOfLine = endOfLine + 1 ;
endOfLine = shaderSource . find_first_of ( ' \n ' , startOfLine ) ;
while ( endOfLine ! = std : : string : : npos )
{
fout < < padding < < " \" " < < shaderSource . substr ( startOfLine , endOfLine - startOfLine ) < < " \\ n \" " < < std : : endl ;
startOfLine = endOfLine + 1 ;
endOfLine = shaderSource . find_first_of ( ' \n ' , startOfLine ) ;
}
fout < < padding < < " \" " < < shaderSource . substr ( startOfLine , endOfLine - startOfLine ) < < " \\ n \" ; " < < std : : endl ;
}
std : : cout < < " Written shader to ` " < < cppFileName < < " ` " < < std : : endl ;
}
int main ( int argc , char * * argv )
{
// use an ArgumentParser object to manage the program arguments.
osg : : ArgumentParser arguments ( & argc , argv ) ;
2014-01-21 01:03:29 +08:00
2008-09-25 22:39:57 +08:00
// set up the usage document, in case we need to print out how to use this program.
arguments . getApplicationUsage ( ) - > setApplicationName ( arguments . getApplicationName ( ) ) ;
2012-02-18 00:51:10 +08:00
arguments . getApplicationUsage ( ) - > setDescription ( arguments . getApplicationName ( ) + " is a utility for converting glsl shader files into char arrays that can be compiled into applications. " ) ;
2008-09-25 22:39:57 +08:00
arguments . getApplicationUsage ( ) - > setCommandLineUsage ( arguments . getApplicationName ( ) + " [options] filename ... " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --shader <filename> " , " Shader file to create a .cpp file for. " ) ;
2014-01-21 01:03:29 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --write-to-source-file-directory " , " Use the path to the source filename as the directory to write to. " ) ;
2008-09-25 22:39:57 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -h or --help " , " Display command line parameters " ) ;
// if user request help write it out to cout.
if ( arguments . read ( " -h " ) | | arguments . read ( " --help " ) )
2014-01-21 01:03:29 +08:00
{
2008-09-25 22:39:57 +08:00
arguments . getApplicationUsage ( ) - > write ( std : : cout ) ;
return 1 ;
}
2014-01-21 01:03:29 +08:00
bool useSamePathAsSourceFile = false ;
if ( arguments . read ( " --write-to-source-file-directory " ) ) useSamePathAsSourceFile = true ;
2008-09-25 22:39:57 +08:00
std : : string filename ;
if ( arguments . read ( " --shader " , filename ) )
{
2015-10-22 22:14:53 +08:00
osg : : ref_ptr < osg : : Shader > shader = osgDB : : readRefShaderFile ( filename ) ;
2008-09-25 22:39:57 +08:00
if ( shader . valid ( ) )
{
std : : string name = osgDB : : getStrippedName ( filename ) ;
2009-11-27 23:39:07 +08:00
std : : string path = osgDB : : getFilePath ( filename ) ;
2008-09-25 22:39:57 +08:00
std : : string invalidCharacters = " -+/ \\ *=(){}[]:;<>,.?@'~#`! \" " ;
std : : string numbericCharacters = " 0123456789 " ;
std : : string : : size_type pos = name . find_first_of ( invalidCharacters ) ;
while ( pos ! = std : : string : : npos )
{
name [ pos ] = ' _ ' ;
pos = name . find_first_of ( invalidCharacters ) ;
}
2014-01-21 01:03:29 +08:00
2008-09-25 22:39:57 +08:00
std : : string ext = osgDB : : getFileExtension ( filename ) ;
2014-01-21 01:03:29 +08:00
std : : string cppFileName = name + " _ " + ext + " .cpp " ;
if ( useSamePathAsSourceFile ) cppFileName = osgDB : : concatPaths ( path , cppFileName ) ;
2008-09-25 22:39:57 +08:00
std : : string variableName = name + " _ " + ext ;
writeShader ( shader . get ( ) , cppFileName , variableName ) ;
return 0 ;
}
else
{
2009-02-06 23:17:49 +08:00
std : : cout < < " Error: could not find file ' " < < filename < < " ' " < < std : : endl ;
2008-09-25 22:39:57 +08:00
return 1 ;
}
2014-01-21 01:03:29 +08:00
2008-09-25 22:39:57 +08:00
}
std : : cout < < " No appropriate command line options used. " < < std : : endl ;
arguments . getApplicationUsage ( ) - > write ( std : : cout ) ;
return 1 ;
}