meshes(1, static_cast<Mesh *>(0)),
material(0)
{
- normal_pass=&passes[""];
+ normal_pass=&passes[0];
}
Object::~Object()
{
- for(map<string, ObjectPass>::iterator i=passes.begin(); i!=passes.end(); ++i)
+ for(map<unsigned, ObjectPass>::iterator i=passes.begin(); i!=passes.end(); ++i)
delete i->second.shdata;
}
-bool Object::has_pass(const string &pn) const
+bool Object::has_pass(const Tag &tag) const
{
- return passes.count(pn);
+ return passes.count(tag.id);
}
-const ObjectPass &Object::get_pass(const string &pn) const
+const ObjectPass &Object::get_pass(const Tag &tag) const
{
- map<string, ObjectPass>::const_iterator i=passes.find(pn);
+ map<unsigned, ObjectPass>::const_iterator i=passes.find(tag.id);
if(i==passes.end())
throw KeyError("Unknown pass");
return i->second;
}
-void Object::render() const
+void Object::render(const Tag &tag) const
{
- render(*normal_pass, 0);
+ render(get_pass(tag), 0);
}
-void Object::render(const ObjectInstance &inst) const
+void Object::render(const ObjectInstance &inst, const Tag &tag) const
{
- render(*normal_pass, &inst);
+ render(get_pass(tag), &inst);
}
-void Object::render(const string &pn) const
+void Object::render(const list<const ObjectInstance *> &insts, const Tag &tag) const
{
- render(get_pass(pn), 0);
-}
-
-void Object::render(const string &pn, const ObjectInstance &inst) const
-{
- render(get_pass(pn), &inst);
-}
-
-void Object::render(const list<const ObjectInstance *> &insts) const
-{
- render(*normal_pass, insts);
-}
-
-void Object::render(const string &pn, const list<const ObjectInstance *> &insts) const
-{
- render(get_pass(pn), insts);
+ render(get_pass(tag), insts);
}
void Object::setup_render(const ObjectPass &pass) const
Object::Loader::~Loader()
{
- for(map<string, ObjectPass>::iterator i=obj.passes.begin(); i!=obj.passes.end(); ++i)
+ for(map<unsigned, ObjectPass>::iterator i=obj.passes.begin(); i!=obj.passes.end(); ++i)
if(i->second.shdata)
{
for(unsigned j=0; j<textures.size(); ++j)
void Object::Loader::pass(const string &n)
{
- if(obj.passes.count(n))
+ unsigned id=Tag(n).id;
+ if(obj.passes.count(id))
throw KeyError("Duplicate pass name");
ObjectPass p;
load_sub(p, coll);
- obj.passes[n]=p;
+ obj.passes[id]=p;
}
void Object::Loader::shader(const string &n)
private:
std::vector<Mesh *> meshes;
std::vector<Texture *> textures;
- std::map<std::string, ObjectPass> passes;
+ std::map<unsigned, ObjectPass> passes;
Material *material;
ObjectPass *normal_pass;
Object();
~Object();
- virtual bool has_pass(const std::string &) const;
- const ObjectPass &get_pass(const std::string &) const;
+ virtual bool has_pass(const Tag &) const;
+ const ObjectPass &get_pass(const Tag &) const;
/**
- Renders the object. If an ObjectInstance is provided, its hook functions
- are called.
+ Renders the object. A tag can be provided to render a non-default pass.
*/
- virtual void render() const;
- virtual void render(const ObjectInstance &) const;
- virtual void render(const std::string &) const;
- virtual void render(const std::string &, const ObjectInstance &) const;
+ virtual void render(const Tag &tag=Tag()) const;
/**
- Renders multiple instances of the object in one go. This may be a
- performance improvement, as the object-specific render setup only has to be
- done once.
+ Renders the object with an instance. The instance's hook functions are
+ called before and after drawing the mesh. A tag may also be given to render
+ a non-default pass.
*/
- void render(const std::list<const ObjectInstance *> &) const;
- void render(const std::string &, const std::list<const ObjectInstance *> &) const;
+ virtual void render(const ObjectInstance &, const Tag &tag=Tag()) const;
+
+ /**
+ Renders multiple instances of the object in one go. This may improve
+ performance, as the object-specific render setup only has to be done once.
+ Each instance's hook functions will be called before and after drawing the
+ mesh.
+ */
+ void render(const std::list<const ObjectInstance *> &, const Tag &tag=Tag()) const;
private:
void setup_render(const ObjectPass &) const;
void finish_render(const ObjectPass &) const;
object(obj)
{ }
-bool ObjectInstance::has_pass(const string &pn) const
+bool ObjectInstance::has_pass(const Tag &tag) const
{
- return object.has_pass(pn);
+ return object.has_pass(tag);
}
-void ObjectInstance::render() const
+void ObjectInstance::render(const Tag &tag) const
{
- object.render(*this);
-}
-
-void ObjectInstance::render(const string &pn) const
-{
- object.render(pn, *this);
+ object.render(*this, tag);
}
} // namespace GL
const Object &get_object() const { return object; }
- virtual bool has_pass(const std::string &) const;
+ virtual bool has_pass(const Tag &tag) const;
- virtual void render() const;
- virtual void render(const std::string &) const;
+ virtual void render(const Tag &tag=Tag()) const;
/**
Hook function, called from Object just before rendering the mesh.
#define MSP_GL_RENDERABLE_H_
#include <string>
+#include "tag.h"
namespace Msp {
namespace GL {
class Renderable
{
public:
- virtual bool has_pass(const std::string &pn) const =0;
+ virtual bool has_pass(const Tag &tag) const =0;
- virtual void render() const =0;
- virtual void render(const std::string &pn) const =0;
+ virtual void render(const Tag &tag=Tag()) const =0;
};
} // namespace Msp
renderables.erase(&r);
}
-void Scene::render() const
+void Scene::render(const Tag &tag) const
{
for(set<const Renderable *>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
- (*i)->render();
-}
-
-void Scene::render(const string &pn) const
-{
- for(set<const Renderable *>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
- if((*i)->has_pass(pn))
- (*i)->render(pn);
+ if((*i)->has_pass(tag))
+ (*i)->render(tag);
}
} // namespace GL
void add(const Renderable &);
void remove(const Renderable &);
- virtual bool has_pass(const std::string &) const { return true; }
- virtual void render() const;
- virtual void render(const std::string &) const;
+ virtual bool has_pass(const Tag &) const { return true; }
+ virtual void render(const Tag &tag=Tag()) const;
};
} // namespace GL
--- /dev/null
+#include "tag.h"
+
+namespace Msp {
+namespace GL {
+
+Tag::Tag(const char *s):
+ id(0)
+{
+ for(const char *i=s; *i; ++i)
+ id=id*id+*i;
+}
+
+Tag::Tag(const std::string &s):
+ id(0)
+{
+ for(std::string::const_iterator i=s.begin(); i!=s.end(); ++i)
+ id=id*id+*i;
+}
+
+} // namespace GL
+} // namespace Msp
--- /dev/null
+#ifndef MSP_GL_TAG_H_
+#define MSP_GL_TAG_H_
+
+#include <string>
+
+namespace Msp {
+namespace GL {
+
+struct Tag
+{
+ unsigned id;
+
+ Tag(): id(0) { }
+ Tag(const char *);
+ Tag(const std::string &s);
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif