X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fprogramcompiler.cpp;h=d65869316423d64806a23bdf3e60254d0f014ce7;hp=3cb8611c0192be3d08d67798aa9c1c0d6407f09a;hb=74bd3813b9744550c9ac5980588e561835b616d9;hpb=acec85413f86c58ff262fbc26c2c1aa8726b5c58 diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index 3cb8611c..d6586931 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -58,15 +58,14 @@ 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))); 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))); } program.bind_attribute(VERTEX4, "vertex"); @@ -164,6 +163,8 @@ void ProgramCompiler::generate(Stage &stage) apply(stage); apply(stage); apply(stage); + apply(stage); + apply(stage); } bool ProgramCompiler::optimize(Stage &stage) @@ -220,6 +221,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 +304,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) { @@ -1281,5 +1290,90 @@ 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.interface=="in" || var.interface=="out") + if(!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