X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fprogramcompiler.cpp;h=fd756de0e00cbbca4c5aa18587b251afc4e94ccb;hb=48e37a09b49cd4148db390170cfd07eef92c9d02;hp=3cb8611c0192be3d08d67798aa9c1c0d6407f09a;hpb=acec85413f86c58ff262fbc26c2c1aa8726b5c58;p=libs%2Fgl.git diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index 3cb8611c..fd756de0 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -58,21 +58,23 @@ void ProgramCompiler::add_shaders(Program &program) if(!module) throw invalid_operation("ProgramCompiler::add_shaders"); - string head = "#version 150\n"; for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) { if(i->type==VERTEX) - program.attach_shader_owned(new VertexShader(head+apply(*i))); + { + program.attach_shader_owned(new VertexShader(apply(*i))); + for(map::iterator j=i->locations.begin(); j!=i->locations.end(); ++j) + program.bind_attribute(j->second, j->first); + } else if(i->type==GEOMETRY) - program.attach_shader_owned(new GeometryShader(head+apply(*i))); + program.attach_shader_owned(new GeometryShader(apply(*i))); else if(i->type==FRAGMENT) - program.attach_shader_owned(new FragmentShader(head+apply(*i))); + { + program.attach_shader_owned(new FragmentShader(apply(*i))); + for(map::iterator j=i->locations.begin(); j!=i->locations.end(); ++j) + program.bind_fragment_data(j->second, j->first); + } } - - program.bind_attribute(VERTEX4, "vertex"); - program.bind_attribute(NORMAL3, "normal"); - program.bind_attribute(COLOR4_FLOAT, "color"); - program.bind_attribute(TEXCOORD4, "texcoord"); } Module *ProgramCompiler::create_builtins_module() @@ -124,9 +126,8 @@ void ProgramCompiler::process() void ProgramCompiler::import(const string &name) { - if(!resources) - throw runtime_error("no resources"); - RefPtr io = resources->open_raw(name+".glsl"); + string fn = name+".glsl"; + RefPtr io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn)); if(!io) throw runtime_error(format("module %s not found", name)); ProgramParser import_parser; @@ -164,6 +165,8 @@ void ProgramCompiler::generate(Stage &stage) apply(stage); apply(stage); apply(stage); + apply(stage); + apply(stage); } bool ProgramCompiler::optimize(Stage &stage) @@ -220,6 +223,14 @@ ProgramCompiler::Formatter::Formatter(): else_if(0) { } +void ProgramCompiler::Formatter::apply(ProgramSyntax::Stage &s) +{ + const Version &ver = s.required_version; + if(ver.major) + formatted += format("#version %d%d\n", ver.major, ver.minor); + Visitor::apply(s); +} + void ProgramCompiler::Formatter::visit(Literal &literal) { formatted += literal.token; @@ -295,7 +306,7 @@ void ProgramCompiler::Formatter::visit(Block &block) if(use_braces) formatted += format("%s{\n", string(brace_indent*2, ' ')); - SetForScope set(indent, indent+!formatted.empty()); + SetForScope set(indent, indent+(indent>0 || use_braces)); string spaces(indent*2, ' '); for(list >::iterator i=block.body.begin(); i!=block.body.end(); ++i) { @@ -326,7 +337,13 @@ void ProgramCompiler::Formatter::visit(Layout &layout) if(!i->value.empty()) formatted += format("=%s", i->value); } - formatted += format(") %s;", layout.interface); + formatted += ')'; +} + +void ProgramCompiler::Formatter::visit(InterfaceLayout &layout) +{ + layout.layout.visit(*this); + formatted += format(" %s;", layout.interface); } void ProgramCompiler::Formatter::visit(StructDeclaration &strct) @@ -338,6 +355,11 @@ void ProgramCompiler::Formatter::visit(StructDeclaration &strct) void ProgramCompiler::Formatter::visit(VariableDeclaration &var) { + if(var.layout) + { + var.layout->visit(*this); + formatted += ' '; + } if(var.constant) formatted += "const "; if(!var.sampling.empty()) @@ -470,6 +492,7 @@ void ProgramCompiler::DeclarationCombiner::visit(VariableDeclaration &var) VariableDeclaration *&ptr = variables[var.name]; if(ptr) { + ptr->type = var.type; if(var.init_expression) ptr->init_expression = var.init_expression; remove_node = true; @@ -1274,6 +1297,7 @@ void ProgramCompiler::NodeRemover::visit(VariableDeclaration &var) { stage->in_variables.erase(var.name); stage->out_variables.erase(var.name); + stage->locations.erase(var.name); if(var.linked_declaration) var.linked_declaration->linked_declaration = 0; } @@ -1281,5 +1305,112 @@ void ProgramCompiler::NodeRemover::visit(VariableDeclaration &var) var.init_expression = 0; } + +ProgramCompiler::LegacyConverter::LegacyConverter(): + target_version(get_glsl_version()) +{ } + +ProgramCompiler::LegacyConverter::LegacyConverter(const Version &v): + target_version(v) +{ } + +bool ProgramCompiler::LegacyConverter::check_version(const Version &feature_version) +{ + if(target_versionrequired_versionrequired_version = feature_version; + + return true; +} + +void ProgramCompiler::LegacyConverter::visit(VariableReference &var) +{ + if(var.name==frag_out_name && !check_version(Version(1, 30))) + { + var.name = "gl_FragColor"; + var.declaration = 0; + type = "vec4"; + } + else if(var.declaration) + type = var.declaration->type; + else + type = string(); +} + +void ProgramCompiler::LegacyConverter::visit(FunctionCall &call) +{ + if(call.name=="texture" && !call.declaration && !check_version(Version(1, 30))) + { + vector >::iterator i = call.arguments.begin(); + if(i!=call.arguments.end()) + { + (*i)->visit(*this); + if(type=="sampler1D") + call.name = "texture1D"; + else if(type=="sampler2D") + call.name = "texture2D"; + else if(type=="sampler3D") + call.name = "texture3D"; + else if(type=="sampler1DShadow") + call.name = "shadow1D"; + else if(type=="sampler2DShadow") + call.name = "shadow2D"; + + for(; i!=call.arguments.end(); ++i) + (*i)->visit(*this); + } + } + else + TraversingVisitor::visit(call); +} + +void ProgramCompiler::LegacyConverter::visit(VariableDeclaration &var) +{ + if(var.layout && !check_version(Version(3, 30))) + { + vector::iterator i; + for(i=var.layout->qualifiers.begin(); (i!=var.layout->qualifiers.end() && i->identifier!="location"); ++i) ; + if(i!=var.layout->qualifiers.end()) + { + unsigned location = lexical_cast(i->value); + if(stage->type==VERTEX && var.interface=="in") + { + stage->locations[var.name] = location; + var.layout->qualifiers.erase(i); + } + else if(stage->type==FRAGMENT && var.interface=="out") + { + stage->locations[var.name] = location; + var.layout->qualifiers.erase(i); + } + + if(var.layout->qualifiers.empty()) + var.layout = 0; + } + } + + if((var.interface=="in" || var.interface=="out") && !check_version(Version(1, 30))) + { + if(stage->type==VERTEX && var.interface=="in") + var.interface = "attribute"; + else if((stage->type==VERTEX && var.interface=="out") || (stage->type==FRAGMENT && var.interface=="in")) + var.interface = "varying"; + else if(stage->type==FRAGMENT && var.interface=="out") + { + frag_out_name = var.name; + remove_node = true; + } + } + + TraversingVisitor::visit(var); +} + +void ProgramCompiler::LegacyConverter::visit(InterfaceBlock &iface) +{ + if(!check_version(Version(1, 50))) + flatten_block(iface.members); +} + } // namespace GL } // namespace Msp