PipelinePass &Pipeline::add_pass(const Tag &tag)
{
- if(passes.count(tag.id))
+ if(passes.count(tag))
throw KeyError("Pass already exists");
- PipelinePass &pass=passes[tag.id];
+ PipelinePass &pass=passes[tag];
pass_order.push_back(tag);
return pass;
}
PipelinePass &Pipeline::get_pass(const Tag &tag)
{
- map<unsigned, PipelinePass>::iterator i=passes.find(tag.id);
+ PassMap::iterator i=passes.find(tag);
if(i==passes.end())
throw KeyError("Unknown pass");
return i->second;
const PipelinePass &Pipeline::get_pass(const Tag &tag) const
{
- map<unsigned, PipelinePass>::const_iterator i=passes.find(tag.id);
+ PassMap::const_iterator i=passes.find(tag);
if(i==passes.end())
throw KeyError("Unknown pass");
return i->second;
class Pipeline: public Renderable
{
private:
- std::map<unsigned, PipelinePass> passes;
+ typedef std::map<Tag, PipelinePass> PassMap;
+
+ PassMap passes;
std::vector<Tag> pass_order;
std::vector<const Renderable *> renderables;
std::vector<Effect *> effects;
/* $Id$
This file is part of libmspgl
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#include "tag.h"
+namespace {
+
+template<typename T>
+inline unsigned hash(T begin, T end)
+{
+ unsigned result=0;
+ for(T i=begin; (i!=end && *i); ++i)
+ result=((result>>29)|(result<<5))^static_cast<unsigned char>(*i);
+ return result;
+}
+
+}
+
namespace Msp {
namespace GL {
Tag::Tag(const char *s):
- id(0)
-{
- for(const char *i=s; *i; ++i)
- id=id*id+*i;
-}
+ id(s ? hash<const char *>(s, 0) : 0)
+{ }
Tag::Tag(const std::string &s):
- id(0)
-{
- for(std::string::const_iterator i=s.begin(); i!=s.end(); ++i)
- id=id*id+*i;
-}
+ id(hash(s.begin(), s.end()))
+{ }
} // namespace GL
} // namespace Msp
/* $Id$
This file is part of libmspgl
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2010 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
Tag(): id(0) { }
Tag(const char *);
Tag(const std::string &s);
+
+ bool operator<(const Tag &t) const { return id<t.id; }
+ bool operator==(const Tag &t) const { return id==t.id; }
};
} // namespace GL
Technique::~Technique()
{
- for(map<unsigned, ObjectPass>::iterator i=passes.begin(); i!=passes.end(); ++i)
+ for(PassMap::iterator i=passes.begin(); i!=passes.end(); ++i)
delete i->second.shdata;
}
bool Technique::has_pass(const GL::Tag &tag) const
{
- return passes.count(tag.id);
+ return passes.count(tag);
}
const ObjectPass &Technique::get_pass(const GL::Tag &tag) const
{
- map<unsigned, ObjectPass>::const_iterator i=passes.find(tag.id);
+ PassMap::const_iterator i=passes.find(tag);
if(i==passes.end())
throw KeyError("Unknown pass");
return i->second;
void Technique::Loader::finish()
{
- for(map<unsigned, ObjectPass>::iterator i=tech.passes.begin(); i!=tech.passes.end(); ++i)
+ for(PassMap::iterator i=tech.passes.begin(); i!=tech.passes.end(); ++i)
if(i->second.shdata)
{
for(unsigned j=0; j<tech.textures.size(); ++j)
void Technique::Loader::pass(const string &n)
{
- unsigned id=Tag(n).id;
- if(tech.passes.count(id))
+ Tag tag(n);
+ if(tech.passes.count(tag))
throw KeyError("Duplicate pass name", n);
ObjectPass p;
load_sub(p, coll);
- tech.passes[id]=p;
+ tech.passes[tag]=p;
}
void Technique::Loader::shader(const string &n)
TextureSlot(): texture(0) { }
};
+ typedef std::map<Tag, ObjectPass> PassMap;
+
std::vector<TextureSlot> textures;
const Texture *main_texture;
- std::map<unsigned, ObjectPass> passes;
+ PassMap passes;
ObjectPass *normal_pass;
const Material *material;