X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fprogrambuilder.cpp;h=195d410fe10f7971739e9ee03448f810dd7c8235;hb=91b86d70b598193201a28c5cd6e6c4b180fda45a;hp=f8c3973f8b8feba30da190196a588d7a62b711ca;hpb=06817138c8f234e299a137fab94fb956169d21c5;p=libs%2Fgl.git diff --git a/source/programbuilder.cpp b/source/programbuilder.cpp index f8c3973f..195d410f 100644 --- a/source/programbuilder.cpp +++ b/source/programbuilder.cpp @@ -162,7 +162,7 @@ const ProgramBuilder::VariableDefinition ProgramBuilder::standard_variables[] = { NO_SCOPE, 0, 0, 0, 0 } }; -const char ProgramBuilder::interfaces[] = { 0, 0, 0, 0, 'v', 0 }; +const char ProgramBuilder::interfaces[] = { 0, 0, 0, 0, 0, 'v', 0 }; ProgramBuilder::ProgramBuilder(const StandardFeatures &f): features(f), @@ -211,6 +211,8 @@ ProgramBuilder::ProgramBuilder(const StandardFeatures &f): var.scope = VERTEX; else if(!strcmp(word, "fragment")) var.scope = FRAGMENT; + else if(!strcmp(word, "function")) + var.scope = FUNCTION; else throw invalid_variable_definition(word); } @@ -220,18 +222,29 @@ ProgramBuilder::ProgramBuilder(const StandardFeatures &f): var.name = word; start = features.custom.find_first_not_of(whitespace, word_end+1); - if(start>=decl_end) + if(start>=decl_end || (var.scope==FUNCTION && features.custom[start]=='(')) break; } if(equals!=string::npos) { + if(var.scope==FUNCTION) + throw invalid_variable_definition("function with expression"); start = features.custom.find_first_not_of(whitespace, equals+1); if(start>=semicolon) throw invalid_variable_definition("no expression"); features.custom[semicolon] = 0; var.expression = &features.custom[start]; } + else if(var.scope==FUNCTION) + { + string::size_type left_paren = features.custom.find('(', start); + string::size_type right_paren = features.custom.find(')', start); + if(left_paren>semicolon || right_paren>semicolon) + throw invalid_variable_definition("no argument list"); + features.custom[right_paren] = 0; + var.expression = &features.custom[left_paren+1]; + } else var.expression = 0; @@ -415,7 +428,13 @@ string ProgramBuilder::create_source(const list &variables, Va set declared_types; set uniform_blocks; for(list::const_iterator i=variables.begin(); i!=variables.end(); ++i) - if((*i)->variable->scope==UNIFORM && (*i)->is_referenced_from(scope) && !(*i)->inlined) + { + if(!(*i)->is_referenced_from(scope)) + continue; + + if((*i)->variable->scope==FUNCTION) + source += format("%s;\n", (*i)->create_declaration()); + else if((*i)->variable->scope==UNIFORM && !(*i)->inlined) { if((*i)->type && !declared_types.count((*i)->type)) { @@ -428,6 +447,7 @@ string ProgramBuilder::create_source(const list &variables, Va else source += format("uniform %s;\n", (*i)->create_declaration()); } + } for(set::const_iterator i=uniform_blocks.begin(); i!=uniform_blocks.end(); ++i) { @@ -921,7 +941,7 @@ void ProgramBuilder::ShaderVariable::update_reference(ShaderVariable &from, Shad void ProgramBuilder::ShaderVariable::check_inline(bool allow_legacy, bool trivial_only) { - if(variable->expression) + if(variable->expression && variable->scope>=UNIFORM) { if(array_sum && array_size>1) return; @@ -995,7 +1015,7 @@ ProgramBuilder::InterfaceFlags ProgramBuilder::ShaderVariable::get_interface_fla { /* Uniforms are available to all stages and are not passed through interfaces */ - if(variable->scope==UNIFORM) + if(variable->scope<=UNIFORM) return NO_INTERFACE; int flags = NO_INTERFACE; @@ -1035,6 +1055,9 @@ string ProgramBuilder::ShaderVariable::create_type_declaration() const string ProgramBuilder::ShaderVariable::create_declaration(char iface, bool loop) const { + if(variable->scope==FUNCTION) + return format("%s %s(%s)", variable->type, resolved_name, variable->expression); + if(variable->scope==UNIFORM && !array_subscript.empty()) { const char *bracket = strrchr(variable->type, '['); @@ -1102,10 +1125,12 @@ string ProgramBuilder::ShaderVariable::create_expression(const char *loop) const ProgramBuilder::StandardFeatures::Loader::Loader(StandardFeatures &f): DataFile::ObjectLoader(f) { + add("clipping", &StandardFeatures::clipping); add("custom", &StandardFeatures::custom); add("fog", &StandardFeatures::fog); add("lighting", &StandardFeatures::lighting); add("material", &StandardFeatures::material); + add("max_clip_planes", &StandardFeatures::max_clip_planes); add("max_lights", &StandardFeatures::max_lights); add("normalmap", &StandardFeatures::normalmap); add("reflection", &StandardFeatures::reflection);