diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/resources/material.cpp | 93 | ||||
-rw-r--r-- | scene/resources/material.h | 11 | ||||
-rw-r--r-- | scene/resources/shader.cpp | 14 | ||||
-rw-r--r-- | scene/resources/shader.h | 2 |
4 files changed, 113 insertions, 7 deletions
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index b7a3b677f5..f07232a3ad 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -202,7 +202,98 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { if (!shader.is_null()) { - shader->get_param_list(p_list); + List<PropertyInfo> list; + shader->get_param_list(&list, true); + + HashMap<String, HashMap<String, List<PropertyInfo>>> groups; + { + HashMap<String, List<PropertyInfo>> none_subgroup; + none_subgroup.insert("<None>", List<PropertyInfo>()); + groups.insert("<None>", none_subgroup); + } + + String last_group = "<None>"; + String last_subgroup = "<None>"; + + bool is_none_group_undefined = true; + bool is_none_group = true; + + for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) { + if (E->get().usage == PROPERTY_USAGE_GROUP) { + if (!E->get().name.is_empty()) { + Vector<String> vgroup = E->get().name.split("::"); + last_group = vgroup[0]; + if (vgroup.size() > 1) { + last_subgroup = vgroup[1]; + } else { + last_subgroup = "<None>"; + } + is_none_group = false; + + if (!groups.has(last_group)) { + PropertyInfo info; + info.usage = PROPERTY_USAGE_GROUP; + info.name = last_group; + + List<PropertyInfo> none_subgroup; + none_subgroup.push_back(info); + + HashMap<String, List<PropertyInfo>> subgroup_map; + subgroup_map.insert("<None>", none_subgroup); + + groups.insert(last_group, subgroup_map); + } + + if (!groups[last_group].has(last_subgroup)) { + PropertyInfo info; + info.usage = PROPERTY_USAGE_SUBGROUP; + info.name = last_subgroup; + + List<PropertyInfo> subgroup; + subgroup.push_back(info); + + groups[last_group].insert(last_subgroup, subgroup); + } + } else { + last_group = "<None>"; + last_subgroup = "<None>"; + is_none_group = true; + } + continue; // Pass group. + } + + if (is_none_group_undefined && is_none_group) { + is_none_group_undefined = false; + + PropertyInfo info; + info.usage = PROPERTY_USAGE_GROUP; + info.name = "Shader Param"; + groups["<None>"]["<None>"].push_back(info); + } + + PropertyInfo info = E->get(); + info.name = info.name; + groups[last_group][last_subgroup].push_back(info); + } + + // Sort groups alphabetically. + List<UniformProp> props; + for (HashMap<String, HashMap<String, List<PropertyInfo>>>::Iterator group = groups.begin(); group; ++group) { + for (HashMap<String, List<PropertyInfo>>::Iterator subgroup = group->value.begin(); subgroup; ++subgroup) { + for (List<PropertyInfo>::Element *item = subgroup->value.front(); item; item = item->next()) { + if (subgroup->key == "<None>") { + props.push_back({ group->key, item->get() }); + } else { + props.push_back({ group->key + "::" + subgroup->key, item->get() }); + } + } + } + } + props.sort_custom<UniformPropComparator>(); + + for (List<UniformProp>::Element *E = props.front(); E; E = E->next()) { + p_list->push_back(E->get().info); + } } } diff --git a/scene/resources/material.h b/scene/resources/material.h index 905e604e95..8c04817c6b 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -84,6 +84,17 @@ class ShaderMaterial : public Material { HashMap<StringName, Variant> param_cache; + struct UniformProp { + String str; + PropertyInfo info; + }; + + struct UniformPropComparator { + bool operator()(const UniformProp &p_a, const UniformProp &p_b) const { + return p_a.str.naturalnocasecmp_to(p_b.str) < 0; + } + }; + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 16117986fe..74031e02d7 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -103,7 +103,7 @@ String Shader::get_code() const { return code; } -void Shader::get_param_list(List<PropertyInfo> *p_params) const { +void Shader::get_param_list(List<PropertyInfo> *p_params, bool p_get_groups) const { _update_shader(); List<PropertyInfo> local; @@ -112,12 +112,16 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const { params_cache_dirty = false; for (PropertyInfo &pi : local) { - if (default_textures.has(pi.name)) { //do not show default textures + bool is_group = pi.usage == PROPERTY_USAGE_GROUP || pi.usage == PROPERTY_USAGE_SUBGROUP; + if (!p_get_groups && is_group) { continue; } - String original_name = pi.name; - pi.name = "shader_param/" + pi.name; - params_cache[pi.name] = original_name; + if (!is_group) { + if (default_textures.has(pi.name)) { //do not show default textures + continue; + } + params_cache[pi.name] = pi.name; + } if (p_params) { //small little hack if (pi.type == Variant::RID) { diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 5de8ad5518..7aa14651a5 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -78,7 +78,7 @@ public: void set_code(const String &p_code); String get_code() const; - void get_param_list(List<PropertyInfo> *p_params) const; + void get_param_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const; bool has_param(const StringName &p_param) const; void set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture, int p_index = 0); |