throw invalid_operation("ProgramCompiler::add_shaders");
string head = "#version 150\n";
- if(module->vertex_stage.present)
- program.attach_shader_owned(new VertexShader(head+format_stage(module->vertex_stage)));
- if(module->geometry_stage.present)
- program.attach_shader_owned(new GeometryShader(head+format_stage(module->geometry_stage)));
- if(module->fragment_stage.present)
- program.attach_shader_owned(new FragmentShader(head+format_stage(module->fragment_stage)));
+ for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
+ {
+ if(i->type==VERTEX)
+ program.attach_shader_owned(new VertexShader(head+create_source(*i)));
+ else if(i->type==GEOMETRY)
+ program.attach_shader_owned(new GeometryShader(head+create_source(*i)));
+ else if(i->type==FRAGMENT)
+ program.attach_shader_owned(new FragmentShader(head+create_source(*i)));
+ }
program.bind_attribute(VERTEX4, "vertex");
program.bind_attribute(NORMAL3, "normal");
void ProgramCompiler::process()
{
- if(module->vertex_stage.present)
- generate(module->vertex_stage);
- if(module->geometry_stage.present)
- generate(module->geometry_stage);
- if(module->fragment_stage.present)
- generate(module->fragment_stage);
-
- if(module->vertex_stage.present)
- optimize(module->vertex_stage);
- if(module->geometry_stage.present)
- optimize(module->geometry_stage);
- if(module->fragment_stage.present)
- optimize(module->fragment_stage);
+ for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
+ generate(*i);
+ for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
+ optimize(*i);
}
void ProgramCompiler::generate(Stage &stage)
stage.content.visit(resolver);
}
-string ProgramCompiler::format_stage(Stage &stage)
+string ProgramCompiler::create_source(Stage &stage)
{
Formatter formatter;
stage.content.visit(formatter);
void optimize(ProgramSyntax::Stage &);
static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &);
static void resolve_variables(ProgramSyntax::Stage &);
- std::string format_stage(ProgramSyntax::Stage &);
+ std::string create_source(ProgramSyntax::Stage &);
};
} // namespace GL
{ { 0 }, 18, NO_OPERATOR, LEFT_TO_RIGHT }
};
+ProgramParser::ProgramParser():
+ module(0)
+{ }
+
+ProgramParser::~ProgramParser()
+{
+ delete module;
+}
+
Module &ProgramParser::parse(const string &s)
{
source = s;
- parse_source(main_module);
- return main_module;
+ parse_source();
+ return *module;
}
Module &ProgramParser::parse(IO::Base &io)
unsigned len = io.read(buffer, sizeof(buffer));
source.append(buffer, len);
}
- parse_source(main_module);
- return main_module;
+ parse_source();
+ return *module;
}
-void ProgramParser::parse_source(Module &module)
+void ProgramParser::parse_source()
{
- cur_module = &module;
- cur_stage = &module.shared;
+ delete module;
+ module = new Module;
+ cur_stage = &module->shared;
iter = source.begin();
while(1)
{
while(Node *statement = parse_global_declaration())
cur_stage->content.body.push_back(statement);
- cur_stage->present = !cur_stage->content.body.empty();
- Stage *prev_stage = cur_stage;
parse_token();
string token = parse_token();
if(token.empty())
break;
- else if(token=="global")
- cur_stage = &module.shared;
else if(token=="vertex")
- cur_stage = &module.vertex_stage;
+ module->stages.push_back(VERTEX);
else if(token=="geometry")
- cur_stage = &module.geometry_stage;
+ module->stages.push_back(GEOMETRY);
else if(token=="fragment")
- cur_stage = &module.fragment_stage;
+ module->stages.push_back(FRAGMENT);
else
throw runtime_error(format("Parse error at '%s': expected stage identifier", token));
- cur_stage->previous = prev_stage;
+
+ if(cur_stage->type!=SHARED)
+ module->stages.back().previous = cur_stage;
+ cur_stage = &module->stages.back();
for(; (iter!=source.end() && *iter!='\n'); ++iter) ;
}
std::string source;
std::string::const_iterator iter;
std::deque<std::string> next_tokens;
- ProgramSyntax::Module main_module;
- ProgramSyntax::Module *cur_module;
+ ProgramSyntax::Module *module;
ProgramSyntax::Stage *cur_stage;
std::set<std::string> declared_types;
static Operator operators[];
public:
+ ProgramParser();
+ ~ProgramParser();
+
ProgramSyntax::Module &parse(const std::string &);
ProgramSyntax::Module &parse(IO::Base &);
private:
- void parse_source(ProgramSyntax::Module &);
+ void parse_source();
const std::string &peek_token(unsigned = 0);
std::string parse_token();
Stage::Stage(StageType t):
type(t),
- present(false),
previous(0)
{ }
Module::Module():
- shared(SHARED),
- vertex_stage(VERTEX),
- geometry_stage(GEOMETRY),
- fragment_stage(FRAGMENT)
+ shared(SHARED)
{ }
} // namespace ProgramSyntax
struct Stage
{
StageType type;
- bool present;
Stage *previous;
ProgramSyntax::Block content;
std::map<std::string, VariableDeclaration *> in_variables;
struct Module
{
Stage shared;
- Stage vertex_stage;
- Stage geometry_stage;
- Stage fragment_stage;
+ std::list<Stage> stages;
Module();
};