]> git.tdb.fi Git - libs/gl.git/blobdiff - source/materials/technique.cpp
Check the flat qualifier from the correct member
[libs/gl.git] / source / materials / technique.cpp
index 09799acee8841ac3eefe9d3fe1cfb5fa08801283..163cbec60f0003245631fca2f503a9cdfc0cea5c 100644 (file)
@@ -1,10 +1,9 @@
 #include <msp/core/refptr.h>
 #include <msp/datafile/collection.h>
+#include <msp/fs/utils.h>
 #include <msp/strings/format.h>
 #include "material.h"
-#include "program.h"
 #include "programdata.h"
-#include "tag.h"
 #include "technique.h"
 #include "texture.h"
 
@@ -13,36 +12,36 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
-RenderPass &Technique::add_pass(const Tag &tag)
+RenderMethod &Technique::add_method(Tag tag)
 {
-       return insert_unique(passes, tag, RenderPass())->second;
+       return insert_unique(methods, tag, RenderMethod())->second;
 }
 
-bool Technique::has_pass(const Tag &tag) const
+bool Technique::has_method(Tag tag) const
 {
-       return passes.count(tag);
+       return methods.count(tag);
 }
 
-const RenderPass &Technique::get_pass(const Tag &tag) const
+const RenderMethod &Technique::get_method(Tag tag) const
 {
-       return get_item(passes, tag);
+       return get_item(methods, tag);
 }
 
-const RenderPass *Technique::find_pass(const Tag &tag) const
+const RenderMethod *Technique::find_method(Tag tag) const
 {
-       PassMap::const_iterator i = passes.find(tag);
-       return (i!=passes.end() ? &i->second : 0);
+       auto i = methods.find(tag);
+       return (i!=methods.end() ? &i->second : 0);
 }
 
 bool Technique::replace_texture(const string &slot, const Texture &tex)
 {
        bool replaced = false;
-       for(PassMap::iterator i=passes.begin(); i!=passes.end(); ++i)
+       for(auto &kvp: methods)
        {
-               int index = i->second.get_texture_index(slot);
-               if(index>=0)
+               Tag tag = kvp.second.get_texture_tag(slot);
+               if(tag.id)
                {
-                       i->second.set_texture(index, &tex);
+                       kvp.second.set_texture(tag, &tex);
                        replaced = true;
                }
        }
@@ -53,12 +52,12 @@ bool Technique::replace_texture(const string &slot, const Texture &tex)
 bool Technique::replace_material(const string &slot, const Material &mat)
 {
        bool replaced = false;
-       for(PassMap::iterator i=passes.begin(); i!=passes.end(); ++i)
+       for(auto &kvp: methods)
        {
-               const string &pass_slot = i->second.get_material_slot_name();
+               const string &pass_slot = kvp.second.get_material_slot_name();
                if(!pass_slot.empty() && pass_slot==slot)
                {
-                       i->second.set_material(&mat);
+                       kvp.second.set_material(&mat);
                        replaced = true;
                }
        }
@@ -69,76 +68,81 @@ bool Technique::replace_material(const string &slot, const Material &mat)
 bool Technique::replace_uniforms(const ProgramData &shdata)
 {
        bool replaced = false;
-       const vector<string> &uniform_names = shdata.get_uniform_names();
-       for(PassMap::iterator i=passes.begin(); i!=passes.end(); ++i)
+       const vector<Tag> &uniform_tags = shdata.get_uniform_tags();
+       for(auto &kvp: methods)
        {
                RefPtr<ProgramData> new_shdata;
-               for(vector<string>::const_iterator j=uniform_names.begin(); j!=uniform_names.end(); ++j)
+               for(Tag t: uniform_tags)
                {
-                       const string &name = i->second.get_slotted_uniform_name(*j);
-                       if(name.empty())
+                       Tag tag = kvp.second.get_slotted_uniform_tag(t);
+                       if(!tag.id)
                                continue;
 
                        if(!new_shdata)
-                               new_shdata = new ProgramData(*i->second.get_shader_data());
+                       {
+                               new_shdata = new ProgramData;
+                               new_shdata->copy_uniforms(*kvp.second.get_shader_data());
+                       }
 
-                       new_shdata->uniform(name, shdata.get_uniform(*j));
+                       new_shdata->copy_uniform(shdata, tag);
                        replaced = true;
                }
 
                if(new_shdata)
-                       i->second.set_shader_program(i->second.get_shader_program(), new_shdata.get());
+                       kvp.second.set_shader_program(kvp.second.get_shader_program(), new_shdata.get());
        }
 
        return replaced;
 }
 
-bool Technique::has_shaders() const
+void Technique::set_debug_name(const string &name)
 {
-       for(PassMap::const_iterator i=passes.begin(); i!=passes.end(); ++i)
-               if(i->second.get_shader_program())
-                       return true;
-       return false;
+#ifdef DEBUG
+       for(auto &kvp: methods)
+               kvp.second.set_debug_name(format("%s [method:%s]", name, kvp.first.str()));
+#else
+       (void)name;
+#endif
 }
 
 
-Technique::Loader::Loader(Technique &t):
-       DataFile::CollectionObjectLoader<Technique>(t, 0)
-{
-       init();
-}
+DataFile::Loader::ActionMap Technique::Loader::shared_actions;
 
 Technique::Loader::Loader(Technique &t, Collection &c):
        DataFile::CollectionObjectLoader<Technique>(t, &c)
 {
-       init();
+       set_actions(shared_actions);
 }
 
-void Technique::Loader::init()
+void Technique::Loader::init_actions()
 {
        add("inherit", &Loader::inherit);
-       add("pass", &Loader::pass);
+       add("method", &Loader::method);
+}
+
+void Technique::Loader::set_inline_base_name(const string &n)
+{
+       inline_base_name = n;
 }
 
 void Technique::Loader::inherit(const string &n)
 {
-       obj.passes = get_collection().get<Technique>(n).get_passes();
+       obj.methods = get_collection().get<Technique>(n).get_methods();
        InheritLoader ldr(obj, get_collection());
        load_sub_with(ldr);
 }
 
-void Technique::Loader::pass(const string &n)
+void Technique::Loader::method(const string &n)
 {
-       RenderPass p;
-       if(coll)
-               load_sub(p, get_collection());
-       else
-               load_sub(p);
+       RenderMethod p;
+       RenderMethod::Loader ldr(p, get_collection());
+       ldr.set_inline_base_name(format("%s/%s.method", (inline_base_name.empty() ? FS::basename(get_source()) : inline_base_name), n));
+       load_sub_with(ldr);
 
        if(!p.get_shader_program())
-               throw logic_error("no shader program in pass");
+               throw logic_error("no shader program in method");
 
-       insert_unique(obj.passes, n, p);
+       insert_unique(obj.methods, n, p);
 }
 
 
@@ -157,15 +161,15 @@ void Technique::InheritLoader::material(const string &slot, const string &name)
                return;
 
        // For backwards compatibility
-       RenderPass &pass = get_item(obj.passes, slot);
-       if(const Material *base_mat = pass.get_material())
+       RenderMethod &method = get_item(obj.methods, slot);
+       if(const Material *base_mat = method.get_material())
        {
-               for(PassMap::iterator i=obj.passes.begin(); i!=obj.passes.end(); ++i)
-                       if(i->second.get_material()==base_mat)
-                               i->second.set_material(&mat);
+               for(auto &kvp: obj.methods)
+                       if(kvp.second.get_material()==base_mat)
+                               kvp.second.set_material(&mat);
        }
        else
-               pass.set_material(&mat);
+               method.set_material(&mat);
 }
 
 void Technique::InheritLoader::texture(const string &slot, const string &name)