From 04005f74fece3c33848ed9420dc0f9c431a9f0ec Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 19 Apr 2021 11:14:51 +0300 Subject: [PATCH] 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. --- source/materials/renderpass.cpp | 40 +++++++++++++-------------------- source/materials/renderpass.h | 4 ++-- 2 files changed, 18 insertions(+), 26 deletions(-) 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 *); -- 2.45.2