From 48e37a09b49cd4148db390170cfd07eef92c9d02 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 19 Nov 2016 18:24:18 +0200 Subject: [PATCH] Use layout declarations to set attribute and fragment data locations A fallback to glBind*Location functions is provided in case the implementation does not support GLSL 3.30. --- shaderlib/singlepass.glsl | 14 +++++------ source/programcompiler.cpp | 50 +++++++++++++++++++++++++++++--------- source/programsyntax.h | 1 + 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/shaderlib/singlepass.glsl b/shaderlib/singlepass.glsl index f8940f7d..67e04e6d 100644 --- a/shaderlib/singlepass.glsl +++ b/shaderlib/singlepass.glsl @@ -78,12 +78,12 @@ uniform Clipping }; ////// vertex -in vec4 vertex; -in vec4 texcoord; -in vec4 color; -in vec3 normal; -in vec3 tangent; -in vec3 binormal; +layout(location=0) in vec4 vertex; +layout(location=8) in vec4 texcoord; +layout(location=3) in vec4 color; +layout(location=2) in vec3 normal; +layout(location=4) in vec3 tangent; +layout(location=5) in vec3 binormal; vec4 get_vertex_position() { @@ -129,7 +129,7 @@ void main() } ////// fragment -out vec4 frag_color; +layout(location=0) out vec4 frag_color; vec4 get_diffuse_sample() { diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index ece48cf0..fd756de0 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -61,17 +61,20 @@ void ProgramCompiler::add_shaders(Program &program) for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) { if(i->type==VERTEX) + { 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(apply(*i))); else if(i->type==FRAGMENT) + { 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() @@ -1294,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; } @@ -1363,19 +1367,41 @@ void ProgramCompiler::LegacyConverter::visit(FunctionCall &call) void ProgramCompiler::LegacyConverter::visit(VariableDeclaration &var) { - if(var.interface=="in" || var.interface=="out") - if(!check_version(Version(1, 30))) + 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") - var.interface = "attribute"; - else if((stage->type==VERTEX && var.interface=="out") || (stage->type==FRAGMENT && var.interface=="in")) - var.interface = "varying"; + { + stage->locations[var.name] = location; + var.layout->qualifiers.erase(i); + } else if(stage->type==FRAGMENT && var.interface=="out") { - frag_out_name = var.name; - remove_node = true; + 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); } diff --git a/source/programsyntax.h b/source/programsyntax.h index 796c4b93..c502ba47 100644 --- a/source/programsyntax.h +++ b/source/programsyntax.h @@ -355,6 +355,7 @@ struct Stage ProgramSyntax::Block content; std::map in_variables; std::map out_variables; + std::map locations; Version required_version; Stage(StageType); -- 2.43.0