From c6aea1bc1586ffef132e6fffdf99343cb56617db Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 4 Nov 2007 22:11:27 +0000 Subject: [PATCH] Add a Tag class to identify passes Refactor the Renderable and Object interfaces a bit --- source/object.cpp | 46 ++++++++++++++------------------------- source/object.h | 31 ++++++++++++++------------ source/objectinstance.cpp | 13 ++++------- source/objectinstance.h | 5 ++--- source/renderable.h | 6 ++--- source/scene.cpp | 12 +++------- source/scene.h | 5 ++--- source/tag.cpp | 21 ++++++++++++++++++ source/tag.h | 21 ++++++++++++++++++ 9 files changed, 89 insertions(+), 71 deletions(-) create mode 100644 source/tag.cpp create mode 100644 source/tag.h diff --git a/source/object.cpp b/source/object.cpp index dba9774e..3ba2d64c 100644 --- a/source/object.cpp +++ b/source/object.cpp @@ -26,56 +26,41 @@ Object::Object(): meshes(1, static_cast(0)), material(0) { - normal_pass=&passes[""]; + normal_pass=&passes[0]; } Object::~Object() { - for(map::iterator i=passes.begin(); i!=passes.end(); ++i) + for(map::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::const_iterator i=passes.find(pn); + map::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 &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 &insts) const -{ - render(*normal_pass, insts); -} - -void Object::render(const string &pn, const list &insts) const -{ - render(get_pass(pn), insts); + render(get_pass(tag), insts); } void Object::setup_render(const ObjectPass &pass) const @@ -163,7 +148,7 @@ Object::Loader::Loader(Object &o, Collection &c): Object::Loader::~Loader() { - for(map::iterator i=obj.passes.begin(); i!=obj.passes.end(); ++i) + for(map::iterator i=obj.passes.begin(); i!=obj.passes.end(); ++i) if(i->second.shdata) { for(unsigned j=0; j meshes; std::vector textures; - std::map passes; + std::map passes; Material *material; ObjectPass *normal_pass; @@ -69,25 +69,28 @@ public: 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; - void render(const std::string &, const std::list &) 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 Tag &tag=Tag()) const; private: void setup_render(const ObjectPass &) const; void finish_render(const ObjectPass &) const; diff --git a/source/objectinstance.cpp b/source/objectinstance.cpp index 10dae392..7552cc93 100644 --- a/source/objectinstance.cpp +++ b/source/objectinstance.cpp @@ -18,19 +18,14 @@ ObjectInstance::ObjectInstance(const Object &obj): 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 diff --git a/source/objectinstance.h b/source/objectinstance.h index 459c2da3..12e0d7fb 100644 --- a/source/objectinstance.h +++ b/source/objectinstance.h @@ -34,10 +34,9 @@ public: 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. diff --git a/source/renderable.h b/source/renderable.h index b9b6b080..00b8b901 100644 --- a/source/renderable.h +++ b/source/renderable.h @@ -9,6 +9,7 @@ Distributed under the LGPL #define MSP_GL_RENDERABLE_H_ #include +#include "tag.h" namespace Msp { namespace GL { @@ -16,10 +17,9 @@ 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 diff --git a/source/scene.cpp b/source/scene.cpp index 2ef2ea78..20399daf 100644 --- a/source/scene.cpp +++ b/source/scene.cpp @@ -22,17 +22,11 @@ void Scene::remove(const Renderable &r) renderables.erase(&r); } -void Scene::render() const +void Scene::render(const Tag &tag) const { for(set::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) - (*i)->render(); -} - -void Scene::render(const string &pn) const -{ - for(set::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 diff --git a/source/scene.h b/source/scene.h index f4e12810..6bfad812 100644 --- a/source/scene.h +++ b/source/scene.h @@ -23,9 +23,8 @@ public: 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 diff --git a/source/tag.cpp b/source/tag.cpp new file mode 100644 index 00000000..c8041e0d --- /dev/null +++ b/source/tag.cpp @@ -0,0 +1,21 @@ +#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 diff --git a/source/tag.h b/source/tag.h new file mode 100644 index 00000000..87d4af65 --- /dev/null +++ b/source/tag.h @@ -0,0 +1,21 @@ +#ifndef MSP_GL_TAG_H_ +#define MSP_GL_TAG_H_ + +#include + +namespace Msp { +namespace GL { + +struct Tag +{ + unsigned id; + + Tag(): id(0) { } + Tag(const char *); + Tag(const std::string &s); +}; + +} // namespace GL +} // namespace Msp + +#endif -- 2.45.2