From b8b06a0ff96763ba7e188d9fcacbd8c0e3dcd515 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 3 Sep 2008 06:40:23 +0000 Subject: [PATCH] Require mspgbase now that Image was moved there Discard Renderable::get_order as bad design Refactor Object to render instances from an iterator range instead of list Rework Scene to make use of Object's multi-instance rendering --- Build | 1 + source/object.cpp | 37 ++++++++----------------------------- source/object.h | 16 ++++++++++++++-- source/renderable.h | 2 -- source/scene.cpp | 34 +++++++++++++++++++++++----------- source/scene.h | 12 ++++++------ 6 files changed, 52 insertions(+), 50 deletions(-) diff --git a/Build b/Build index 7d435789..46a9b2eb 100644 --- a/Build +++ b/Build @@ -8,6 +8,7 @@ package "mspgl" tar_file "License.txt"; require "mspdatafile"; + require "mspgbase"; require "opengl"; library "mspgl" diff --git a/source/object.cpp b/source/object.cpp index f710145a..78f44557 100644 --- a/source/object.cpp +++ b/source/object.cpp @@ -59,11 +59,6 @@ void Object::render(const ObjectInstance &inst, const Tag &tag) const render(get_pass(tag), &inst); } -void Object::render(const list &insts, const Tag &tag) const -{ - render(get_pass(tag), insts); -} - void Object::setup_render(const ObjectPass &pass) const { if(!meshes[0]) @@ -105,36 +100,20 @@ void Object::render(const ObjectPass &pass, const ObjectInstance *inst) const { 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 &insts) const +void Object::render_instance(const ObjectPass &pass, const ObjectInstance &inst) const { - setup_render(pass); - - for(list::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); } diff --git a/source/object.h b/source/object.h index 0039dffd..42541eaf 100644 --- a/source/object.h +++ b/source/object.h @@ -92,12 +92,24 @@ public: Each instance's hook functions will be called before and after drawing the mesh. */ - void render(const std::list &, const Tag &tag=Tag()) const; + template + 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; + + template + 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 diff --git a/source/renderable.h b/source/renderable.h index aeee1666..e96ac77a 100644 --- a/source/renderable.h +++ b/source/renderable.h @@ -17,9 +17,7 @@ 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; }; diff --git a/source/scene.cpp b/source/scene.cpp index 607166d5..59f30411 100644 --- a/source/scene.cpp +++ b/source/scene.cpp @@ -5,6 +5,8 @@ Copyright © 2007 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include "object.h" +#include "objectinstance.h" #include "scene.h" using namespace std; @@ -14,28 +16,38 @@ namespace GL { void Scene::add(const Renderable &r) { - renderables.insert(&r); + if(const ObjectInstance *oi=dynamic_cast(&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(&r)) + { + map >::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_iterator i=renderables.begin(); i!=renderables.end(); ++i) + for(map >::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_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()get_order(); - return a #include #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 renderables; + std::map > objects; + std::set renderables; public: void add(const Renderable &); -- 2.43.0