summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/animation_library.cpp21
-rw-r--r--scene/resources/animation_library.h3
-rw-r--r--scene/resources/default_theme/default_theme.cpp65
-rw-r--r--scene/resources/default_theme/default_theme.h2
-rw-r--r--scene/resources/font.cpp22
-rw-r--r--scene/resources/font.h4
-rw-r--r--scene/resources/gradient.cpp2
-rw-r--r--scene/resources/gradient.h2
-rw-r--r--scene/resources/immediate_mesh.cpp2
-rw-r--r--scene/resources/material.cpp127
-rw-r--r--scene/resources/material.h18
-rw-r--r--scene/resources/packed_scene.cpp3
-rw-r--r--scene/resources/resource_format_text.cpp2
-rw-r--r--scene/resources/style_box.cpp62
-rw-r--r--scene/resources/style_box.h4
-rw-r--r--scene/resources/texture.cpp5
16 files changed, 262 insertions, 82 deletions
diff --git a/scene/resources/animation_library.cpp b/scene/resources/animation_library.cpp
index 229d9ab218..5d92c3b0c6 100644
--- a/scene/resources/animation_library.cpp
+++ b/scene/resources/animation_library.cpp
@@ -30,8 +30,25 @@
#include "animation_library.h"
+bool AnimationLibrary::is_valid_name(const String &p_name) {
+ return !(p_name.is_empty() || p_name.contains("/") || p_name.contains(":") || p_name.contains(",") || p_name.contains("["));
+}
+
+String AnimationLibrary::validate_name(const String &p_name) {
+ if (p_name.is_empty()) {
+ return "_"; // Should always return a valid name.
+ }
+
+ String name = p_name;
+ const char *characters = "/:,[";
+ for (const char *p = characters; *p; p++) {
+ name = name.replace(String::chr(*p), "_");
+ }
+ return name;
+}
+
Error AnimationLibrary::add_animation(const StringName &p_name, const Ref<Animation> &p_animation) {
- ERR_FAIL_COND_V_MSG(String(p_name).contains("/") || String(p_name).contains(":") || String(p_name).contains(",") || String(p_name).contains("["), ERR_INVALID_PARAMETER, "Invalid animation name: " + String(p_name) + ".");
+ ERR_FAIL_COND_V_MSG(!is_valid_name(p_name), ERR_INVALID_PARAMETER, "Invalid animation name: '" + String(p_name) + "'.");
ERR_FAIL_COND_V(p_animation.is_null(), ERR_INVALID_PARAMETER);
if (animations.has(p_name)) {
@@ -55,7 +72,7 @@ void AnimationLibrary::remove_animation(const StringName &p_name) {
void AnimationLibrary::rename_animation(const StringName &p_name, const StringName &p_new_name) {
ERR_FAIL_COND(!animations.has(p_name));
- ERR_FAIL_COND_MSG(String(p_new_name).contains("/") || String(p_new_name).contains(":") || String(p_new_name).contains(",") || String(p_new_name).contains("["), "Invalid animation name: " + String(p_new_name) + ".");
+ ERR_FAIL_COND_MSG(!is_valid_name(p_new_name), "Invalid animation name: '" + String(p_new_name) + "'.");
ERR_FAIL_COND(animations.has(p_new_name));
animations.insert(p_new_name, animations[p_name]);
diff --git a/scene/resources/animation_library.h b/scene/resources/animation_library.h
index 69ac5a97d2..0f327fb072 100644
--- a/scene/resources/animation_library.h
+++ b/scene/resources/animation_library.h
@@ -49,6 +49,9 @@ protected:
static void _bind_methods();
public:
+ static bool is_valid_name(const String &p_name);
+ static String validate_name(const String &p_name);
+
Error add_animation(const StringName &p_name, const Ref<Animation> &p_animation);
void remove_animation(const StringName &p_name);
void rename_animation(const StringName &p_name, const StringName &p_new_name);
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 69b8355497..271cf61171 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -177,7 +177,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("icon_focus_color", "Button", Color(1, 1, 1, 1));
theme->set_color("icon_disabled_color", "Button", Color(1, 1, 1, 0.4));
- theme->set_constant("hseparation", "Button", 2 * scale);
+ theme->set_constant("h_separation", "Button", 2 * scale);
// LinkButton
@@ -230,7 +230,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_disabled_color", "OptionButton", control_font_disabled_color);
theme->set_color("font_outline_color", "OptionButton", Color(1, 1, 1));
- theme->set_constant("hseparation", "OptionButton", 2 * scale);
+ theme->set_constant("h_separation", "OptionButton", 2 * scale);
theme->set_constant("arrow_margin", "OptionButton", 4 * scale);
theme->set_constant("outline_size", "OptionButton", 0);
@@ -252,7 +252,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_disabled_color", "MenuButton", Color(1, 1, 1, 0.3));
theme->set_color("font_outline_color", "MenuButton", Color(1, 1, 1));
- theme->set_constant("hseparation", "MenuButton", 3 * scale);
+ theme->set_constant("h_separation", "MenuButton", 3 * scale);
theme->set_constant("outline_size", "MenuButton", 0);
// CheckBox
@@ -295,8 +295,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_disabled_color", "CheckBox", control_font_disabled_color);
theme->set_color("font_outline_color", "CheckBox", Color(1, 1, 1));
- theme->set_constant("hseparation", "CheckBox", 4 * scale);
- theme->set_constant("check_vadjust", "CheckBox", 0 * scale);
+ theme->set_constant("h_separation", "CheckBox", 4 * scale);
+ theme->set_constant("check_v_adjust", "CheckBox", 0 * scale);
theme->set_constant("outline_size", "CheckBox", 0);
// CheckButton
@@ -335,8 +335,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_disabled_color", "CheckButton", control_font_disabled_color);
theme->set_color("font_outline_color", "CheckButton", Color(1, 1, 1));
- theme->set_constant("hseparation", "CheckButton", 4 * scale);
- theme->set_constant("check_vadjust", "CheckButton", 0 * scale);
+ theme->set_constant("h_separation", "CheckButton", 4 * scale);
+ theme->set_constant("check_v_adjust", "CheckButton", 0 * scale);
theme->set_constant("outline_size", "CheckButton", 0);
// Label
@@ -582,8 +582,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("close", "Window", icons["close"]);
theme->set_icon("close_pressed", "Window", icons["close_hl"]);
- theme->set_constant("close_h_ofs", "Window", 18 * scale);
- theme->set_constant("close_v_ofs", "Window", 24 * scale);
+ theme->set_constant("close_h_offset", "Window", 18 * scale);
+ theme->set_constant("close_v_offset", "Window", 24 * scale);
// Dialogs
@@ -665,8 +665,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_outline_color", "PopupMenu", Color(1, 1, 1));
theme->set_color("font_separator_outline_color", "PopupMenu", Color(1, 1, 1));
- theme->set_constant("hseparation", "PopupMenu", 4 * scale);
- theme->set_constant("vseparation", "PopupMenu", 4 * scale);
+ theme->set_constant("h_separation", "PopupMenu", 4 * scale);
+ theme->set_constant("v_separation", "PopupMenu", 4 * scale);
theme->set_constant("outline_size", "PopupMenu", 0);
theme->set_constant("separator_outline_size", "PopupMenu", 0);
theme->set_constant("item_start_padding", "PopupMenu", 2 * scale);
@@ -688,9 +688,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
graphnode_position->set_border_color(Color(0.98, 0.89, 0.27));
theme->set_stylebox("frame", "GraphNode", graphnode_normal);
- theme->set_stylebox("selectedframe", "GraphNode", graphnode_selected);
+ theme->set_stylebox("selected_frame", "GraphNode", graphnode_selected);
theme->set_stylebox("comment", "GraphNode", graphnode_comment_normal);
- theme->set_stylebox("commentfocus", "GraphNode", graphnode_comment_selected);
+ theme->set_stylebox("comment_focus", "GraphNode", graphnode_comment_selected);
theme->set_stylebox("breakpoint", "GraphNode", graphnode_breakpoint);
theme->set_stylebox("position", "GraphNode", graphnode_position);
@@ -746,8 +746,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("children_hl_line_color", "Tree", Color(0.27, 0.27, 0.27));
theme->set_color("custom_button_font_highlight", "Tree", control_font_hover_color);
- theme->set_constant("hseparation", "Tree", 4 * scale);
- theme->set_constant("vseparation", "Tree", 4 * scale);
+ theme->set_constant("h_separation", "Tree", 4 * scale);
+ theme->set_constant("v_separation", "Tree", 4 * scale);
theme->set_constant("item_margin", "Tree", 16 * scale);
theme->set_constant("button_margin", "Tree", 4 * scale);
theme->set_constant("draw_relationship_lines", "Tree", 0);
@@ -764,8 +764,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("bg", "ItemList", make_flat_stylebox(style_normal_color));
theme->set_stylebox("bg_focus", "ItemList", focus);
- theme->set_constant("hseparation", "ItemList", 4);
- theme->set_constant("vseparation", "ItemList", 2);
+ theme->set_constant("h_separation", "ItemList", 4);
+ theme->set_constant("v_separation", "ItemList", 2);
theme->set_constant("icon_margin", "ItemList", 4);
theme->set_constant("line_separation", "ItemList", 2 * scale);
@@ -846,7 +846,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_outline_color", "TabBar", Color(1, 1, 1));
theme->set_color("drop_mark_color", "TabBar", Color(1, 1, 1));
- theme->set_constant("hseparation", "TabBar", 4 * scale);
+ theme->set_constant("h_separation", "TabBar", 4 * scale);
theme->set_constant("outline_size", "TabBar", 0);
// Separators
@@ -896,7 +896,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_disabled_color", "ColorPickerButton", Color(0.9, 0.9, 0.9, 0.3));
theme->set_color("font_outline_color", "ColorPickerButton", Color(1, 1, 1));
- theme->set_constant("hseparation", "ColorPickerButton", 2 * scale);
+ theme->set_constant("h_separation", "ColorPickerButton", 2 * scale);
theme->set_constant("outline_size", "ColorPickerButton", 0);
// ColorPresetButton
@@ -956,8 +956,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("shadow_outline_size", "RichTextLabel", 1 * scale);
theme->set_constant("line_separation", "RichTextLabel", 0 * scale);
- theme->set_constant("table_hseparation", "RichTextLabel", 3 * scale);
- theme->set_constant("table_vseparation", "RichTextLabel", 3 * scale);
+ theme->set_constant("table_h_separation", "RichTextLabel", 3 * scale);
+ theme->set_constant("table_v_separation", "RichTextLabel", 3 * scale);
theme->set_constant("outline_size", "RichTextLabel", 0);
@@ -976,16 +976,16 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("margin_top", "MarginContainer", 0 * scale);
theme->set_constant("margin_right", "MarginContainer", 0 * scale);
theme->set_constant("margin_bottom", "MarginContainer", 0 * scale);
- theme->set_constant("hseparation", "GridContainer", 4 * scale);
- theme->set_constant("vseparation", "GridContainer", 4 * scale);
+ theme->set_constant("h_separation", "GridContainer", 4 * scale);
+ theme->set_constant("v_separation", "GridContainer", 4 * scale);
theme->set_constant("separation", "HSplitContainer", 12 * scale);
theme->set_constant("separation", "VSplitContainer", 12 * scale);
theme->set_constant("autohide", "HSplitContainer", 1 * scale);
theme->set_constant("autohide", "VSplitContainer", 1 * scale);
- theme->set_constant("hseparation", "HFlowContainer", 4 * scale);
- theme->set_constant("vseparation", "HFlowContainer", 4 * scale);
- theme->set_constant("hseparation", "VFlowContainer", 4 * scale);
- theme->set_constant("vseparation", "VFlowContainer", 4 * scale);
+ theme->set_constant("h_separation", "HFlowContainer", 4 * scale);
+ theme->set_constant("v_separation", "HFlowContainer", 4 * scale);
+ theme->set_constant("h_separation", "VFlowContainer", 4 * scale);
+ theme->set_constant("v_separation", "VFlowContainer", 4 * scale);
theme->set_stylebox("panel", "PanelContainer", make_flat_stylebox(style_normal_color, 0, 0, 0, 0));
@@ -1026,7 +1026,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
default_style = make_flat_stylebox(Color(1, 0.365, 0.365), 4, 4, 4, 4, 0, false, 2);
}
-void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_subpixel, TextServer::Hinting p_hinting, bool p_aa) {
+void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel, TextServer::Hinting p_font_hinting, bool p_font_antialiased, bool p_font_msdf, bool p_font_generate_mipmaps) {
Ref<Theme> t;
t.instantiate();
@@ -1051,9 +1051,12 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos
Ref<FontData> dynamic_font_data;
dynamic_font_data.instantiate();
dynamic_font_data->set_data_ptr(_font_OpenSans_SemiBold, _font_OpenSans_SemiBold_size);
- dynamic_font_data->set_subpixel_positioning(p_subpixel);
- dynamic_font_data->set_hinting(p_hinting);
- dynamic_font_data->set_antialiased(p_aa);
+ dynamic_font_data->set_subpixel_positioning(p_font_subpixel);
+ dynamic_font_data->set_hinting(p_font_hinting);
+ dynamic_font_data->set_antialiased(p_font_antialiased);
+ dynamic_font_data->set_multichannel_signed_distance_field(p_font_msdf);
+ dynamic_font_data->set_generate_mipmaps(p_font_generate_mipmaps);
+
dynamic_font->add_data(dynamic_font_data);
default_font = dynamic_font;
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index a9e21dda3f..f777330a07 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -36,7 +36,7 @@
const int default_font_size = 16;
void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &bold_font, const Ref<Font> &bold_italics_font, const Ref<Font> &italics_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
-void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_subpixel, TextServer::Hinting p_hinting, bool p_aa);
+void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel = TextServer::SUBPIXEL_POSITIONING_AUTO, TextServer::Hinting p_font_hinting = TextServer::HINTING_LIGHT, bool p_font_antialiased = true, bool p_font_msdf = false, bool p_font_generate_mipmaps = false);
void clear_default_theme();
#endif
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index efbe9c93f7..d6b2572628 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -54,6 +54,7 @@ _FORCE_INLINE_ void FontData::_ensure_rid(int p_cache_index) const {
cache.write[p_cache_index] = TS->create_font();
TS->font_set_data_ptr(cache[p_cache_index], data_ptr, data_size);
TS->font_set_antialiased(cache[p_cache_index], antialiased);
+ TS->font_set_generate_mipmaps(cache[p_cache_index], mipmaps);
TS->font_set_multichannel_signed_distance_field(cache[p_cache_index], msdf);
TS->font_set_msdf_pixel_range(cache[p_cache_index], msdf_pixel_range);
TS->font_set_msdf_size(cache[p_cache_index], msdf_size);
@@ -77,6 +78,9 @@ void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &FontData::set_antialiased);
ClassDB::bind_method(D_METHOD("is_antialiased"), &FontData::is_antialiased);
+ ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &FontData::set_generate_mipmaps);
+ ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &FontData::get_generate_mipmaps);
+
ClassDB::bind_method(D_METHOD("set_font_name", "name"), &FontData::set_font_name);
ClassDB::bind_method(D_METHOD("get_font_name"), &FontData::get_font_name);
@@ -212,6 +216,7 @@ void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_supported_variation_list"), &FontData::get_supported_variation_list);
ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_data", "get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_generate_mipmaps", "get_generate_mipmaps");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_antialiased", "is_antialiased");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_name", "get_font_name");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style_name", "get_font_style_name");
@@ -442,6 +447,7 @@ void FontData::reset_state() {
cache.clear();
antialiased = true;
+ mipmaps = false;
msdf = false;
force_autohinter = false;
hinting = TextServer::HINTING_LIGHT;
@@ -735,6 +741,7 @@ Error FontData::load_bitmap_font(const String &p_path) {
reset_state();
antialiased = false;
+ mipmaps = false;
msdf = false;
force_autohinter = false;
hinting = TextServer::HINTING_NONE;
@@ -1290,6 +1297,21 @@ bool FontData::is_antialiased() const {
return antialiased;
}
+void FontData::set_generate_mipmaps(bool p_generate_mipmaps) {
+ if (mipmaps != p_generate_mipmaps) {
+ mipmaps = p_generate_mipmaps;
+ for (int i = 0; i < cache.size(); i++) {
+ _ensure_rid(i);
+ TS->font_set_generate_mipmaps(cache[i], mipmaps);
+ }
+ emit_changed();
+ }
+}
+
+bool FontData::get_generate_mipmaps() const {
+ return mipmaps;
+}
+
void FontData::set_multichannel_signed_distance_field(bool p_msdf) {
if (msdf != p_msdf) {
msdf = p_msdf;
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 2aa12dd2de..9a90032605 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -49,6 +49,7 @@ class FontData : public Resource {
PackedByteArray data;
bool antialiased = true;
+ bool mipmaps = false;
bool msdf = false;
int msdf_pixel_range = 16;
int msdf_size = 48;
@@ -103,6 +104,9 @@ public:
virtual void set_antialiased(bool p_antialiased);
virtual bool is_antialiased() const;
+ virtual void set_generate_mipmaps(bool p_generate_mipmaps);
+ virtual bool get_generate_mipmaps() const;
+
virtual void set_multichannel_signed_distance_field(bool p_msdf);
virtual bool is_multichannel_signed_distance_field() const;
diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp
index caaa3d8628..a9c44dc6bf 100644
--- a/scene/resources/gradient.cpp
+++ b/scene/resources/gradient.cpp
@@ -157,7 +157,7 @@ void Gradient::reverse() {
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void Gradient::set_points(Vector<Gradient::Point> &p_points) {
+void Gradient::set_points(const Vector<Gradient::Point> &p_points) {
points = p_points;
is_sorted = false;
emit_signal(CoreStringNames::get_singleton()->changed);
diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h
index c2085b3a13..a3d3449099 100644
--- a/scene/resources/gradient.h
+++ b/scene/resources/gradient.h
@@ -73,7 +73,7 @@ public:
void add_point(float p_offset, const Color &p_color);
void remove_point(int p_index);
- void set_points(Vector<Point> &p_points);
+ void set_points(const Vector<Point> &p_points);
Vector<Point> &get_points();
void reverse();
diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp
index 28afef8638..044477e744 100644
--- a/scene/resources/immediate_mesh.cpp
+++ b/scene/resources/immediate_mesh.cpp
@@ -211,7 +211,7 @@ void ImmediateMesh::surface_end() {
value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10;
value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20;
if (t.d > 0) {
- value |= 3 << 30;
+ value |= 3UL << 30;
}
*tangent = value;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 430626b008..8e17ff35a9 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -395,6 +395,9 @@ void BaseMaterial3D::init_shaders() {
shader_names->distance_fade_min = "distance_fade_min";
shader_names->distance_fade_max = "distance_fade_max";
+ shader_names->msdf_pixel_range = "msdf_pixel_range";
+ shader_names->msdf_outline_size = "msdf_outline_size";
+
shader_names->metallic_texture_channel = "metallic_texture_channel";
shader_names->ao_texture_channel = "ao_texture_channel";
shader_names->clearcoat_texture_channel = "clearcoat_texture_channel";
@@ -432,12 +435,10 @@ void BaseMaterial3D::init_shaders() {
shader_names->albedo_texture_size = "albedo_texture_size";
}
-Ref<StandardMaterial3D> BaseMaterial3D::materials_for_2d[BaseMaterial3D::MAX_MATERIALS_FOR_2D];
+HashMap<uint64_t, Ref<StandardMaterial3D>> BaseMaterial3D::materials_for_2d;
void BaseMaterial3D::finish_shaders() {
- for (int i = 0; i < MAX_MATERIALS_FOR_2D; i++) {
- materials_for_2d[i].unref();
- }
+ materials_for_2d.clear();
memdelete(dirty_materials);
dirty_materials = nullptr;
@@ -644,6 +645,11 @@ void BaseMaterial3D::_update_shader() {
code += "uniform float distance_fade_max;\n";
}
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ code += "uniform float msdf_pixel_range;\n";
+ code += "uniform float msdf_outline_size;\n";
+ }
+
// alpha scissor is only valid if there is not antialiasing edge
// alpha hash is valid whenever, but not with alpha scissor
if (transparency == TRANSPARENCY_ALPHA_SCISSOR) {
@@ -911,6 +917,12 @@ void BaseMaterial3D::_update_shader() {
code += "}\n";
code += "\n\n";
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ code += "float msdf_median(float r, float g, float b, float a) {\n";
+ code += " return min(max(min(r, g), min(max(r, g), b)), a);\n";
+ code += "}\n";
+ }
+ code += "\n\n";
if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) {
code += "vec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_triplanar_pos) {\n";
code += " vec4 samp=vec4(0.0);\n";
@@ -1010,7 +1022,30 @@ void BaseMaterial3D::_update_shader() {
}
}
- if (flags[FLAG_ALBEDO_TEXTURE_FORCE_SRGB]) {
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ code += " {\n";
+ code += " albedo_tex.rgb = mix(vec3(1.0 + 0.055) * pow(albedo_tex.rgb, vec3(1.0 / 2.4)) - vec3(0.055), vec3(12.92) * albedo_tex.rgb.rgb, lessThan(albedo_tex.rgb, vec3(0.0031308)));\n";
+ code += " vec2 msdf_size = vec2(msdf_pixel_range) / vec2(textureSize(texture_albedo, 0));\n";
+ if (flags[FLAG_USE_POINT_SIZE]) {
+ code += " vec2 dest_size = vec2(1.0) / fwidth(POINT_COORD);\n";
+ } else {
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += " vec2 dest_size = vec2(1.0) / fwidth(uv1_triplanar_pos);\n";
+ } else {
+ code += " vec2 dest_size = vec2(1.0) / fwidth(base_uv);\n";
+ }
+ }
+ code += " float px_size = max(0.5 * dot(msdf_size, dest_size), 1.0);\n";
+ code += " float d = msdf_median(albedo_tex.r, albedo_tex.g, albedo_tex.b, albedo_tex.a) - 0.5;\n";
+ code += " if (msdf_outline_size > 0.0) {\n";
+ code += " float cr = clamp(msdf_outline_size, 0.0, msdf_pixel_range / 2.0) / msdf_pixel_range;\n";
+ code += " albedo_tex.a = clamp((d + cr) * px_size, 0.0, 1.0);\n";
+ code += " } else {\n";
+ code += " albedo_tex.a = clamp(d * px_size + 0.5, 0.0, 1.0);\n";
+ code += " }\n";
+ code += " albedo_tex.rgb = vec3(1.0);\n";
+ code += " }\n";
+ } else if (flags[FLAG_ALBEDO_TEXTURE_FORCE_SRGB]) {
code += " albedo_tex.rgb = mix(pow((albedo_tex.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex.rgb.rgb * (1.0 / 12.92),lessThan(albedo_tex.rgb,vec3(0.04045)));\n";
}
@@ -1777,6 +1812,14 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
property.usage = PROPERTY_USAGE_NO_EDITOR;
}
+ if (property.name == "msdf_pixel_range" && !flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ property.usage = PROPERTY_USAGE_NO_EDITOR;
+ }
+
+ if (property.name == "msdf_outline_size" && !flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ property.usage = PROPERTY_USAGE_NO_EDITOR;
+ }
+
if ((property.name == "distance_fade_max_distance" || property.name == "distance_fade_min_distance") && distance_fade == DISTANCE_FADE_DISABLED) {
property.usage = PROPERTY_USAGE_NO_EDITOR;
}
@@ -2125,35 +2168,45 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel()
return refraction_texture_channel;
}
-Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y, RID *r_shader_rid) {
- int version = 0;
+Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, RID *r_shader_rid) {
+ int64_t hash = 0;
if (p_shaded) {
- version = 1;
+ hash |= 1 << 0;
}
if (p_transparent) {
- version |= 2;
+ hash |= 1 << 1;
}
if (p_cut_alpha) {
- version |= 4;
+ hash |= 1 << 2;
}
if (p_opaque_prepass) {
- version |= 8;
+ hash |= 1 << 3;
}
if (p_double_sided) {
- version |= 16;
+ hash |= 1 << 4;
}
if (p_billboard) {
- version |= 32;
+ hash |= 1 << 5;
}
if (p_billboard_y) {
- version |= 64;
+ hash |= 1 << 6;
+ }
+ if (p_msdf) {
+ hash |= 1 << 7;
}
+ if (p_no_depth) {
+ hash |= 1 << 8;
+ }
+ if (p_fixed_size) {
+ hash |= 1 << 9;
+ }
+ hash = hash_djb2_one_64(p_filter, hash);
- if (materials_for_2d[version].is_valid()) {
+ if (materials_for_2d.has(hash)) {
if (r_shader_rid) {
- *r_shader_rid = materials_for_2d[version]->get_shader_rid();
+ *r_shader_rid = materials_for_2d[hash]->get_shader_rid();
}
- return materials_for_2d[version];
+ return materials_for_2d[hash];
}
Ref<StandardMaterial3D> material;
@@ -2164,18 +2217,22 @@ Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, bool p_transpar
material->set_cull_mode(p_double_sided ? CULL_DISABLED : CULL_BACK);
material->set_flag(FLAG_SRGB_VERTEX_COLOR, true);
material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ material->set_flag(FLAG_ALBEDO_TEXTURE_MSDF, p_msdf);
+ material->set_flag(FLAG_DISABLE_DEPTH_TEST, p_no_depth);
+ material->set_flag(FLAG_FIXED_SIZE, p_fixed_size);
+ material->set_texture_filter(p_filter);
if (p_billboard || p_billboard_y) {
material->set_flag(FLAG_BILLBOARD_KEEP_SCALE, true);
material->set_billboard_mode(p_billboard_y ? BILLBOARD_FIXED_Y : BILLBOARD_ENABLED);
}
- materials_for_2d[version] = material;
+ materials_for_2d[hash] = material;
if (r_shader_rid) {
- *r_shader_rid = materials_for_2d[version]->get_shader_rid();
+ *r_shader_rid = materials_for_2d[hash]->get_shader_rid();
}
- return materials_for_2d[version];
+ return materials_for_2d[hash];
}
void BaseMaterial3D::set_on_top_of_alpha() {
@@ -2203,6 +2260,24 @@ float BaseMaterial3D::get_proximity_fade_distance() const {
return proximity_fade_distance;
}
+void BaseMaterial3D::set_msdf_pixel_range(float p_range) {
+ msdf_pixel_range = p_range;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->msdf_pixel_range, p_range);
+}
+
+float BaseMaterial3D::get_msdf_pixel_range() const {
+ return msdf_pixel_range;
+}
+
+void BaseMaterial3D::set_msdf_outline_size(float p_size) {
+ msdf_outline_size = p_size;
+ RS::get_singleton()->material_set_param(_get_material(), shader_names->msdf_outline_size, p_size);
+}
+
+float BaseMaterial3D::get_msdf_outline_size() const {
+ return msdf_outline_size;
+}
+
void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) {
distance_fade = p_mode;
_queue_shader_change();
@@ -2445,6 +2520,12 @@ void BaseMaterial3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_proximity_fade_distance", "distance"), &BaseMaterial3D::set_proximity_fade_distance);
ClassDB::bind_method(D_METHOD("get_proximity_fade_distance"), &BaseMaterial3D::get_proximity_fade_distance);
+ ClassDB::bind_method(D_METHOD("set_msdf_pixel_range", "range"), &BaseMaterial3D::set_msdf_pixel_range);
+ ClassDB::bind_method(D_METHOD("get_msdf_pixel_range"), &BaseMaterial3D::get_msdf_pixel_range);
+
+ ClassDB::bind_method(D_METHOD("set_msdf_outline_size", "size"), &BaseMaterial3D::set_msdf_outline_size);
+ ClassDB::bind_method(D_METHOD("get_msdf_outline_size"), &BaseMaterial3D::get_msdf_outline_size);
+
ClassDB::bind_method(D_METHOD("set_distance_fade", "mode"), &BaseMaterial3D::set_distance_fade);
ClassDB::bind_method(D_METHOD("get_distance_fade"), &BaseMaterial3D::get_distance_fade);
@@ -2479,6 +2560,7 @@ void BaseMaterial3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo_color"), "set_albedo", "get_albedo");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ALBEDO);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "albedo_tex_msdf"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_MSDF);
ADD_GROUP("ORM", "orm_");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orm_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ORM);
@@ -2616,6 +2698,9 @@ void BaseMaterial3D::_bind_methods() {
ADD_GROUP("Proximity Fade", "proximity_fade_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "proximity_fade_enable"), "set_proximity_fade", "is_proximity_fade_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_proximity_fade_distance", "get_proximity_fade_distance");
+ ADD_GROUP("MSDF", "msdf_");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "msdf_pixel_range", PROPERTY_HINT_RANGE, "1,100,1"), "set_msdf_pixel_range", "get_msdf_pixel_range");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "msdf_outline_size", PROPERTY_HINT_RANGE, "1,250,1"), "set_msdf_outline_size", "get_msdf_outline_size");
ADD_GROUP("Distance Fade", "distance_fade_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "distance_fade_mode", PROPERTY_HINT_ENUM, "Disabled,PixelAlpha,PixelDither,ObjectDither"), "set_distance_fade", "get_distance_fade");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_min_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_distance_fade_min_distance", "get_distance_fade_min_distance");
@@ -2715,6 +2800,7 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_INVERT_HEIGHTMAP);
BIND_ENUM_CONSTANT(FLAG_SUBSURFACE_MODE_SKIN);
BIND_ENUM_CONSTANT(FLAG_PARTICLE_TRAILS_MODE);
+ BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_MSDF);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);
@@ -2804,6 +2890,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
set_heightmap_deep_parallax_max_layers(32);
set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal
+ flags[FLAG_ALBEDO_TEXTURE_MSDF] = false;
flags[FLAG_USE_TEXTURE_REPEAT] = true;
is_initialized = true;
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 07227c037c..99e125f5b0 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -242,6 +242,7 @@ public:
FLAG_INVERT_HEIGHTMAP,
FLAG_SUBSURFACE_MODE_SKIN,
FLAG_PARTICLE_TRAILS_MODE,
+ FLAG_ALBEDO_TEXTURE_MSDF,
FLAG_MAX
};
@@ -412,6 +413,8 @@ private:
StringName uv2_blend_sharpness;
StringName grow;
StringName proximity_fade_distance;
+ StringName msdf_pixel_range;
+ StringName msdf_outline_size;
StringName distance_fade_min;
StringName distance_fade_max;
StringName ao_light_affect;
@@ -500,6 +503,9 @@ private:
bool proximity_fade_enabled = false;
float proximity_fade_distance;
+ float msdf_pixel_range = 4.f;
+ float msdf_outline_size = 0.f;
+
DistanceFadeMode distance_fade = DISTANCE_FADE_DISABLED;
float distance_fade_max_distance;
float distance_fade_min_distance;
@@ -527,9 +533,7 @@ private:
_FORCE_INLINE_ void _validate_feature(const String &text, Feature feature, PropertyInfo &property) const;
- static const int MAX_MATERIALS_FOR_2D = 128;
-
- static Ref<StandardMaterial3D> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff
+ static HashMap<uint64_t, Ref<StandardMaterial3D>> materials_for_2d; //used by Sprite3D, Label3D and other stuff
void _validate_high_end(const String &text, PropertyInfo &property) const;
@@ -714,6 +718,12 @@ public:
void set_proximity_fade_distance(float p_distance);
float get_proximity_fade_distance() const;
+ void set_msdf_pixel_range(float p_range);
+ float get_msdf_pixel_range() const;
+
+ void set_msdf_outline_size(float p_size);
+ float get_msdf_outline_size() const;
+
void set_distance_fade(DistanceFadeMode p_mode);
DistanceFadeMode get_distance_fade() const;
@@ -739,7 +749,7 @@ public:
static void finish_shaders();
static void flush_changes();
- static Ref<Material> get_material_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false, RID *r_shader_rid = nullptr);
+ static Ref<Material> get_material_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false, bool p_msdf = false, bool p_no_depth = false, bool p_fixed_size = false, TextureFilter p_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RID *r_shader_rid = nullptr);
virtual RID get_shader_rid() const override;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index b1c2702a1e..b991cb1abe 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -310,6 +310,9 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
NODE_FROM_ID(owner, n.owner);
if (owner) {
node->_set_owner_nocheck(owner);
+ if (node->data.unique_name_in_owner) {
+ node->_acquire_unique_name_in_owner();
+ }
}
}
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 4b0456681b..b18456d464 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -898,6 +898,8 @@ Error ResourceLoaderText::rename_dependencies(Ref<FileAccess> p_f, const String
return ERR_CANT_CREATE;
}
+ fw.unref();
+
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
da->remove(p_path);
da->rename(p_path + ".depren", p_path);
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index fe52761482..f3cb2b9ea7 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -124,8 +124,8 @@ void StyleBox::_bind_methods() {
ADD_GROUP("Content Margin", "content_margin_");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_left", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", SIDE_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_right", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_top", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", SIDE_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_right", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_bottom", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", SIDE_BOTTOM);
GDVIRTUAL_BIND(_get_style_margin, "side")
@@ -316,19 +316,23 @@ void StyleBoxTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
+
ADD_GROUP("Margin", "margin_");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", SIDE_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", SIDE_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", SIDE_BOTTOM);
+
ADD_GROUP("Expand Margin", "expand_margin_");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", SIDE_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", SIDE_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", SIDE_BOTTOM);
+
ADD_GROUP("Axis Stretch", "axis_stretch_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_horizontal", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_h_axis_stretch_mode", "get_h_axis_stretch_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_vertical", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_v_axis_stretch_mode", "get_v_axis_stretch_mode");
+
ADD_GROUP("Modulate", "modulate_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate_color"), "set_modulate", "get_modulate");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled");
@@ -457,6 +461,15 @@ bool StyleBoxFlat::is_draw_center_enabled() const {
return draw_center;
}
+void StyleBoxFlat::set_skew(Vector2 p_skew) {
+ skew = p_skew;
+ emit_changed();
+}
+
+Vector2 StyleBoxFlat::get_skew() const {
+ return skew;
+}
+
void StyleBoxFlat::set_shadow_color(const Color &p_color) {
shadow_color = p_color;
emit_changed();
@@ -542,7 +555,7 @@ inline void set_inner_corner_radius(const Rect2 style_rect, const Rect2 inner_re
}
inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color> &colors, const Rect2 &style_rect, const real_t corner_radius[4],
- const Rect2 &ring_rect, const Rect2 &inner_rect, const Color &inner_color, const Color &outer_color, const int corner_detail, const bool fill_center = false) {
+ const Rect2 &ring_rect, const Rect2 &inner_rect, const Color &inner_color, const Color &outer_color, const int corner_detail, const Vector2 &skew, bool fill_center = false) {
int vert_offset = verts.size();
if (!vert_offset) {
vert_offset = 0;
@@ -586,9 +599,12 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color
color = outer_color;
corner_point = outer_points[corner_index];
}
- real_t x = radius * (real_t)cos((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.x;
- real_t y = radius * (real_t)sin((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.y;
- verts.push_back(Vector2(x, y));
+
+ const real_t x = radius * (real_t)cos((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.x;
+ const real_t y = radius * (real_t)sin((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.y;
+ const float x_skew = -skew.x * (y - ring_rect.get_center().y);
+ const float y_skew = -skew.y * (x - ring_rect.get_center().x);
+ verts.push_back(Vector2(x + x_skew, y + y_skew));
colors.push_back(color);
}
}
@@ -666,10 +682,12 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
return;
}
- bool rounded_corners = (corner_radius[0] > 0) || (corner_radius[1] > 0) || (corner_radius[2] > 0) || (corner_radius[3] > 0);
- bool aa_on = rounded_corners && anti_aliased;
+ const bool rounded_corners = (corner_radius[0] > 0) || (corner_radius[1] > 0) || (corner_radius[2] > 0) || (corner_radius[3] > 0);
+ // Only enable antialiasing if it is actually needed. This improve performances
+ // and maximizes sharpness for non-skewed StyleBoxes with sharp corners.
+ const bool aa_on = (rounded_corners || !skew.is_equal_approx(Vector2())) && anti_aliased;
- bool blend_on = blend_border && draw_border;
+ const bool blend_on = blend_border && draw_border;
Color border_color_alpha = Color(border_color.r, border_color.g, border_color.b, 0);
Color border_color_blend = (draw_center ? bg_color : border_color_alpha);
@@ -716,24 +734,24 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
Color shadow_color_transparent = Color(shadow_color.r, shadow_color.g, shadow_color.b, 0);
draw_ring(verts, indices, colors, shadow_inner_rect, adapted_corner,
- shadow_rect, shadow_inner_rect, shadow_color, shadow_color_transparent, corner_detail);
+ shadow_rect, shadow_inner_rect, shadow_color, shadow_color_transparent, corner_detail, skew);
if (draw_center) {
draw_ring(verts, indices, colors, shadow_inner_rect, adapted_corner,
- shadow_inner_rect, shadow_inner_rect, shadow_color, shadow_color, corner_detail, true);
+ shadow_inner_rect, shadow_inner_rect, shadow_color, shadow_color, corner_detail, skew, true);
}
}
// Create border (no AA).
if (draw_border && !aa_on) {
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
- border_style_rect, infill_rect, border_color_inner, border_color, corner_detail);
+ border_style_rect, infill_rect, border_color_inner, border_color, corner_detail, skew);
}
// Create infill (no AA).
if (draw_center && (!aa_on || blend_on || !draw_border)) {
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
- infill_rect, infill_rect, bg_color, bg_color, corner_detail, true);
+ infill_rect, infill_rect, bg_color, bg_color, corner_detail, skew, true);
}
if (aa_on) {
@@ -765,7 +783,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
aa_border_width[SIDE_RIGHT], aa_border_width[SIDE_BOTTOM]);
// Create infill within AA border.
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
- infill_inner_rect_aa, infill_inner_rect_aa, bg_color, bg_color, corner_detail, true);
+ infill_inner_rect_aa, infill_inner_rect_aa, bg_color, bg_color, corner_detail, skew, true);
}
if (!blend_on || !draw_border) {
@@ -776,7 +794,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
// Create infill fake AA gradient.
draw_ring(verts, indices, colors, style_rect, adapted_corner,
- infill_rect_aa, infill_rect, bg_color, alpha_bg, corner_detail);
+ infill_rect_aa, infill_rect, bg_color, alpha_bg, corner_detail, skew);
}
}
@@ -790,17 +808,17 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
// Create border.
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
- border_style_rect_aa, ((blend_on) ? infill_rect : infill_rect_aa), border_color_inner, border_color, corner_detail);
+ border_style_rect_aa, ((blend_on) ? infill_rect : infill_rect_aa), border_color_inner, border_color, corner_detail, skew);
if (!blend_on) {
// Create inner border fake AA gradient.
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
- infill_rect_aa, infill_rect, border_color_blend, border_color, corner_detail);
+ infill_rect_aa, infill_rect, border_color_blend, border_color, corner_detail, skew);
}
// Create outer border fake AA gradient.
draw_ring(verts, indices, colors, border_style_rect, adapted_corner,
- style_rect_aa, border_style_rect_aa, border_color, border_color_alpha, corner_detail);
+ style_rect_aa, border_style_rect_aa, border_color, border_color_alpha, corner_detail, skew);
}
}
@@ -858,6 +876,9 @@ void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_draw_center", "draw_center"), &StyleBoxFlat::set_draw_center);
ClassDB::bind_method(D_METHOD("is_draw_center_enabled"), &StyleBoxFlat::is_draw_center_enabled);
+ ClassDB::bind_method(D_METHOD("set_skew", "skew"), &StyleBoxFlat::set_skew);
+ ClassDB::bind_method(D_METHOD("get_skew"), &StyleBoxFlat::get_skew);
+
ClassDB::bind_method(D_METHOD("set_shadow_color", "color"), &StyleBoxFlat::set_shadow_color);
ClassDB::bind_method(D_METHOD("get_shadow_color"), &StyleBoxFlat::get_shadow_color);
@@ -879,6 +900,7 @@ void StyleBoxFlat::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "bg_color"), "set_bg_color", "get_bg_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "skew"), "set_skew", "get_skew");
ADD_GROUP("Border Width", "border_width_");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_left", PROPERTY_HINT_RANGE, "0,1024,1"), "set_border_width", "get_border_width", SIDE_LEFT);
@@ -901,8 +923,8 @@ void StyleBoxFlat::_bind_methods() {
ADD_GROUP("Expand Margin", "expand_margin_");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", SIDE_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", SIDE_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", SIDE_BOTTOM);
ADD_GROUP("Shadow", "shadow_");
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 68ad41b69c..3b3654775f 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -155,6 +155,7 @@ class StyleBoxFlat : public StyleBox {
bool draw_center = true;
bool blend_border = false;
+ Vector2 skew;
bool anti_aliased = true;
int corner_detail = 8;
@@ -200,6 +201,9 @@ public:
void set_draw_center(bool p_enabled);
bool is_draw_center_enabled() const;
+ void set_skew(Vector2 p_skew);
+ Vector2 get_skew() const;
+
void set_shadow_color(const Color &p_color);
Color get_shadow_color() const;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 4c20e07976..14abe13afa 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -2278,6 +2278,8 @@ Ref<Image> GradientTexture1D::get_image() const {
return RenderingServer::get_singleton()->texture_2d_get(texture);
}
+//////////////////
+
GradientTexture2D::GradientTexture2D() {
_queue_update();
}
@@ -2299,7 +2301,8 @@ void GradientTexture2D::set_gradient(Ref<Gradient> p_gradient) {
if (gradient.is_valid()) {
gradient->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture2D::_queue_update));
}
- _queue_update();
+ _update();
+ emit_changed();
}
Ref<Gradient> GradientTexture2D::get_gradient() const {