3 This file is part of libmspgl
4 Copyright © 2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
8 #include <msp/strings/formatter.h>
13 #include "objectinstance.h"
14 #include "objectpass.h"
16 #include "programdata.h"
17 #include "technique.h"
27 meshes(1, static_cast<Mesh *>(0)),
37 bool Object::has_pass(const Tag &tag) const
40 return technique->has_pass(tag);
45 void Object::render(const Tag &tag) const
47 const ObjectPass *pass=get_pass(tag);
53 void Object::render(const ObjectInstance &inst, const Tag &tag) const
55 const ObjectPass *pass=get_pass(tag);
57 render_instance(inst, tag);
62 const ObjectPass *Object::get_pass(const Tag &tag) const
65 return &technique->get_pass(tag);
68 throw KeyError("Unknown pass");
71 void Object::setup_render(const ObjectPass *pass) const
74 throw InvalidState("Trying to render Object without mesh");
76 if(pass && pass->shprog)
79 pass->shdata->apply();
80 for(unsigned i=0; i<textures.size(); ++i)
86 else if(main_texture && (!pass || pass->use_textures))
93 void Object::finish_render(const ObjectPass *pass) const
95 if(pass && pass->shprog)
98 for(unsigned i=textures.size(); i--;)
100 TexUnit::activate(i);
104 else if(main_texture)
111 void Object::render_instance(const ObjectInstance &inst, const Tag &tag) const
113 inst.setup_render(tag);
114 unsigned lod=min(inst.get_level_of_detail(), meshes.size()-1);
116 inst.finish_render(tag);
120 Object::Loader::Loader(Object &o, Collection &c):
124 add("lod_mesh", &Loader::lod_mesh);
125 add("material", &Object::material);
126 add("material_inline", &Loader::material_inline);
127 add("mesh", &Loader::mesh);
128 add("shader_texture", &Loader::shader_texture);
129 add("technique", &Loader::technique);
130 add("texture", &Loader::texture);
133 void Object::Loader::finish()
135 for(unsigned i=0; i<obj.textures.size(); ++i)
139 obj.textures[i]=obj.technique->get_texture(i);
141 throw Exception("Object does not specify all textures required by Technique");
146 void Object::Loader::lod_mesh(unsigned l, const string &n)
148 obj.meshes.resize(l+1, 0);
149 obj.meshes[l]=coll.get<Mesh>(n);
152 void Object::Loader::material_inline()
154 RefPtr<Material> mat=new Material;
156 coll.add(format("_%p", mat.get()), mat.get());
157 obj.material=mat.release();
160 void Object::Loader::mesh(const string &n)
162 obj.meshes[0]=coll.get<Mesh>(n);
165 void Object::Loader::shader_texture(const string &n)
168 throw InvalidState("Can't specify shader textures without a Technique");
170 unsigned eqsign=n.find('=');
171 if(eqsign==string::npos)
172 throw InvalidParameterValue("Must specify texture slot name");
174 obj.textures[obj.technique->get_texture_index(n.substr(0, eqsign))]=coll.get<Texture>(n.substr(eqsign+1));
177 void Object::Loader::technique(const string &n)
179 obj.technique=coll.get<Technique>(n);
180 obj.textures.resize(obj.technique->get_n_textures());
181 obj.material=obj.technique->get_material();
184 void Object::Loader::texture(const string &n)
187 throw Exception("Only one main texture may be specified");
189 Texture *tex=coll.get<Texture>(n);
191 obj.textures[obj.technique->get_texture_index("texture")]=tex;
192 obj.main_texture=tex;