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<unsigned>(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 if(obj.technique && !obj.main_texture)
136 obj.main_texture=obj.technique->get_main_texture();
137 for(unsigned i=0; i<obj.textures.size(); ++i)
141 obj.textures[i]=obj.technique->get_texture(i);
143 throw Exception("Object does not specify all textures required by Technique");
148 void Object::Loader::lod_mesh(unsigned l, const string &n)
150 obj.meshes.resize(l+1, 0);
151 obj.meshes[l]=coll.get<Mesh>(n);
154 void Object::Loader::material_inline()
156 RefPtr<Material> mat=new Material;
158 coll.add(format("_%p", mat.get()), mat.get());
159 obj.material=mat.release();
162 void Object::Loader::mesh(const string &n)
164 obj.meshes[0]=coll.get<Mesh>(n);
167 void Object::Loader::shader_texture(const string &n)
170 throw InvalidState("Can't specify shader textures without a Technique");
172 string::size_type eqsign=n.find('=');
173 if(eqsign==string::npos)
174 throw InvalidParameterValue("Must specify texture slot name");
176 obj.textures[obj.technique->get_texture_index(n.substr(0, eqsign))]=coll.get<Texture>(n.substr(eqsign+1));
179 void Object::Loader::technique(const string &n)
181 obj.technique=coll.get<Technique>(n);
182 obj.textures.resize(obj.technique->get_n_textures());
183 obj.material=obj.technique->get_material();
186 void Object::Loader::texture(const string &n)
189 throw Exception("Only one main texture may be specified");
191 Texture *tex=coll.get<Texture>(n);
193 obj.textures[obj.technique->get_texture_index("texture")]=tex;
194 obj.main_texture=tex;