]> git.tdb.fi Git - libs/gl.git/blob - tools/glslcompiler.cpp
Support specialization constants in the GLSL compiler
[libs/gl.git] / tools / glslcompiler.cpp
1 #include <msp/core/application.h>
2 #include <msp/core/getopt.h>
3 #include <msp/gl/glsl/compiler.h>
4 #include <msp/io/print.h>
5 #include <msp/strings/utils.h>
6
7 class GlslCompiler: public Msp::RegisteredApplication<GlslCompiler>
8 {
9 private:
10         std::string source_fn;
11         std::map<std::string, int> spec_values;
12         bool parse_only;
13         bool combined;
14         Msp::GL::SL::Stage::Type stage;
15         bool dump_ast;
16
17 public:
18         GlslCompiler(int, char **);
19
20         virtual int main();
21 };
22
23 using namespace std;
24 using namespace Msp;
25
26 GlslCompiler::GlslCompiler(int argc, char **argv):
27         parse_only(false),
28         combined(false),
29         stage(GL::SL::Stage::SHARED),
30         dump_ast(false)
31 {
32         string stage_str;
33         vector<string> spec_values_in;
34
35         GetOpt getopt;
36         getopt.add_option('c', "combined", combined, GetOpt::NO_ARG).set_help("Output combined GLSL");
37         getopt.add_option('a', "dump-ast", dump_ast, GetOpt::NO_ARG).set_help("Dump AST for debugging");
38         getopt.add_option('p', "parse_only", parse_only, GetOpt::NO_ARG).set_help("Only parse the loaded source, don't compile");
39         getopt.add_option('e', "specialize", spec_values_in, GetOpt::REQUIRED_ARG).set_help("Set specialization constant", "NAME:VALUE");
40         getopt.add_option('s', "stage", stage_str, GetOpt::REQUIRED_ARG).set_help("Output GLSL for STAGE", "STAGE");
41         getopt.add_argument("source", source_fn, GetOpt::REQUIRED_ARG).set_help("GLSL file to compile");
42         getopt(argc, argv);
43
44         if(stage_str=="vertex")
45                 stage = GL::SL::Stage::VERTEX;
46         else if(stage_str=="geometry")
47                 stage = GL::SL::Stage::GEOMETRY;
48         else if(stage_str=="fragment")
49                 stage = GL::SL::Stage::FRAGMENT;
50         else if(!dump_ast)
51                 combined = true;
52
53         for(vector<string>::const_iterator i=spec_values_in.begin(); i!=spec_values_in.end(); ++i)
54         {
55                 unsigned colon = i->find(':');
56                 if(colon==string::npos || colon==0 || colon+1>=i->size())
57                         throw usage_error("Invalid specialization value");
58
59                 string value_str = i->substr(colon+1);
60                 int value;
61                 if(isnumrc(value_str))
62                         value = lexical_cast<int>(value_str);
63                 else
64                         value = lexical_cast<bool>(value_str);
65                 spec_values[i->substr(0, colon)] = value;
66         }
67 }
68
69 int GlslCompiler::main()
70 {
71         GL::SL::Compiler compiler(GL::SL::Features::all());
72         IO::File file(source_fn);
73         compiler.load_source(file, source_fn);
74         compiler.specialize(spec_values);
75         if(!parse_only)
76                 compiler.compile(GL::SL::Compiler::PROGRAM);
77
78         if(dump_ast)
79         {
80                 vector<GL::SL::Stage::Type> stages = compiler.get_stages();
81                 for(vector<GL::SL::Stage::Type>::const_iterator i=stages.begin(); i!=stages.end(); ++i)
82                         IO::print("%s\n", compiler.get_stage_debug(*i));
83         }
84
85         if(combined)
86                 IO::print("%s\n", compiler.get_combined_glsl());
87         else if(stage!=GL::SL::Stage::SHARED)
88                 IO::print("%s\n", compiler.get_stage_glsl(stage));
89
90         return 0;
91 }