diff --git a/servers/rendering/dummy/storage/material_storage.cpp b/servers/rendering/dummy/storage/material_storage.cpp index e8b553ca763..b22971a750c 100644 --- a/servers/rendering/dummy/storage/material_storage.cpp +++ b/servers/rendering/dummy/storage/material_storage.cpp @@ -30,6 +30,8 @@ #include "material_storage.h" +#include "core/config/project_settings.h" + using namespace RendererDummy; MaterialStorage *MaterialStorage::singleton = nullptr; @@ -42,6 +44,103 @@ MaterialStorage::MaterialStorage() { MaterialStorage::~MaterialStorage() { singleton = nullptr; + global_shader_variables.clear(); +} + +void MaterialStorage::global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) { + ERR_FAIL_COND(global_shader_variables.has(p_name)); + + global_shader_variables[p_name] = p_type; +} + +void MaterialStorage::global_shader_parameter_remove(const StringName &p_name) { + if (!global_shader_variables.has(p_name)) { + return; + } + + global_shader_variables.erase(p_name); +} + +Vector MaterialStorage::global_shader_parameter_get_list() const { + Vector names; + for (const KeyValue &E : global_shader_variables) { + names.push_back(E.key); + } + names.sort_custom(); + return names; +} + +RS::GlobalShaderParameterType MaterialStorage::global_shader_parameter_get_type(const StringName &p_name) const { + if (!global_shader_variables.has(p_name)) { + print_line("don't have name, sorry"); + return RS::GLOBAL_VAR_TYPE_MAX; + } + + return global_shader_variables[p_name]; +} + +void MaterialStorage::global_shader_parameters_load_settings(bool p_load_textures) { + List settings; + ProjectSettings::get_singleton()->get_property_list(&settings); + + for (const PropertyInfo &E : settings) { + if (E.name.begins_with("shader_globals/")) { + StringName name = E.name.get_slice("/", 1); + Dictionary d = GLOBAL_GET(E.name); + + ERR_CONTINUE(!d.has("type")); + ERR_CONTINUE(!d.has("value")); + + String type = d["type"]; + + static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = { + "bool", + "bvec2", + "bvec3", + "bvec4", + "int", + "ivec2", + "ivec3", + "ivec4", + "rect2i", + "uint", + "uvec2", + "uvec3", + "uvec4", + "float", + "vec2", + "vec3", + "vec4", + "color", + "rect2", + "mat2", + "mat3", + "mat4", + "transform_2d", + "transform", + "sampler2D", + "sampler2DArray", + "sampler3D", + "samplerCube", + "samplerExternalOES" + }; + + RS::GlobalShaderParameterType gvtype = RS::GLOBAL_VAR_TYPE_MAX; + + for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { + if (global_var_type_names[i] == type) { + gvtype = RS::GlobalShaderParameterType(i); + break; + } + } + + ERR_CONTINUE(gvtype == RS::GLOBAL_VAR_TYPE_MAX); //type invalid + + if (!global_shader_variables.has(name)) { + global_shader_parameter_add(name, gvtype, Variant()); + } + } + } } RID MaterialStorage::shader_allocate() { @@ -131,3 +230,56 @@ void MaterialStorage::get_shader_parameter_list(RID p_shader, List p_param_list->push_back(pi); } } + +RID MaterialStorage::material_allocate() { + return material_owner.allocate_rid(); +} + +void MaterialStorage::material_initialize(RID p_rid) { + material_owner.initialize_rid(p_rid, DummyMaterial()); +} + +void MaterialStorage::material_free(RID p_rid) { + DummyMaterial *material = material_owner.get_or_null(p_rid); + ERR_FAIL_NULL(material); + + material_owner.free(p_rid); +} + +void MaterialStorage::material_set_shader(RID p_material, RID p_shader) { + DummyMaterial *material = material_owner.get_or_null(p_material); + ERR_FAIL_NULL(material); + + material->shader = p_shader; +} + +void MaterialStorage::material_set_next_pass(RID p_material, RID p_next_material) { + DummyMaterial *material = material_owner.get_or_null(p_material); + ERR_FAIL_NULL(material); + + material->next_pass = p_next_material; +} + +void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List *r_parameters) { + DummyMaterial *material = material_owner.get_or_null(p_material); + ERR_FAIL_NULL(material); + DummyShader *shader = shader_owner.get_or_null(material->shader); + + if (shader) { + for (const KeyValue &E : shader->uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + RendererMaterialStorage::InstanceShaderParam p; + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); + r_parameters->push_back(p); + } + } + if (material->next_pass.is_valid()) { + material_get_instance_shader_parameters(material->next_pass, r_parameters); + } +} diff --git a/servers/rendering/dummy/storage/material_storage.h b/servers/rendering/dummy/storage/material_storage.h index 9422c395e2e..ef46cf3b9b4 100644 --- a/servers/rendering/dummy/storage/material_storage.h +++ b/servers/rendering/dummy/storage/material_storage.h @@ -42,6 +42,8 @@ class MaterialStorage : public RendererMaterialStorage { private: static MaterialStorage *singleton; + HashMap global_shader_variables; + struct DummyShader { HashMap uniforms; }; @@ -50,6 +52,13 @@ private: ShaderCompiler dummy_compiler; + struct DummyMaterial { + RID shader; + RID next_pass; + }; + + mutable RID_Owner material_owner; + public: static MaterialStorage *get_singleton() { return singleton; } @@ -58,16 +67,16 @@ public: /* GLOBAL SHADER UNIFORM API */ - virtual void global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) override {} - virtual void global_shader_parameter_remove(const StringName &p_name) override {} - virtual Vector global_shader_parameter_get_list() const override { return Vector(); } + virtual void global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) override; + virtual void global_shader_parameter_remove(const StringName &p_name) override; + virtual Vector global_shader_parameter_get_list() const override; virtual void global_shader_parameter_set(const StringName &p_name, const Variant &p_value) override {} virtual void global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) override {} virtual Variant global_shader_parameter_get(const StringName &p_name) const override { return Variant(); } - virtual RS::GlobalShaderParameterType global_shader_parameter_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; } + virtual RS::GlobalShaderParameterType global_shader_parameter_get_type(const StringName &p_name) const override; - virtual void global_shader_parameters_load_settings(bool p_load_textures = true) override {} + virtual void global_shader_parameters_load_settings(bool p_load_textures = true) override; virtual void global_shader_parameters_clear() override {} virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override { return 0; } @@ -95,23 +104,26 @@ public: virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); } /* MATERIAL API */ - virtual RID material_allocate() override { return RID(); } - virtual void material_initialize(RID p_rid) override {} - virtual void material_free(RID p_rid) override {} + + bool owns_material(RID p_rid) { return material_owner.owns(p_rid); } + + virtual RID material_allocate() override; + virtual void material_initialize(RID p_rid) override; + virtual void material_free(RID p_rid) override; virtual void material_set_render_priority(RID p_material, int priority) override {} - virtual void material_set_shader(RID p_shader_material, RID p_shader) override {} + virtual void material_set_shader(RID p_shader_material, RID p_shader) override; virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override {} virtual Variant material_get_param(RID p_material, const StringName &p_param) const override { return Variant(); } - virtual void material_set_next_pass(RID p_material, RID p_next_material) override {} + virtual void material_set_next_pass(RID p_material, RID p_next_material) override; virtual bool material_is_animated(RID p_material) override { return false; } virtual bool material_casts_shadows(RID p_material) override { return false; } virtual RS::CullMode material_get_cull_mode(RID p_material) const override { return RS::CULL_MODE_DISABLED; } - virtual void material_get_instance_shader_parameters(RID p_material, List *r_parameters) override {} + virtual void material_get_instance_shader_parameters(RID p_material, List *r_parameters) override; virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {} }; diff --git a/servers/rendering/dummy/storage/utilities.h b/servers/rendering/dummy/storage/utilities.h index 4e20dee640e..02e163fd8e8 100644 --- a/servers/rendering/dummy/storage/utilities.h +++ b/servers/rendering/dummy/storage/utilities.h @@ -77,6 +77,9 @@ public: } else if (RendererDummy::MaterialStorage::get_singleton()->owns_shader(p_rid)) { RendererDummy::MaterialStorage::get_singleton()->shader_free(p_rid); return true; + } else if (RendererDummy::MaterialStorage::get_singleton()->owns_material(p_rid)) { + RendererDummy::MaterialStorage::get_singleton()->material_free(p_rid); + return true; } return false; }