]> git.tdb.fi Git - libs/gl.git/commitdiff
Use layout declarations to set attribute and fragment data locations
authorMikko Rasa <tdb@tdb.fi>
Sat, 19 Nov 2016 16:24:18 +0000 (18:24 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sat, 19 Nov 2016 16:25:24 +0000 (18:25 +0200)
A fallback to glBind*Location functions is provided in case the
implementation does not support GLSL 3.30.

shaderlib/singlepass.glsl
source/programcompiler.cpp
source/programsyntax.h

index f8940f7ddfbd02ee9582d1cf45ccbc50d8e6417f..67e04e6d8fc3f05909e79c670a6a003b3ec55708 100644 (file)
@@ -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()
 {
index ece48cf06e2606219e76e6fb86bd03577a98074a..fd756de0e00cbbca4c5aa18587b251afc4e94ccb 100644 (file)
@@ -61,17 +61,20 @@ void ProgramCompiler::add_shaders(Program &program)
        for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
        {
                if(i->type==VERTEX)
+               {
                        program.attach_shader_owned(new VertexShader(apply<Formatter>(*i)));
+                       for(map<string, unsigned>::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<Formatter>(*i)));
                else if(i->type==FRAGMENT)
+               {
                        program.attach_shader_owned(new FragmentShader(apply<Formatter>(*i)));
+                       for(map<string, unsigned>::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<Layout::Qualifier>::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<unsigned>(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);
 }
index 796c4b938f10f6f84eb1fbcdcdd0c3fd9bd6f062..c502ba47a90f32701bc885e44006ff48a8d93c24 100644 (file)
@@ -355,6 +355,7 @@ struct Stage
        ProgramSyntax::Block content;
        std::map<std::string, VariableDeclaration *> in_variables;
        std::map<std::string, VariableDeclaration *> out_variables;
+       std::map<std::string, unsigned> locations;
        Version required_version;
 
        Stage(StageType);