]> git.tdb.fi Git - libs/gl.git/blob - source/technique.cpp
Add missing includes
[libs/gl.git] / source / technique.cpp
1 #include <msp/core/refptr.h>
2 #include <msp/datafile/collection.h>
3 #include <msp/strings/format.h>
4 #include "material.h"
5 #include "program.h"
6 #include "programdata.h"
7 #include "tag.h"
8 #include "technique.h"
9 #include "texture.h"
10
11 using namespace std;
12
13 namespace Msp {
14 namespace GL {
15
16 RenderPass &Technique::add_pass(const Tag &tag)
17 {
18         return insert_unique(passes, tag, RenderPass())->second;
19 }
20
21 bool Technique::has_pass(const Tag &tag) const
22 {
23         return passes.count(tag);
24 }
25
26 const RenderPass &Technique::get_pass(const Tag &tag) const
27 {
28         return get_item(passes, tag);
29 }
30
31 bool Technique::replace_texture(const string &slot, const Texture &tex)
32 {
33         bool replaced = false;
34         for(PassMap::iterator i=passes.begin(); i!=passes.end(); ++i)
35         {
36                 int index = i->second.get_texture_index(slot);
37                 if(index>=0)
38                 {
39                         i->second.set_texture(index, &tex);
40                         replaced = true;
41                 }
42         }
43
44         return replaced;
45 }
46
47 bool Technique::replace_material(const string &slot, const Material &mat)
48 {
49         bool replaced = false;
50         for(PassMap::iterator i=passes.begin(); i!=passes.end(); ++i)
51         {
52                 const string &pass_slot = i->second.get_material_slot_name();
53                 if(!pass_slot.empty() && pass_slot==slot)
54                 {
55                         i->second.set_material(&mat);
56                         replaced = true;
57                 }
58         }
59
60         return replaced;
61 }
62
63 bool Technique::has_shaders() const
64 {
65         for(PassMap::const_iterator i=passes.begin(); i!=passes.end(); ++i)
66                 if(i->second.get_shader_program())
67                         return true;
68         return false;
69 }
70
71
72 Technique::Loader::Loader(Technique &t):
73         DataFile::CollectionObjectLoader<Technique>(t, 0)
74 {
75         init();
76 }
77
78 Technique::Loader::Loader(Technique &t, Collection &c):
79         DataFile::CollectionObjectLoader<Technique>(t, &c)
80 {
81         init();
82 }
83
84 void Technique::Loader::init()
85 {
86         add("inherit", &Loader::inherit);
87         add("pass", &Loader::pass);
88 }
89
90 void Technique::Loader::inherit(const string &n)
91 {
92         obj.passes = get_collection().get<Technique>(n).get_passes();
93         InheritLoader ldr(obj, get_collection());
94         load_sub_with(ldr);
95 }
96
97 void Technique::Loader::pass(const string &n)
98 {
99         RenderPass p;
100         if(coll)
101                 load_sub(p, get_collection());
102         else
103                 load_sub(p);
104
105         insert_unique(obj.passes, n, p);
106 }
107
108
109 Technique::InheritLoader::InheritLoader(Technique &t, Collection &c):
110         DataFile::CollectionObjectLoader<Technique>(t, &c)
111 {
112         add("material", &InheritLoader::material);
113         add("texture", &InheritLoader::texture);
114 }
115
116 void Technique::InheritLoader::material(const string &slot, const string &name)
117 {
118         const Material &mat = get_collection().get<Material>(name);
119         if(obj.replace_material(slot, mat))
120                 return;
121
122         // For backwards compatibility
123         RenderPass &pass = get_item(obj.passes, slot);
124         if(const Material *base_mat = pass.get_material())
125         {
126                 for(PassMap::iterator i=obj.passes.begin(); i!=obj.passes.end(); ++i)
127                         if(i->second.get_material()==base_mat)
128                                 i->second.set_material(&mat);
129         }
130         else
131                 pass.set_material(&mat);
132 }
133
134 void Technique::InheritLoader::texture(const string &slot, const string &name)
135 {
136         if(!obj.replace_texture(slot, get_collection().get<Texture>(name)))
137                 throw key_error(slot);
138 }
139
140 } // namespace GL
141 } // namespace Msp