From: Mikko Rasa Date: Mon, 19 Apr 2021 08:14:51 +0000 (+0300) Subject: Rearrange material-related state management in RenderPass X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=04005f74fece3c33848ed9420dc0f9c431a9f0ec;p=libs%2Fgl.git Rearrange material-related state management in RenderPass The change in texture handling allows some simplifications here since material textures no longer need to set any uniforms. Creation of material shader while loading is deferred to finish() so it isn't done needlessly. --- diff --git a/source/materials/renderpass.cpp b/source/materials/renderpass.cpp index e6a9a0a4..951cbb5d 100644 --- a/source/materials/renderpass.cpp +++ b/source/materials/renderpass.cpp @@ -25,11 +25,8 @@ RenderPass::RenderPass(): back_faces(false) { } -void RenderPass::finalize_material(DataFile::Collection *coll) +void RenderPass::set_material_textures() { - maybe_create_material_shader(coll); - ensure_private_shader_data(); - const Tag *material_texture_tags = material->get_texture_tags(); for(const Tag *tag=material_texture_tags; tag->id; ++tag) set_texture(*tag, material->get_texture(*tag), material->get_sampler()); @@ -46,7 +43,7 @@ void RenderPass::maybe_create_material_shader(DataFile::Collection *coll) shprog.keep(); } else - throw invalid_operation("no collection"); + throw invalid_operation("RenderPass::maybe_create_material_shader"); if(shdata) shdata = new ProgramData(*shdata, shprog.get()); @@ -54,25 +51,12 @@ void RenderPass::maybe_create_material_shader(DataFile::Collection *coll) shprog_from_material = true; } -void RenderPass::ensure_private_shader_data() -{ - if(!shprog) - throw invalid_operation("RenderPass::ensure_private_shader_data"); - - if(!shdata) - shdata = new ProgramData(shprog.get()); - else if(shdata.refcount()>1) - shdata = new ProgramData(*shdata); -} - 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); - if(material) - finalize_material(0); } Tag RenderPass::get_slotted_uniform_tag(Tag slot) const @@ -87,7 +71,8 @@ void RenderPass::set_material(const Material *mat, DataFile::Collection *coll) { material = mat; material.keep(); - finalize_material(coll); + maybe_create_material_shader(coll); + set_material_textures(); } void RenderPass::set_texture(Tag tag, const Texture *tex, const Sampler *samp) @@ -182,6 +167,12 @@ void RenderPass::Loader::init_actions() add("texunit", &Loader::texunit_named); } +void RenderPass::Loader::finish() +{ + if(obj.material) + obj.maybe_create_material_shader(coll); +} + // Temporary compatibility feature string RenderPass::Loader::get_shader_name(const string &n) { @@ -198,14 +189,14 @@ void RenderPass::Loader::material_inline() Material::GenericLoader ldr(coll); load_sub_with(ldr); obj.material = ldr.get_material(); - obj.finalize_material(coll); + obj.set_material_textures(); } void RenderPass::Loader::material(const string &name) { obj.material = &get_collection().get(name); obj.material.keep(); - obj.finalize_material(coll); + obj.set_material_textures(); } void RenderPass::Loader::shader(const string &n) @@ -215,8 +206,6 @@ void RenderPass::Loader::shader(const string &n) obj.shprog_from_material = false; if(obj.shdata) obj.shdata = new ProgramData(*obj.shdata, obj.shprog.get()); - if(obj.material) - obj.finalize_material(coll); } void RenderPass::Loader::texture(const string &n) @@ -265,7 +254,10 @@ void RenderPass::Loader::uniforms() { if(!obj.shprog || obj.shprog_from_material) throw runtime_error("Shader is required for uniforms"); - obj.ensure_private_shader_data(); + if(!obj.shdata) + obj.shdata = new ProgramData(obj.shprog.get()); + 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 cb378556..b5b9cfb5 100644 --- a/source/materials/renderpass.h +++ b/source/materials/renderpass.h @@ -33,6 +33,7 @@ public: private: virtual void init_actions(); + virtual void finish(); static std::string get_shader_name(const std::string &); @@ -83,9 +84,8 @@ public: RenderPass(); private: - void finalize_material(DataFile::Collection *); void maybe_create_material_shader(DataFile::Collection *); - void ensure_private_shader_data(); + void set_material_textures(); public: void set_shader_program(const Program *, const ProgramData *);