tar_file "License.txt";
require "mspdatafile";
+ require "mspgbase";
require "opengl";
library "mspgl"
render(get_pass(tag), &inst);
}
-void Object::render(const list<const ObjectInstance *> &insts, const Tag &tag) const
-{
- render(get_pass(tag), insts);
-}
-
void Object::setup_render(const ObjectPass &pass) const
{
if(!meshes[0])
{
setup_render(pass);
- unsigned lod=0;
- if(inst)
- {
- inst->setup_render(pass);
- lod=min(inst->get_level_of_detail(), meshes.size()-1);
- }
-
- meshes[lod]->draw();
-
if(inst)
- inst->finish_render(pass);
+ render_instance(pass, *inst);
+ else
+ meshes[0]->draw();
finish_render(pass);
}
-void Object::render(const ObjectPass &pass, const list<const ObjectInstance *> &insts) const
+void Object::render_instance(const ObjectPass &pass, const ObjectInstance &inst) const
{
- setup_render(pass);
-
- for(list<const ObjectInstance *>::const_iterator i=insts.begin(); i!=insts.end(); ++i)
- {
- (*i)->setup_render(pass);
-
- unsigned lod=min((*i)->get_level_of_detail(), meshes.size()-1);
- meshes[lod]->draw();
-
- (*i)->finish_render(pass);
- }
-
- finish_render(pass);
+ inst.setup_render(pass);
+ unsigned lod=min(inst.get_level_of_detail(), meshes.size()-1);
+ meshes[lod]->draw();
+ inst.finish_render(pass);
}
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;
+ template<typename Iter>
+ void render(Iter begin, Iter end, const Tag &tag=Tag()) const
+ { render(get_pass(tag), begin, end); }
private:
void setup_render(const ObjectPass &) const;
void finish_render(const ObjectPass &) const;
void render(const ObjectPass &, const ObjectInstance *) const;
- void render(const ObjectPass &, const std::list<const ObjectInstance *> &) const;
+
+ template<typename Iter>
+ void render(const ObjectPass &pass, Iter begin, Iter end) const
+ {
+ setup_render(pass);
+ for(Iter i=begin; i!=end; ++i)
+ render_instance(pass, **i);
+ finish_render(pass);
+ }
+
+ void render_instance(const ObjectPass &, const ObjectInstance &) const;
};
} // namespace GL
class Renderable
{
public:
- virtual int get_order() const { return 0; }
virtual bool has_pass(const Tag &tag) const =0;
-
virtual void render(const Tag &tag=Tag()) const =0;
};
Distributed under the LGPL
*/
+#include "object.h"
+#include "objectinstance.h"
#include "scene.h"
using namespace std;
void Scene::add(const Renderable &r)
{
- renderables.insert(&r);
+ if(const ObjectInstance *oi=dynamic_cast<const ObjectInstance *>(&r))
+ objects[&oi->get_object()].insert(oi);
+ else
+ renderables.insert(&r);
}
void Scene::remove(const Renderable &r)
{
- renderables.erase(&r);
+ if(const ObjectInstance *oi=dynamic_cast<const ObjectInstance *>(&r))
+ {
+ map<const Object *, set<const ObjectInstance *> >::iterator i=objects.find(&oi->get_object());
+ if(i!=objects.end())
+ {
+ i->second.erase(oi);
+ if(i->second.empty())
+ objects.erase(i);
+ }
+ }
+ else
+ renderables.erase(&r);
}
void Scene::render(const Tag &tag) const
{
- for(set<const Renderable *, Compare>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
+ for(map<const Object *, set<const ObjectInstance *> >::const_iterator i=objects.begin(); i!=objects.end(); ++i)
+ if(i->first->has_pass(tag))
+ i->first->render(i->second.begin(), i->second.end(), tag);
+
+ for(set<const Renderable *>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
if((*i)->has_pass(tag))
(*i)->render(tag);
}
-
-bool Scene::Compare::operator()(const Renderable *a, const Renderable *b) const
-{
- if(a->get_order()!=b->get_order())
- return a->get_order()<b->get_order();
- return a<b;
-}
-
} // namespace GL
} // namespace Msp
#ifndef MSP_GL_SCENE_H_
#define MSP_GL_SCENE_H_
+#include <map>
#include <set>
#include "renderable.h"
namespace Msp {
namespace GL {
+class Object;
+class ObjectInstance;
+
class Scene: public Renderable
{
private:
- struct Compare
- {
- bool operator()(const Renderable *, const Renderable *) const;
- };
-
- std::set<const Renderable *, Compare> renderables;
+ std::map<const Object *, std::set<const ObjectInstance *> > objects;
+ std::set<const Renderable *> renderables;
public:
void add(const Renderable &);