void ProgramCompiler::compile(const string &source)
{
module = &parser.parse(source);
+ process();
}
void ProgramCompiler::compile(IO::Base &io)
{
module = &parser.parse(io);
+ process();
}
void ProgramCompiler::add_shaders(Program &program)
if(!module)
throw invalid_operation("ProgramCompiler::add_shaders");
- string global_source = "#version 150\n"+format_context(module->global_context);
+ string head = "#version 150\n";
if(module->vertex_context.present)
- program.attach_shader_owned(new VertexShader(global_source+"\n"+format_context(module->vertex_context)));
+ program.attach_shader_owned(new VertexShader(head+format_context(module->vertex_context)));
if(module->geometry_context.present)
- program.attach_shader_owned(new GeometryShader(global_source+"\n"+format_context(module->geometry_context)));
+ program.attach_shader_owned(new GeometryShader(head+format_context(module->geometry_context)));
if(module->fragment_context.present)
- program.attach_shader_owned(new FragmentShader(global_source+"\n"+format_context(module->fragment_context)));
+ program.attach_shader_owned(new FragmentShader(head+format_context(module->fragment_context)));
program.bind_attribute(VERTEX4, "vertex");
program.bind_attribute(NORMAL3, "normal");
program.bind_attribute(TEXCOORD4, "texcoord");
}
+void ProgramCompiler::process()
+{
+ if(module->vertex_context.present)
+ process(module->vertex_context);
+ if(module->geometry_context.present)
+ process(module->geometry_context);
+ if(module->fragment_context.present)
+ process(module->fragment_context);
+}
+
+void ProgramCompiler::process(Context &context)
+{
+ inject_block(context.content, module->global_context.content);
+}
+
+void ProgramCompiler::inject_block(Block &target, const Block &source)
+{
+ list<NodePtr<Node> >::iterator insert_point = target.body.begin();
+ for(list<NodePtr<Node> >::const_iterator i=source.body.begin(); i!=source.body.end(); ++i)
+ target.body.insert(insert_point, (*i)->clone());
+}
+
string ProgramCompiler::format_context(Context &context)
{
Formatter formatter;
bool change_indent = (!formatted.empty() && !else_if);
indent += change_indent;
string spaces(indent*2, ' ');
- for(vector<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); ++i)
+ for(list<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); ++i)
{
if(i!=block.body.begin())
formatted += '\n';