X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Frender%2Fobject.cpp;h=65e9a7ef083fc52db1f899906b7febaed96264a5;hp=dc1f4f3f1a7996bd55008732df21c0c826f27af5;hb=5871764de7aa23d2c40cac03ad9d07088fb57e06;hpb=7aaec9a70b8d7733429bec043f8e33e02956f266 diff --git a/source/render/object.cpp b/source/render/object.cpp index dc1f4f3f..65e9a7ef 100644 --- a/source/render/object.cpp +++ b/source/render/object.cpp @@ -1,38 +1,47 @@ #include +#include #include #include "error.h" -#include "material.h" #include "mesh.h" #include "object.h" #include "objectinstance.h" -#include "program.h" -#include "programdata.h" #include "renderer.h" #include "resourcemanager.h" #include "technique.h" -#include "texturing.h" using namespace std; namespace Msp { namespace GL { -Matrix Object::identity_matrix; +const Matrix Object::identity_matrix; Object::Object(): - lods(1), - lod0_watched(false) + lods(1) { } Object::Object(const Mesh *m, const Technique *t): - lods(1), - lod0_watched(false) + Object() { set_mesh(m); set_technique(t); } -// TODO should have copy-c'tor to set watch on lod0 mesh if necessary +Object::Object(const Object &other): + lods(other.lods), + bounding_sphere(other.bounding_sphere) +{ + if(other.lod0_watched) + watch_lod0(); +} + +Object::Object(Object &&other): + lods(move(other.lods)), + bounding_sphere(move(other.bounding_sphere)) +{ + if(other.lod0_watched) + watch_lod0(); +} Object::~Object() { @@ -56,33 +65,37 @@ Object::LevelOfDetail &Object::get_lod(unsigned i, const char *caller) void Object::set_mesh(unsigned i, const Mesh *m) { - RefPtr &ptr = get_lod(i, "Object::set_mesh").mesh; + const Mesh *&ptr = get_lod(i, "Object::set_mesh").mesh; if(i==0 && ptr && lod0_watched) if(ResourceManager *rm = ptr->get_manager()) rm->unobserve_resource(*ptr, *this); ptr = m; - ptr.keep(); lod0_watched = false; if(i==0 && m) - if(ResourceManager *rm = m->get_manager()) - { - rm->observe_resource(*m, *this); - lod0_watched = true; - } + watch_lod0(); update_bounding_sphere(); } +void Object::watch_lod0() +{ + if(ResourceManager *rm = lods[0].mesh->get_manager()) + { + rm->observe_resource(*lods[0].mesh, *this); + lod0_watched = true; + } +} + void Object::update_bounding_sphere() { vector points; - for(vector::const_iterator i=lods.begin(); i!=lods.end(); ++i) + for(const LevelOfDetail &l: lods) { - if(!i->mesh || !i->mesh->is_loaded()) + if(!l.mesh || !l.mesh->is_loaded()) continue; - const VertexArray &vertices = i->mesh->get_vertices(); + const VertexArray &vertices = l.mesh->get_vertices(); int offset = vertices.get_format().offset(VERTEX3); bool three = true; @@ -98,8 +111,8 @@ void Object::update_bounding_sphere() points.reserve(points.size()+n_vertices); for(unsigned j=0; j(vertices[j]+offset); + points.emplace_back(v[0], v[1], (three ? v[2] : 0.0f)); } } @@ -116,14 +129,12 @@ const Mesh *Object::get_mesh(unsigned i) const if(i>=lods.size()) return 0; - return lods[i].mesh.get(); + return lods[i].mesh; } void Object::set_technique(unsigned i, const Technique *t) { - RefPtr &ptr = get_lod(i, "Object::set_technique").technique; - ptr = t; - ptr.keep(); + get_lod(i, "Object::set_technique").technique = t; } const Technique *Object::get_technique(unsigned i) const @@ -131,40 +142,40 @@ const Technique *Object::get_technique(unsigned i) const if(i>=lods.size()) return 0; - return lods[i].technique.get(); + return lods[i].technique; } -void Object::render(Renderer &renderer, const Tag &tag) const +void Object::render(Renderer &renderer, Tag tag) const { - const RenderPass *pass = get_pass(tag, 0); - if(!pass) + const RenderMethod *method = get_method(tag, 0); + if(!method) return; - const Mesh *mesh = lods.front().mesh.get(); + const Mesh *mesh = lods.front().mesh; if (!mesh) throw logic_error("no mesh"); Renderer::Push push(renderer); - pass->apply(renderer); + method->apply(renderer); setup_render(renderer, tag); mesh->draw(renderer); finish_render(renderer, tag); } -void Object::render(Renderer &renderer, const ObjectInstance &inst, const Tag &tag) const +void Object::render(Renderer &renderer, const ObjectInstance &inst, Tag tag) const { unsigned lod = min(inst.get_level_of_detail(renderer), lods.size()-1); - const RenderPass *pass = get_pass(tag, lod); - if(!pass) + const RenderMethod *method = get_method(tag, lod); + if(!method) return; - const Mesh *mesh = lods[lod].mesh.get(); + const Mesh *mesh = lods[lod].mesh; if (!mesh) throw logic_error("no mesh"); Renderer::Push push(renderer); - pass->apply(renderer); + method->apply(renderer); setup_render(renderer, tag); inst.setup_render(renderer, tag); @@ -173,40 +184,29 @@ void Object::render(Renderer &renderer, const ObjectInstance &inst, const Tag &t finish_render(renderer, tag); } -const RenderPass *Object::get_pass(const Tag &tag, unsigned lod) const +const RenderMethod *Object::get_method(Tag tag, unsigned lod) const { - const Technique *tech = lods[lod].technique.get(); + const Technique *tech = lods[lod].technique; if(!tech) throw logic_error("no technique"); - return tech->find_pass(tag); + return tech->find_method(tag); } void Object::resource_loaded(Resource &res) { - if(&res==lods.front().mesh.get() && bounding_sphere.is_empty()) + if(&res==lods.front().mesh && bounding_sphere.is_empty()) update_bounding_sphere(); } void Object::resource_removed(Resource &res) { - if(&res==lods.front().mesh.get()) + if(&res==lods.front().mesh) lod0_watched = false; } -Object::Loader::Loader(Object &o): - LodLoader(o, 0, 0) -{ - init(); -} - Object::Loader::Loader(Object &o, Collection &c): - LodLoader(o, 0, &c) -{ - init(); -} - -void Object::Loader::init() + LodLoader(o, 0, c) { add("bounding_sphere_hint", &Loader::bounding_sphere_hint); add("level_of_detail", &Loader::level_of_detail); @@ -224,13 +224,13 @@ void Object::Loader::bounding_sphere_hint(float x, float y, float z, float r) void Object::Loader::level_of_detail(unsigned i) { - LodLoader ldr(obj, i, coll); + LodLoader ldr(obj, i, get_collection()); load_sub_with(ldr); } -Object::LodLoader::LodLoader(Object &o, unsigned i, Collection *c): - DataFile::CollectionObjectLoader(o, c), +Object::LodLoader::LodLoader(Object &o, unsigned i, Collection &c): + DataFile::CollectionObjectLoader(o, &c), index(i), lod(obj.get_lod(index, "Object::LodLoader::LodLoader")) { @@ -249,10 +249,11 @@ void Object::LodLoader::mesh_inline() { RefPtr msh = new Mesh; load_sub(*msh); - lod.mesh = msh; + get_collection().add(format("%s/lod%d.mesh", FS::basename(get_source()), index), msh.get()); + lod.mesh = msh.release(); } -void Object::LodLoader::technique(const std::string &n) +void Object::LodLoader::technique(const string &n) { obj.set_technique(index, &get_collection().get(n)); } @@ -260,11 +261,12 @@ void Object::LodLoader::technique(const std::string &n) void Object::LodLoader::technique_inline() { RefPtr tech = new Technique; - if(coll) - load_sub(*tech, get_collection()); - else - load_sub(*tech); - lod.technique = tech; + Technique::Loader ldr(*tech, get_collection()); + string name = format("%s/lod%d.tech", FS::basename(get_source()), index); + ldr.set_inline_base_name(name); + load_sub(*tech, get_collection()); + get_collection().add(name, tech.get()); + lod.technique = tech.release(); } } // namespace GL