root/OpenSceneGraph/trunk/examples/osg2cpp/osg2cpp.cpp @ 10840

Revision 10840, 4.3 kB (checked in by robert, 5 years ago)

From Jean-Sebastien Guay, Explanation:

Currently osg2cpp removes "\n" line endings to replace them with a textual equivalent ("\\n") in order for the string representing the shader to contain line endings in the string. But if the file that was read contained Windows line endings ("\r\n"), the resulting file looked really weird (the \r were left there and editors interpreted that as an additional newline). Also, I can imagine that if the shader file that was read had Mac line endings ("\r") then the output shader would all end up in one long line since there are no "\n"...

What I've done:

I've added a search and replace of "\r\n" to "\n", and then "\r" to "\n" (note that the order is important).

I've also changed the filename handling so that the output file will be put in the same directory as the input file in case it was specified with a path. Previous functionality is retained for files specified with the filename only.""

Line 
1#include <osg/ArgumentParser>
2#include <osg/ApplicationUsage>
3
4#include <osgDB/ReadFile>
5#include <osgDB/FileNameUtils>
6#include <osgDB/fstream>
7
8#include <iostream>
9
10// Search in str for all occurences of spat and replace them with rpat.
11void searchAndReplace(std::string& str, const std::string& spat, const std::string& rpat)
12{
13    std::string::size_type pos = 0;
14    while ((pos = str.find(spat, pos)) != std::string::npos)
15    {
16        str.replace(pos, spat.length(), rpat);
17    }
18}
19
20void writeShader(osg::Shader* shader, const std::string& cppFileName, const std::string& variableName)
21{
22    osgDB::ofstream fout(cppFileName.c_str());
23    if (!fout)
24    {
25        std::cout<<"Error: could not open file `"<<cppFileName<<"` for writing."<<std::endl;
26    }
27
28    std::string shaderSource = shader->getShaderSource();
29    searchAndReplace(shaderSource, "\r\n", "\n");
30    searchAndReplace(shaderSource, "\r", "\n");
31
32    std::string variableString = std::string("char ")+variableName+std::string("[] = ");
33   
34    std::string::size_type startOfLine = 0;
35    std::string::size_type endOfLine = shaderSource.find_first_of('\n', startOfLine);
36   
37    if (endOfLine==std::string::npos)
38    {
39        fout<<variableString<<shaderSource<<"\\n\";"<<std::endl;
40    }
41    else
42    {
43        std::string padding(variableString.size(),' ');
44
45        fout<<variableString<<"\""<<shaderSource.substr(startOfLine,endOfLine-startOfLine)<<"\\n\""<<std::endl;
46        startOfLine = endOfLine+1;
47        endOfLine = shaderSource.find_first_of('\n', startOfLine);
48
49        while (endOfLine != std::string::npos)
50        {
51            fout<<padding<<"\""<<shaderSource.substr(startOfLine,endOfLine-startOfLine)<<"\\n\""<<std::endl;
52            startOfLine = endOfLine + 1;
53            endOfLine = shaderSource.find_first_of('\n', startOfLine);
54        }
55        fout<<padding<<"\""<<shaderSource.substr(startOfLine,endOfLine-startOfLine)<<"\\n\";"<<std::endl;
56    }
57    std::cout<<"Written shader to `"<<cppFileName<<"`"<<std::endl;
58}
59
60int main( int argc, char **argv )
61{
62    // use an ArgumentParser object to manage the program arguments.
63    osg::ArgumentParser arguments(&argc,argv);
64   
65    // set up the usage document, in case we need to print out how to use this program.
66    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
67    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is a utility for converting between various input and output databases formats.");
68    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
69    arguments.getApplicationUsage()->addCommandLineOption("--shader <filename>","Shader file to create a .cpp file for.");
70    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display command line parameters");
71
72    // if user request help write it out to cout.
73    if (arguments.read("-h") || arguments.read("--help"))
74    {
75        arguments.getApplicationUsage()->write(std::cout);
76        return 1;
77    }
78   
79    std::string filename;
80    if (arguments.read("--shader",filename))
81    {
82        osg::ref_ptr<osg::Shader> shader = osgDB::readShaderFile(filename);
83        if (shader.valid())
84        {
85            std::string name = osgDB::getStrippedName(filename);
86            std::string path = osgDB::getFilePath(filename);
87            std::string invalidCharacters = "-+/\\*=(){}[]:;<>,.?@'~#`!\"";
88            std::string numbericCharacters = "0123456789";
89            std::string::size_type pos = name.find_first_of(invalidCharacters);
90            while (pos != std::string::npos)
91            {
92                name[pos] = '_';
93                pos = name.find_first_of(invalidCharacters);
94            }
95           
96            std::string ext = osgDB::getFileExtension(filename);
97            std::string cppFileName = osgDB::concatPaths(path, name + "_" + ext + ".cpp");
98            std::string variableName = name + "_" + ext;
99            writeShader(shader.get(), cppFileName, variableName);
100
101            return 0;
102        }
103        else
104        {
105            std::cout<<"Error: could not find file '"<<filename<<"'"<<std::endl;
106            return 1;
107        }
108       
109    }
110
111    std::cout<<"No appropriate command line options used."<<std::endl;
112
113    arguments.getApplicationUsage()->write(std::cout);
114    return 1;
115}
Note: See TracBrowser for help on using the browser.