X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fmaterials%2Frendermethod.cpp;h=ddbe4f1e457e83760dc699bce85ad52dd64ac29e;hp=053197589ab1fe6e9d3c83c78261ffc3e27ebc0e;hb=HEAD;hpb=5a01404e40717c6c2cc389ed8357713e1f216f07 diff --git a/source/materials/rendermethod.cpp b/source/materials/rendermethod.cpp index 05319758..78b937d0 100644 --- a/source/materials/rendermethod.cpp +++ b/source/materials/rendermethod.cpp @@ -14,18 +14,11 @@ using namespace std; namespace Msp { namespace GL { -RenderMethod::RenderMethod(): - shprog(0), - shprog_from_material(false), - shdata(0), - material(0), - face_cull(CULL_BACK), - receive_shadows(false), - image_based_lighting(false) -{ } - void RenderMethod::set_material_textures() { + if(!material) + return; + 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(*tag)); @@ -33,7 +26,7 @@ void RenderMethod::set_material_textures() void RenderMethod::maybe_create_material_shader() { - if(shprog && !shprog_from_material) + if(!material || (shprog && !shprog_from_material)) return; map extra_spec; @@ -41,11 +34,17 @@ void RenderMethod::maybe_create_material_shader() extra_spec["use_shadow_map"] = true; if(image_based_lighting) extra_spec["use_image_based_lighting"] = true; + if(instancing) + extra_spec["use_instancing"] = true; shprog = material->create_compatible_shader(extra_spec); if(shdata) - shdata = new ProgramData(*shdata, shprog); + { + RefPtr old_shdata = shdata; + shdata = new ProgramData(shprog); + shdata->copy_uniforms(*old_shdata); + } shprog_from_material = true; } @@ -54,7 +53,14 @@ void RenderMethod::set_shader_program(const Program *prog, const ProgramData *da { shprog = prog; shprog_from_material = false; - shdata = (data ? new ProgramData(*data) : 0); + if(data) + { + shdata = new ProgramData; + shdata->copy_uniforms(*data); + } + else + shdata = 0; + maybe_create_material_shader(); } Tag RenderMethod::get_slotted_uniform_tag(Tag slot) const @@ -77,7 +83,7 @@ void RenderMethod::set_texture(Tag tag, const Texture *tex, const Sampler *samp) auto i = find_member(textures, tag, &TextureSlot::tag); if(i==textures.end()) { - textures.push_back(TextureSlot(tag)); + textures.emplace_back(tag); i = textures.end()-1; } i->texture = tex; @@ -96,9 +102,21 @@ void RenderMethod::set_face_cull(CullMode fc) face_cull = fc; } +void RenderMethod::set_blend(const Blend &b) +{ + blend = b; +} + void RenderMethod::set_receive_shadows(bool rs) { receive_shadows = rs; + maybe_create_material_shader(); +} + +void RenderMethod::set_image_based_lighting(bool ibl) +{ + image_based_lighting = ibl; + maybe_create_material_shader(); } void RenderMethod::apply(Renderer &renderer) const @@ -109,6 +127,7 @@ void RenderMethod::apply(Renderer &renderer) const if(material) renderer.add_shader_data(material->get_shader_data()); renderer.set_face_cull(face_cull); + renderer.set_blend(&blend); } void RenderMethod::set_debug_name(const string &name) @@ -132,9 +151,12 @@ RenderMethod::Loader::Loader(RenderMethod &p, Collection &c): void RenderMethod::Loader::init_actions() { + add("blend", &Loader::blend); + add("blend", &Loader::blend_factors); add("face_cull", &RenderMethod::face_cull); - add("shader", &Loader::shader); + add("shader", &Loader::shader); add("image_based_lighting", &RenderMethod::image_based_lighting); + add("instancing", &RenderMethod::instancing); add("material", &Loader::material_inline); add("material", &Loader::material); add("material_slot", &RenderMethod::material_slot); @@ -156,6 +178,16 @@ void RenderMethod::Loader::finish() obj.maybe_create_material_shader(); } +void RenderMethod::Loader::blend() +{ + load_sub(obj.blend); +} + +void RenderMethod::Loader::blend_factors(BlendFactor src, BlendFactor dest) +{ + obj.blend = Blend(src, dest); +} + void RenderMethod::Loader::material_inline() { Material::GenericLoader ldr(get_collection()); @@ -175,7 +207,11 @@ void RenderMethod::Loader::shader(const string &n) obj.shprog = &get_collection().get(n); obj.shprog_from_material = false; if(obj.shdata) - obj.shdata = new ProgramData(*obj.shdata, obj.shprog); + { + RefPtr old_shdata = obj.shdata; + obj.shdata = new ProgramData(obj.shprog); + obj.shdata->copy_uniforms(*old_shdata); + } } void RenderMethod::Loader::texture(const string &n) @@ -183,7 +219,7 @@ void RenderMethod::Loader::texture(const string &n) auto i = find_member(obj.textures, Tag(n), &TextureSlot::tag); if(i==obj.textures.end()) { - obj.textures.push_back(TextureSlot(n)); + obj.textures.emplace_back(n); i = obj.textures.end()-1; } TextureSlot::Loader ldr(*i, n, coll); @@ -197,7 +233,11 @@ void RenderMethod::Loader::uniforms() if(!obj.shdata) obj.shdata = new ProgramData(obj.shprog); else if(obj.shdata.refcount()>1) - obj.shdata = new ProgramData(*obj.shdata); + { + RefPtr old_shdata = obj.shdata; + obj.shdata = new ProgramData; + obj.shdata->copy_uniforms(*old_shdata); + } load_sub(*obj.shdata); }