]> git.tdb.fi Git - libs/gl.git/blobdiff - source/programcompiler.cpp
Inject the global context to the syntax tree
[libs/gl.git] / source / programcompiler.cpp
index 1914831289a9dde32c77892cb3bfdc5411fd4900..1da80bab07871f02befd3a2cc960b22ab1ebd486 100644 (file)
@@ -19,11 +19,13 @@ ProgramCompiler::ProgramCompiler():
 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)
@@ -31,13 +33,13 @@ 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");
@@ -45,6 +47,28 @@ void ProgramCompiler::add_shaders(Program &program)
        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;
@@ -135,7 +159,7 @@ void ProgramCompiler::Formatter::visit(Block &block)
        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';