+#include <msp/core/application.h>
+#include <msp/core/getopt.h>
+#include <msp/gl/glsl/compiler.h>
+#include <msp/io/print.h>
+
+class GlslCompiler: public Msp::RegisteredApplication<GlslCompiler>
+{
+private:
+ std::string source_fn;
+ bool parse_only;
+ bool combined;
+ Msp::GL::SL::Stage::Type stage;
+ bool dump_ast;
+
+public:
+ GlslCompiler(int, char **);
+
+ virtual int main();
+};
+
+using namespace std;
+using namespace Msp;
+
+GlslCompiler::GlslCompiler(int argc, char **argv):
+ parse_only(false),
+ combined(false),
+ stage(GL::SL::Stage::SHARED),
+ dump_ast(false)
+{
+ string stage_str;
+
+ GetOpt getopt;
+ getopt.add_option('c', "combined", combined, GetOpt::NO_ARG).set_help("Output combined GLSL");
+ getopt.add_option('a', "dump-ast", dump_ast, GetOpt::NO_ARG).set_help("Dump AST for debugging");
+ getopt.add_option('p', "parse_only", parse_only, GetOpt::NO_ARG).set_help("Only parse the loaded source, don't compile");
+ getopt.add_option('s', "stage", stage_str, GetOpt::REQUIRED_ARG).set_help("Output GLSL for STAGE", "STAGE");
+ getopt.add_argument("source", source_fn, GetOpt::REQUIRED_ARG).set_help("GLSL file to compile");
+ getopt(argc, argv);
+
+ if(stage_str=="vertex")
+ stage = GL::SL::Stage::VERTEX;
+ else if(stage_str=="geometry")
+ stage = GL::SL::Stage::GEOMETRY;
+ else if(stage_str=="fragment")
+ stage = GL::SL::Stage::FRAGMENT;
+ else if(!dump_ast)
+ combined = true;
+}
+
+int GlslCompiler::main()
+{
+ GL::SL::Compiler compiler(GL::SL::Features::all());
+ IO::File file(source_fn);
+ compiler.load_source(file, source_fn);
+ if(!parse_only)
+ compiler.compile(GL::SL::Compiler::PROGRAM);
+
+ if(dump_ast)
+ {
+ vector<GL::SL::Stage::Type> stages = compiler.get_stages();
+ for(vector<GL::SL::Stage::Type>::const_iterator i=stages.begin(); i!=stages.end(); ++i)
+ IO::print("%s\n", compiler.get_stage_debug(*i));
+ }
+
+ if(combined)
+ IO::print("%s\n", compiler.get_combined_glsl());
+ else if(stage!=GL::SL::Stage::SHARED)
+ IO::print("%s\n", compiler.get_stage_glsl(stage));
+
+ return 0;
+}