From: Mikko Rasa Date: Sun, 9 May 2021 10:53:13 +0000 (+0300) Subject: Add inline data items to the collection X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=3ac3a51c623271da815c8ee60c484445871753bf Add inline data items to the collection This simplifies the internals of various objects and does away with the special keep() semantic of RefPtr. Blend and DepthTest will be handled separately as part of rendering state rework. --- diff --git a/source/animation/animation.cpp b/source/animation/animation.cpp index a8d9e969..b62f5dd9 100644 --- a/source/animation/animation.cpp +++ b/source/animation/animation.cpp @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include #include "animation.h" #include "animationeventobserver.h" #include "armature.h" @@ -20,6 +22,9 @@ Animation::Animation(): Animation::~Animation() { + for(vector::iterator i=keyframes.begin(); i!=keyframes.end(); ++i) + if(i->owned) + delete i->keyframe; for(vector::iterator i=curves.begin(); i!=curves.end(); ++i) delete *i; } @@ -155,9 +160,8 @@ void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame *kf, bool TimedKeyFrame tkf; tkf.time = t; tkf.keyframe = kf; - if(!owned) - tkf.keyframe.keep(); tkf.control = c; + tkf.owned = owned; keyframes.push_back(tkf); @@ -553,7 +557,11 @@ void Animation::Loader::load_kf_inline(bool c) { RefPtr kf = new KeyFrame; if(coll) - load_sub(*kf, get_collection()); + { + KeyFrame::Loader ldr(*kf, get_collection()); + ldr.set_inline_base_name(format("%s/%d.kframe", FS::basename(get_source()), obj.keyframes.size())); + load_sub_with(ldr); + } else load_sub(*kf); diff --git a/source/animation/animation.h b/source/animation/animation.h index 6845d23e..3d247cf5 100644 --- a/source/animation/animation.h +++ b/source/animation/animation.h @@ -121,8 +121,9 @@ private: struct TimedKeyFrame { Time::TimeDelta time; - RefPtr keyframe; + const KeyFrame *keyframe; bool control; + bool owned; }; struct Event diff --git a/source/animation/keyframe.cpp b/source/animation/keyframe.cpp index f610de2d..6cb8ce6a 100644 --- a/source/animation/keyframe.cpp +++ b/source/animation/keyframe.cpp @@ -1,4 +1,5 @@ #include +#include #include "keyframe.h" #include "pose.h" @@ -33,7 +34,6 @@ void KeyFrame::set_uniform(const string &n, const AnimatedUniform &u) void KeyFrame::set_pose(const Pose &p) { pose = &p; - pose.keep(); } @@ -73,17 +73,22 @@ void KeyFrame::Loader::init() add("scaling", &Loader::scaling); } +void KeyFrame::Loader::set_inline_base_name(const string &n) +{ + inline_base_name = n; +} + void KeyFrame::Loader::pose(const string &n) { obj.pose = &get_collection().get(n); - obj.pose.keep(); } void KeyFrame::Loader::pose_inline() { RefPtr p = new Pose; load_sub(*p, get_collection()); - obj.pose = p; + get_collection().add((inline_base_name.empty() ? FS::basename(get_source()) : inline_base_name)+".pose", p.get()); + obj.pose = p.release(); } void KeyFrame::Loader::position(float x, float y, float z) diff --git a/source/animation/keyframe.h b/source/animation/keyframe.h index 5b748add..7a96447e 100644 --- a/source/animation/keyframe.h +++ b/source/animation/keyframe.h @@ -19,12 +19,19 @@ class KeyFrame public: class Loader: public DataFile::CollectionObjectLoader { + private: + std::string inline_base_name; + public: Loader(KeyFrame &); Loader(KeyFrame &, Collection &); private: void init(); + public: + void set_inline_base_name(const std::string &); + + private: void pose(const std::string &); void pose_inline(); void position(float, float, float); @@ -60,7 +67,7 @@ public: private: Transform transform; UniformMap uniforms; - RefPtr pose; + const Pose *pose; public: KeyFrame(); @@ -73,7 +80,7 @@ public: const Transform &get_transform() const { return transform; } Matrix get_matrix() const { return transform.to_matrix(); } const UniformMap &get_uniforms() const { return uniforms; } - const Pose *get_pose() const { return pose.get(); } + const Pose *get_pose() const { return pose; } }; } // namespace GL diff --git a/source/builders/font.cpp b/source/builders/font.cpp index 5990c57d..7281bf41 100644 --- a/source/builders/font.cpp +++ b/source/builders/font.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "bindable.h" #include "gl.h" #include "font.h" @@ -26,7 +27,6 @@ Font::~Font() void Font::set_texture(const Texture2D &t) { texture = &t; - texture.keep(); } const Texture2D &Font::get_texture() const @@ -193,13 +193,13 @@ void Font::Loader::texture() { RefPtr tex = new Texture2D; load_sub(*tex); - obj.texture = tex; + get_collection().add(FS::basename(get_source())+".tex2d", tex.get()); + obj.texture = tex.release(); } void Font::Loader::texture_ref(const string &name) { obj.texture = &get_collection().get(name); - obj.texture.keep(); } diff --git a/source/builders/font.h b/source/builders/font.h index 9f040dc9..18c225c1 100644 --- a/source/builders/font.h +++ b/source/builders/font.h @@ -60,7 +60,7 @@ private: typedef std::map KerningMap; typedef std::map LigatureMap; - RefPtr texture; + const Texture2D *texture; float native_size; float ascent; float descent; diff --git a/source/builders/sequencebuilder.cpp b/source/builders/sequencebuilder.cpp index c45d0cc6..317b6884 100644 --- a/source/builders/sequencebuilder.cpp +++ b/source/builders/sequencebuilder.cpp @@ -53,7 +53,7 @@ void SequenceBuilder::build(Sequence &sequence) const Sequence::Step &step = sequence.add_step(i->tag, *renderable); step.set_blend(i->blend.get()); step.set_depth_test(i->depth_test.get()); - step.set_lighting(i->lighting.get()); + step.set_lighting(i->lighting); } const SequenceTemplate::PostProcessorArray &postprocs = tmpl.get_postprocessors(); diff --git a/source/builders/sequencetemplate.cpp b/source/builders/sequencetemplate.cpp index d8526433..3ad97313 100644 --- a/source/builders/sequencetemplate.cpp +++ b/source/builders/sequencetemplate.cpp @@ -113,7 +113,11 @@ void SequenceTemplate::Loader::step_with_slot(const string &tag, const string &r stp.tag = tag; stp.slot_name = rend; if(coll) - load_sub(stp, *coll); + { + Step::Loader ldr(stp, *coll); + ldr.set_inline_base_name(format("%s/%d.step", get_source(), obj.steps.size())); + load_sub_with(ldr); + } else load_sub(stp); @@ -145,6 +149,11 @@ void SequenceTemplate::Step::Loader::init() add("scene", &Loader::scene); } +void SequenceTemplate::Step::Loader::set_inline_base_name(const string &n) +{ + inline_base_name = n; +} + void SequenceTemplate::Step::Loader::blend_predefined(const string &name) { const Blend *bln = 0; @@ -187,13 +196,13 @@ void SequenceTemplate::Step::Loader::lighting_inline() { RefPtr lightn = new Lighting; load_sub(*lightn); - obj.lighting = lightn; + get_collection().add(inline_base_name+".lightn", lightn.get()); + obj.lighting = lightn.release(); } void SequenceTemplate::Step::Loader::lighting(const string &name) { obj.lighting = &get_collection().get(name); - obj.lighting.keep(); } void SequenceTemplate::Step::Loader::object(const string &name) diff --git a/source/builders/sequencetemplate.h b/source/builders/sequencetemplate.h index 4c195a00..32736d8e 100644 --- a/source/builders/sequencetemplate.h +++ b/source/builders/sequencetemplate.h @@ -64,12 +64,19 @@ public: { class Loader: public DataFile::CollectionObjectLoader { + private: + std::string inline_base_name; + public: Loader(Step &); Loader(Step &, Collection &); private: void init(); + public: + void set_inline_base_name(const std::string &); + + private: void blend(BlendFactor, BlendFactor); void blend_predefined(const std::string &); void depth_test(Predicate); @@ -81,7 +88,7 @@ public: }; std::string tag; - RefPtr lighting; + const Lighting *lighting; RefPtr depth_test; RefPtr blend; std::string slot_name; diff --git a/source/materials/lighting.cpp b/source/materials/lighting.cpp index 3bbc01a3..699aabc0 100644 --- a/source/materials/lighting.cpp +++ b/source/materials/lighting.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "error.h" #include "light.h" #include "lighting.h" @@ -21,12 +22,6 @@ Lighting::Lighting(): set_fog_density(0.0f); } -Lighting::~Lighting() -{ - for(vector::iterator i=owned_data.begin(); i!=owned_data.end(); ++i) - delete *i; -} - void Lighting::set_ambient(const Color &a) { ambient = a; @@ -200,8 +195,8 @@ void Lighting::Loader::light_inline() { RefPtr lgt = new Light; load_sub(*lgt); - obj.attach(*lgt); - obj.owned_data.push_back(lgt.release()); + get_collection().add(format("%s/%d.light", FS::basename(get_source()), obj.lights.size()), lgt.get()); + obj.attach(*lgt.release()); } void Lighting::Loader::light_inline_index(unsigned) diff --git a/source/materials/lighting.h b/source/materials/lighting.h index a2f84c32..9fe37ca6 100644 --- a/source/materials/lighting.h +++ b/source/materials/lighting.h @@ -59,12 +59,10 @@ private: Color fog_color; float fog_density; std::vector lights; - std::vector owned_data; mutable ProgramData shdata; public: Lighting(); - ~Lighting(); /** Sets the ambient lighting color. Affects all surfaces in the scene. */ void set_ambient(const Color &); diff --git a/source/materials/renderpass.cpp b/source/materials/renderpass.cpp index 6e33b5d1..62056ff9 100644 --- a/source/materials/renderpass.cpp +++ b/source/materials/renderpass.cpp @@ -46,10 +46,9 @@ void RenderPass::maybe_create_material_shader() extra_spec["use_image_based_lighting"] = true; shprog = material->create_compatible_shader(extra_spec); - shprog.keep(); if(shdata) - shdata = new ProgramData(*shdata, shprog.get()); + shdata = new ProgramData(*shdata, shprog); shprog_from_material = true; } @@ -57,7 +56,6 @@ void RenderPass::maybe_create_material_shader() void RenderPass::set_shader_program(const Program *prog, const ProgramData *data) { shprog = prog; - shprog.keep(); shprog_from_material = false; shdata = (data ? new ProgramData(*data) : 0); } @@ -73,7 +71,6 @@ Tag RenderPass::get_slotted_uniform_tag(Tag slot) const void RenderPass::set_material(const Material *mat) { material = mat; - material.keep(); maybe_create_material_shader(); set_material_textures(); } @@ -142,8 +139,8 @@ void RenderPass::apply(Renderer &renderer) const { for(vector::const_iterator i=textures.begin(); i!=textures.end(); ++i) renderer.set_texture(i->tag, i->texture, i->sampler); - renderer.set_material(material.get()); - renderer.set_shader_program(shprog.get(), shdata.get()); + renderer.set_material(material); + renderer.set_shader_program(shprog, shdata.get()); renderer.set_reverse_winding(back_faces); } @@ -192,6 +189,11 @@ void RenderPass::Loader::init_actions() add("texunit", &Loader::texunit_named); } +void RenderPass::Loader::set_inline_base_name(const string &n) +{ + inline_base_name = n; +} + void RenderPass::Loader::finish() { if(obj.material) @@ -213,24 +215,24 @@ void RenderPass::Loader::material_inline() { Material::GenericLoader ldr(coll); load_sub_with(ldr); - obj.material = ldr.get_material(); + RefPtr mat = ldr.get_material(); + get_collection().add(inline_base_name+".mat", mat.get()); + obj.material = mat.release(); obj.set_material_textures(); } void RenderPass::Loader::material(const string &name) { obj.material = &get_collection().get(name); - obj.material.keep(); obj.set_material_textures(); } void RenderPass::Loader::shader(const string &n) { obj.shprog = &get_collection().get(get_shader_name(n)); - obj.shprog.keep(); obj.shprog_from_material = false; if(obj.shdata) - obj.shdata = new ProgramData(*obj.shdata, obj.shprog.get()); + obj.shdata = new ProgramData(*obj.shdata, obj.shprog); } void RenderPass::Loader::texture(const string &n) @@ -280,7 +282,7 @@ void RenderPass::Loader::uniforms() if(!obj.shprog || obj.shprog_from_material) throw runtime_error("Shader is required for uniforms"); if(!obj.shdata) - obj.shdata = new ProgramData(obj.shprog.get()); + obj.shdata = new ProgramData(obj.shprog); else if(obj.shdata.refcount()>1) obj.shdata = new ProgramData(*obj.shdata); load_sub(*obj.shdata); diff --git a/source/materials/renderpass.h b/source/materials/renderpass.h index de04461a..d149a7d0 100644 --- a/source/materials/renderpass.h +++ b/source/materials/renderpass.h @@ -25,14 +25,20 @@ public: class Loader: public DataFile::CollectionObjectLoader { private: + std::string inline_base_name; + static ActionMap shared_actions; public: Loader(RenderPass &); Loader(RenderPass &, Collection &); - private: virtual void init_actions(); + + public: + void set_inline_base_name(const std::string &); + + private: virtual void finish(); static std::string get_shader_name(const std::string &); @@ -71,11 +77,11 @@ private: TextureSlot(Tag t): tag(t), texture(0), sampler(0) { } }; - RefPtr shprog; + const Program *shprog; bool shprog_from_material; RefPtr shdata; std::map uniform_slots; - RefPtr material; + const Material *material; std::string material_slot; std::vector textures; bool back_faces; @@ -91,11 +97,11 @@ private: public: void set_shader_program(const Program *, const ProgramData *); - const Program *get_shader_program() const { return shprog.get(); } + const Program *get_shader_program() const { return shprog; } const ProgramData *get_shader_data() const { return shdata.get(); } Tag get_slotted_uniform_tag(Tag) const; void set_material(const Material *); - const Material *get_material() const { return material.get(); } + const Material *get_material() const { return material; } const std::string &get_material_slot_name() const { return material_slot; } void set_texture(Tag, const Texture *, const Sampler * = 0); Tag get_texture_tag(const std::string &) const; diff --git a/source/materials/technique.cpp b/source/materials/technique.cpp index b5ed6447..26a70a01 100644 --- a/source/materials/technique.cpp +++ b/source/materials/technique.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "material.h" #include "program.h" @@ -132,6 +133,11 @@ void Technique::Loader::init_actions() add("pass", &Loader::pass); } +void Technique::Loader::set_inline_base_name(const string &n) +{ + inline_base_name = n; +} + void Technique::Loader::inherit(const string &n) { obj.passes = get_collection().get(n).get_passes(); @@ -143,7 +149,11 @@ void Technique::Loader::pass(const string &n) { RenderPass p; if(coll) - load_sub(p, get_collection()); + { + RenderPass::Loader ldr(p, get_collection()); + ldr.set_inline_base_name(format("%s/%s.pass", (inline_base_name.empty() ? FS::basename(get_source()) : inline_base_name), n)); + load_sub_with(ldr); + } else load_sub(p); diff --git a/source/materials/technique.h b/source/materials/technique.h index 47a307c9..a7999c0c 100644 --- a/source/materials/technique.h +++ b/source/materials/technique.h @@ -19,15 +19,20 @@ public: class Loader: public Msp::DataFile::CollectionObjectLoader { private: + std::string inline_base_name; + static ActionMap shared_actions; public: Loader(Technique &); Loader(Technique &, Collection &); - private: virtual void init_actions(); + public: + void set_inline_base_name(const std::string &); + + private: void inherit(const std::string &); void pass(const std::string &); }; diff --git a/source/render/object.cpp b/source/render/object.cpp index 702faaf9..caad3a07 100644 --- a/source/render/object.cpp +++ b/source/render/object.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "error.h" #include "material.h" @@ -56,12 +57,11 @@ 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) @@ -116,14 +116,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,7 +129,7 @@ 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, Tag tag) const @@ -140,7 +138,7 @@ void Object::render(Renderer &renderer, Tag tag) const if(!pass) return; - const Mesh *mesh = lods.front().mesh.get(); + const Mesh *mesh = lods.front().mesh; if (!mesh) throw logic_error("no mesh"); @@ -159,7 +157,7 @@ void Object::render(Renderer &renderer, const ObjectInstance &inst, Tag tag) con if(!pass) return; - const Mesh *mesh = lods[lod].mesh.get(); + const Mesh *mesh = lods[lod].mesh; if (!mesh) throw logic_error("no mesh"); @@ -175,7 +173,7 @@ void Object::render(Renderer &renderer, const ObjectInstance &inst, Tag tag) con const RenderPass *Object::get_pass(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); @@ -183,13 +181,13 @@ const RenderPass *Object::get_pass(Tag tag, unsigned lod) const 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; } @@ -249,7 +247,8 @@ 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 string &n) @@ -260,11 +259,12 @@ void Object::LodLoader::technique(const 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 diff --git a/source/render/object.h b/source/render/object.h index c97e951c..522d3adc 100644 --- a/source/render/object.h +++ b/source/render/object.h @@ -66,8 +66,8 @@ public: private: struct LevelOfDetail { - RefPtr mesh; - RefPtr technique; + const Mesh *mesh; + const Technique *technique; }; std::vector lods; diff --git a/source/render/scene.cpp b/source/render/scene.cpp index cec2683a..d916def8 100644 --- a/source/render/scene.cpp +++ b/source/render/scene.cpp @@ -1,4 +1,5 @@ #include +#include #include "camera.h" #include "objectinstance.h" #include "occludedscene.h" @@ -13,12 +14,6 @@ using namespace std; namespace Msp { namespace GL { -Scene::~Scene() -{ - for(vector::iterator i=owned_data.begin(); i!=owned_data.end(); ++i) - delete *i; -} - bool Scene::setup_frustum(const Renderer &renderer) const { const Camera *camera = renderer.get_camera(); @@ -123,10 +118,10 @@ void Scene::Loader::object_tagged(const string &n, const string &t) { RefPtr inst = new ObjectInstance(get_collection().get(n)); load_sub(*inst); - obj.add(*inst); + get_collection().add(format("%s/%d.inst", FS::basename(get_source()), inst_counter++), inst.get()); if(content && !t.empty()) (*content)[t] = inst.get(); - obj.owned_data.push_back(inst.release()); + obj.add(*inst.release()); } void Scene::Loader::scene(const string &n) diff --git a/source/render/scene.h b/source/render/scene.h index 33678b79..fcf5d33e 100644 --- a/source/render/scene.h +++ b/source/render/scene.h @@ -26,6 +26,7 @@ protected: private: ContentMap *content; + unsigned inst_counter; public: Loader(Scene &, Collection &); @@ -71,8 +72,6 @@ private: typedef TypeRegistry SceneRegistry; protected: - // XXX If a loaded renderable is removed from the scene it needs to be removed from here as well - std::vector owned_data; mutable Matrix culling_matrix; mutable Vector4 frustum_edges[6]; @@ -81,7 +80,7 @@ private: Scene(const Scene &); Scene &operator=(const Scene &); public: - virtual ~Scene(); + virtual ~Scene() { } virtual void add(Renderable &) = 0; virtual void remove(Renderable &) = 0; diff --git a/source/render/sequence.cpp b/source/render/sequence.cpp index b8fb6076..06b1403b 100644 --- a/source/render/sequence.cpp +++ b/source/render/sequence.cpp @@ -47,6 +47,9 @@ void Sequence::init(unsigned w, unsigned h) Sequence::~Sequence() { + for(vector::iterator i=postproc.begin(); i!=postproc.end(); ++i) + if(i->owned) + delete i->postproc; delete target[0]; delete target[1]; delete target_ms; @@ -114,25 +117,25 @@ Sequence::Step &Sequence::add_step(Tag tag, Renderable &r) void Sequence::add_postprocessor(PostProcessor &pp) { - add_postprocessor(&pp, true); + add_postprocessor(&pp, false); } void Sequence::add_postprocessor_owned(PostProcessor *pp) { - add_postprocessor(pp, false); + add_postprocessor(pp, true); } -void Sequence::add_postprocessor(PostProcessor *pp, bool keep) +void Sequence::add_postprocessor(PostProcessor *pp, bool owned) { - postproc.push_back(pp); - if(keep) - postproc.back().keep(); + postproc.push_back(PostProcStep(pp, owned)); try { create_targets(0); } catch(...) { + if(!owned) + delete pp; postproc.pop_back(); throw; } @@ -206,7 +209,7 @@ void Sequence::render(Renderer &renderer, Tag tag) const out_fbo->bind(); const Texture2D &color = target[j]->get_target_texture(RENDER_COLOR); const Texture2D &depth = target[j]->get_target_texture(RENDER_DEPTH); - postproc[i]->render(renderer, color, depth); + postproc[i].postproc->render(renderer, color, depth); } } } diff --git a/source/render/sequence.h b/source/render/sequence.h index fb60e371..8a480add 100644 --- a/source/render/sequence.h +++ b/source/render/sequence.h @@ -66,9 +66,17 @@ public: DEPRECATED typedef Step Pass; private: + struct PostProcStep + { + PostProcessor *postproc; + bool owned; + + PostProcStep(PostProcessor *pp, bool o): postproc(pp), owned(o) { } + }; + std::vector steps; const Camera *camera; - std::vector > postproc; + std::vector postproc; unsigned width; unsigned height; bool hdr;