diff options
Diffstat (limited to 'scene/resources')
43 files changed, 1832 insertions, 383 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index b6151bccf4..f6e0df0265 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -2320,22 +2320,12 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a if (vformat == ((1 << Variant::INT) | (1 << Variant::FLOAT)) || vformat == (1 << Variant::FLOAT)) { //mix of real and int + real_t a = p_a; + real_t b = p_b; + real_t pa = p_pre_a; + real_t pb = p_post_b; - real_t p0 = p_pre_a; - real_t p1 = p_a; - real_t p2 = p_b; - real_t p3 = p_post_b; - - real_t t = p_c; - real_t t2 = t * t; - real_t t3 = t2 * t; - - return 0.5f * - ((p1 * 2.0f) + - (-p0 + p2) * t + - (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 + - (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3); - + return Math::cubic_interpolate(a, b, pa, pb, p_c); } else if ((vformat & (vformat - 1))) { return p_a; //can't interpolate, mix of types } @@ -2423,7 +2413,7 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol real_t c = 0.0; // prepare for all cases of interpolation - if ((loop_mode == LOOP_LINEAR || loop_mode == LOOP_PINGPONG) && p_loop_wrap) { + if (loop_mode == LOOP_LINEAR && p_loop_wrap) { // loop if (!p_backward) { // no backward @@ -2577,11 +2567,19 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol case INTERPOLATION_CUBIC: { int pre = idx - 1; if (pre < 0) { - pre = 0; + if (loop_mode == LOOP_LINEAR && p_loop_wrap) { + pre = len - 1; + } else { + pre = 0; + } } int post = next + 1; if (post >= len) { - post = next; + if (loop_mode == LOOP_LINEAR && p_loop_wrap) { + post = 0; + } else { + post = next; + } } return _cubic_interpolate(p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c); @@ -4349,7 +4347,7 @@ struct AnimationCompressionDataState { if (temp_packets.size() == 0) { return; //nohing to do } -#define DEBUG_PACKET_PUSH +//#define DEBUG_PACKET_PUSH #ifdef DEBUG_PACKET_PUSH #ifndef _MSC_VER #warning Debugging packet push, disable this code in production to gain a bit more import performance. @@ -4380,7 +4378,7 @@ struct AnimationCompressionDataState { header_bytes += 2; } - while (header_bytes % 4 != 0) { + while (header_bytes < 8 && header_bytes % 4 != 0) { // First cond needed to silence wrong GCC warning. header[header_bytes++] = 0; } diff --git a/scene/resources/box_shape_3d.cpp b/scene/resources/box_shape_3d.cpp index a1ec9a2230..1abbf366fd 100644 --- a/scene/resources/box_shape_3d.cpp +++ b/scene/resources/box_shape_3d.cpp @@ -77,6 +77,7 @@ bool BoxShape3D::_get(const StringName &p_name, Variant &r_property) const { #endif // DISABLE_DEPRECATED void BoxShape3D::set_size(const Vector3 &p_size) { + ERR_FAIL_COND_MSG(p_size.x < 0 || p_size.y < 0 || p_size.z < 0, "BoxShape3D size cannot be negative."); size = p_size; _update_shape(); notify_change_to_owners(); diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp index 4d2698d27d..a1ad487bff 100644 --- a/scene/resources/capsule_shape_2d.cpp +++ b/scene/resources/capsule_shape_2d.cpp @@ -59,6 +59,7 @@ void CapsuleShape2D::_update_shape() { } void CapsuleShape2D::set_radius(real_t p_radius) { + ERR_FAIL_COND_MSG(p_radius < 0, "CapsuleShape2D radius cannot be negative."); radius = p_radius; if (radius > height * 0.5) { height = radius * 2.0; @@ -71,6 +72,7 @@ real_t CapsuleShape2D::get_radius() const { } void CapsuleShape2D::set_height(real_t p_height) { + ERR_FAIL_COND_MSG(p_height < 0, "CapsuleShape2D height cannot be negative."); height = p_height; if (radius > height * 0.5) { radius = height * 0.5; diff --git a/scene/resources/capsule_shape_3d.cpp b/scene/resources/capsule_shape_3d.cpp index c16ddad984..2179ce82dd 100644 --- a/scene/resources/capsule_shape_3d.cpp +++ b/scene/resources/capsule_shape_3d.cpp @@ -79,6 +79,7 @@ void CapsuleShape3D::_update_shape() { } void CapsuleShape3D::set_radius(float p_radius) { + ERR_FAIL_COND_MSG(p_radius < 0, "CapsuleShape3D radius cannot be negative."); radius = p_radius; if (radius > height * 0.5) { height = radius * 2.0; @@ -92,6 +93,7 @@ float CapsuleShape3D::get_radius() const { } void CapsuleShape3D::set_height(float p_height) { + ERR_FAIL_COND_MSG(p_height < 0, "CapsuleShape3D height cannot be negative."); height = p_height; if (radius > height * 0.5) { radius = height * 0.5; diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp index 9c16ac2eed..de931fca7e 100644 --- a/scene/resources/circle_shape_2d.cpp +++ b/scene/resources/circle_shape_2d.cpp @@ -43,6 +43,7 @@ void CircleShape2D::_update_shape() { } void CircleShape2D::set_radius(real_t p_radius) { + ERR_FAIL_COND_MSG(p_radius < 0, "CircleShape2D radius cannot be negative."); radius = p_radius; _update_shape(); } diff --git a/scene/resources/cylinder_shape_3d.cpp b/scene/resources/cylinder_shape_3d.cpp index 5eeb62d17b..c4f1cba341 100644 --- a/scene/resources/cylinder_shape_3d.cpp +++ b/scene/resources/cylinder_shape_3d.cpp @@ -72,6 +72,7 @@ void CylinderShape3D::_update_shape() { } void CylinderShape3D::set_radius(float p_radius) { + ERR_FAIL_COND_MSG(p_radius < 0, "CylinderShape3D radius cannot be negative."); radius = p_radius; _update_shape(); notify_change_to_owners(); @@ -82,6 +83,7 @@ float CylinderShape3D::get_radius() const { } void CylinderShape3D::set_height(float p_height) { + ERR_FAIL_COND_MSG(p_height < 0, "CylinderShape3D height cannot be negative."); height = p_height; _update_shape(); notify_change_to_owners(); diff --git a/scene/resources/default_theme/color_picker_sample.svg b/scene/resources/default_theme/color_picker_sample.svg deleted file mode 100644 index 140ac20a99..0000000000 --- a/scene/resources/default_theme/color_picker_sample.svg +++ /dev/null @@ -1 +0,0 @@ -<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 256 20" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m0 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m5 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m80 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m85 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m159.978 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m164.978 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m39.991 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m44.991 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m119.99 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m124.99 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m199.968 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m204.968 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m9.98 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m14.98 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m89.98 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m94.98 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m169.957 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m174.957 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m49.97 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m54.97 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m129.97 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m134.97 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m209.948 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m214.948 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m19.995 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m24.995 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m99.995 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m104.995 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m179.973 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m184.973 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m59.986 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m64.986 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m139.986 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m144.986 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m219.964 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m224.964 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m30.011 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m35.011 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m110.011 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m115.011 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m189.989 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m194.989 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m70.001 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m75.001 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m150.001 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m155.001 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m229.979 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m234.979 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m240.017 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m245.017 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m249.996 0v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m254.996 0v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m249.996 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m254.996 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m240.017 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m245.017 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m0 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m5 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m80 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m85 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m159.978 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m164.978 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m39.991 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m44.991 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m119.99 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m124.99 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m199.968 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m204.968 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m9.98 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m14.98 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m89.98 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m94.98 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m169.957 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m174.957 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m49.97 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m54.97 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m129.97 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m134.97 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m209.948 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m214.948 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m19.995 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m24.995 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m99.995 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m104.995 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m179.973 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m184.973 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m59.986 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m64.986 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m139.986 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m144.986 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m219.964 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m224.964 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m30.011 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m35.011 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m110.011 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m115.011 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m189.989 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m194.989 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m70.001 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m75.001 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m150.001 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m155.001 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/><path d="m229.979 10v5h5v-5zm5 5v5h5v-5z" fill="#e0e0e0"/><path d="m234.979 10v5h5v-5zm0 5h-5v5h5z" fill="#fff"/></g></svg> diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index c92a46a98c..da37228ed9 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -103,7 +103,7 @@ static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margi return style; } -void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale) { +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) { scale = p_scale; // Font colors @@ -466,7 +466,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te theme->set_color("completion_background_color", "CodeEdit", Color(0.17, 0.16, 0.2)); theme->set_color("completion_selected_color", "CodeEdit", Color(0.26, 0.26, 0.27)); theme->set_color("completion_existing_color", "CodeEdit", Color(0.87, 0.87, 0.87, 0.13)); - theme->set_color("completion_scroll_color", "CodeEdit", control_font_pressed_color); + theme->set_color("completion_scroll_color", "CodeEdit", control_font_pressed_color * Color(1, 1, 1, 0.29)); theme->set_color("completion_font_color", "CodeEdit", Color(0.67, 0.67, 0.67)); theme->set_color("font_color", "CodeEdit", control_font_color); theme->set_color("font_selected_color", "CodeEdit", Color(0, 0, 0)); @@ -490,7 +490,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te theme->set_constant("completion_lines", "CodeEdit", 7); theme->set_constant("completion_max_width", "CodeEdit", 50); - theme->set_constant("completion_scroll_width", "CodeEdit", 3); + theme->set_constant("completion_scroll_width", "CodeEdit", 6); theme->set_constant("line_spacing", "CodeEdit", 4 * scale); theme->set_constant("outline_size", "CodeEdit", 0); @@ -864,7 +864,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te theme->set_icon("screen_picker", "ColorPicker", icons["color_picker_pipette"]); theme->set_icon("add_preset", "ColorPicker", icons["add"]); theme->set_icon("color_hue", "ColorPicker", icons["color_picker_hue"]); - theme->set_icon("color_sample", "ColorPicker", icons["color_picker_sample"]); theme->set_icon("sample_bg", "ColorPicker", icons["mini_checkerboard"]); theme->set_icon("overbright_indicator", "ColorPicker", icons["color_picker_overbright"]); theme->set_icon("bar_arrow", "ColorPicker", icons["color_picker_bar_arrow"]); @@ -925,9 +924,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te theme->set_stylebox("normal", "RichTextLabel", make_empty_stylebox(0, 0, 0, 0)); theme->set_font("normal_font", "RichTextLabel", Ref<Font>()); - theme->set_font("bold_font", "RichTextLabel", Ref<Font>()); - theme->set_font("italics_font", "RichTextLabel", Ref<Font>()); - theme->set_font("bold_italics_font", "RichTextLabel", Ref<Font>()); + theme->set_font("bold_font", "RichTextLabel", bold_font); + theme->set_font("italics_font", "RichTextLabel", italics_font); + theme->set_font("bold_italics_font", "RichTextLabel", bold_italics_font); theme->set_font("mono_font", "RichTextLabel", Ref<Font>()); theme->set_font_size("normal_font_size", "RichTextLabel", -1); @@ -1019,13 +1018,16 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te 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) { +void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_subpixel, TextServer::Hinting p_hinting, bool p_aa) { Ref<Theme> t; t.instantiate(); Ref<StyleBox> default_style; Ref<Texture2D> default_icon; Ref<Font> default_font; + Ref<Font> bold_font; + Ref<Font> bold_italics_font; + Ref<Font> italics_font; float default_scale = CLAMP(p_scale, 0.5, 8.0); if (p_font.is_valid()) { @@ -1041,12 +1043,39 @@ void make_default_theme(float p_scale, Ref<Font> p_font) { 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->add_data(dynamic_font_data); default_font = dynamic_font; } - fill_default_theme(t, default_font, default_icon, default_style, default_scale); + if (default_font.is_valid()) { + bold_font.instantiate(); + for (int i = 0; i < default_font->get_data_count(); i++) { + Ref<FontData> data = default_font->get_data(i)->duplicate(); + data->set_embolden(1.2); + bold_font->add_data(data); + } + + bold_italics_font.instantiate(); + for (int i = 0; i < default_font->get_data_count(); i++) { + Ref<FontData> data = default_font->get_data(i)->duplicate(); + data->set_embolden(1.2); + data->set_transform(Transform2D(1.0, 0.4, 0.0, 1.0, 0.0, 0.0)); + bold_italics_font->add_data(data); + } + + italics_font.instantiate(); + for (int i = 0; i < default_font->get_data_count(); i++) { + Ref<FontData> data = default_font->get_data(i)->duplicate(); + data->set_transform(Transform2D(1.0, 0.4, 0.0, 1.0, 0.0, 0.0)); + italics_font->add_data(data); + } + } + + fill_default_theme(t, default_font, bold_font, bold_italics_font, italics_font, default_icon, default_style, default_scale); Theme::set_default(t); Theme::set_fallback_base_scale(default_scale); diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h index 3016517824..a9e21dda3f 100644 --- a/scene/resources/default_theme/default_theme.h +++ b/scene/resources/default_theme/default_theme.h @@ -35,8 +35,8 @@ const int default_font_size = 16; -void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale); -void make_default_theme(float p_scale, Ref<Font> p_font); +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 clear_default_theme(); #endif diff --git a/scene/resources/default_theme/mini_checkerboard.svg b/scene/resources/default_theme/mini_checkerboard.svg index 0ae6a855bd..03438f75a6 100644 --- a/scene/resources/default_theme/mini_checkerboard.svg +++ b/scene/resources/default_theme/mini_checkerboard.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.9994"><path d="m0 0v8h8v-8zm8 8v8h8v-8z" fill="#e0e0e0"/><path d="m8 0v8h8v-8zm0 8h-8v8h8z" fill="#fff"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="2"><path d="m0 0v8h8v-8zm8 8v8h8v-8z" fill="#808080"/><path d="m8 0v8h8v-8zm0 8h-8v8h8z" fill="#fff"/></g></svg> diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index b13ae9d016..82d8ad4444 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -155,7 +155,9 @@ float Environment::get_ambient_light_energy() const { } void Environment::set_ambient_light_sky_contribution(float p_ratio) { - ambient_sky_contribution = p_ratio; + // Sky contribution values outside the [0.0; 1.0] range don't make sense and + // can result in negative colors. + ambient_sky_contribution = CLAMP(p_ratio, 0.0, 1.0); _update_ambient_light(); } @@ -1332,7 +1334,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_min_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_sdfgi_min_cell_size", "get_sdfgi_min_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_max_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_max_distance", "get_sdfgi_max_distance"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_y_scale", PROPERTY_HINT_ENUM, "Disable,75%,50%"), "set_sdfgi_y_scale", "get_sdfgi_y_scale"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_y_scale", PROPERTY_HINT_ENUM, "50% (Compact),75% (Balanced),100% (Sparse)"), "set_sdfgi_y_scale", "get_sdfgi_y_scale"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_energy"), "set_sdfgi_energy", "get_sdfgi_energy"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_normal_bias"), "set_sdfgi_normal_bias", "get_sdfgi_normal_bias"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_probe_bias"), "set_sdfgi_probe_bias", "get_sdfgi_probe_bias"); @@ -1511,9 +1513,9 @@ void Environment::_bind_methods() { BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_MIX); - BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_DISABLED); - BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_75_PERCENT); BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_50_PERCENT); + BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_75_PERCENT); + BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_100_PERCENT); } Environment::Environment() { diff --git a/scene/resources/environment.h b/scene/resources/environment.h index b04723a221..b71fe8904a 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -34,7 +34,6 @@ #include "core/io/resource.h" #include "scene/resources/sky.h" #include "scene/resources/texture.h" -#include "servers/rendering_server.h" class Environment : public Resource { GDCLASS(Environment, Resource); @@ -71,9 +70,9 @@ public: }; enum SDFGIYScale { - SDFGI_Y_SCALE_DISABLED, - SDFGI_Y_SCALE_75_PERCENT, SDFGI_Y_SCALE_50_PERCENT, + SDFGI_Y_SCALE_75_PERCENT, + SDFGI_Y_SCALE_100_PERCENT, }; enum GlowBlendMode { @@ -147,12 +146,12 @@ private: // SDFGI bool sdfgi_enabled = false; - int sdfgi_cascades = 6; + int sdfgi_cascades = 4; float sdfgi_min_cell_size = 0.2; - SDFGIYScale sdfgi_y_scale = SDFGI_Y_SCALE_DISABLED; + SDFGIYScale sdfgi_y_scale = SDFGI_Y_SCALE_75_PERCENT; bool sdfgi_use_occlusion = false; - float sdfgi_bounce_feedback = 0.0; - bool sdfgi_read_sky_light = false; + float sdfgi_bounce_feedback = 0.5; + bool sdfgi_read_sky_light = true; float sdfgi_energy = 1.0; float sdfgi_normal_bias = 1.1; float sdfgi_probe_bias = 1.1; diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index b512acdd8a..ce2a675854 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -60,6 +60,9 @@ _FORCE_INLINE_ void FontData::_ensure_rid(int p_cache_index) const { TS->font_set_fixed_size(cache[p_cache_index], fixed_size); TS->font_set_force_autohinter(cache[p_cache_index], force_autohinter); TS->font_set_hinting(cache[p_cache_index], hinting); + TS->font_set_subpixel_positioning(cache[p_cache_index], subpixel_positioning); + TS->font_set_embolden(cache[p_cache_index], embolden); + TS->font_set_transform(cache[p_cache_index], transform); TS->font_set_oversampling(cache[p_cache_index], oversampling); } } @@ -101,6 +104,15 @@ void FontData::_bind_methods() { ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &FontData::set_hinting); ClassDB::bind_method(D_METHOD("get_hinting"), &FontData::get_hinting); + ClassDB::bind_method(D_METHOD("set_subpixel_positioning", "subpixel_positioning"), &FontData::set_subpixel_positioning); + ClassDB::bind_method(D_METHOD("get_subpixel_positioning"), &FontData::get_subpixel_positioning); + + ClassDB::bind_method(D_METHOD("set_embolden", "strength"), &FontData::set_embolden); + ClassDB::bind_method(D_METHOD("get_embolden"), &FontData::get_embolden); + + ClassDB::bind_method(D_METHOD("set_transform", "transform"), &FontData::set_transform); + ClassDB::bind_method(D_METHOD("get_transform"), &FontData::get_transform); + ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &FontData::set_oversampling); ClassDB::bind_method(D_METHOD("get_oversampling"), &FontData::get_oversampling); @@ -204,6 +216,9 @@ void FontData::_bind_methods() { 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"); ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style", "get_font_style"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_STORAGE), "set_subpixel_positioning", "get_subpixel_positioning"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_RANGE, "-2,2,0.01", PROPERTY_USAGE_STORAGE), "set_embolden", "get_embolden"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field"); ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_pixel_range", "get_msdf_pixel_range"); ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_size", "get_msdf_size"); @@ -430,9 +445,12 @@ void FontData::reset_state() { msdf = false; force_autohinter = false; hinting = TextServer::HINTING_LIGHT; + subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED; msdf_pixel_range = 14; msdf_size = 128; fixed_size = 0; + embolden = 0.f; + transform = Transform2D(); oversampling = 0.f; } @@ -1364,6 +1382,51 @@ TextServer::Hinting FontData::get_hinting() const { return hinting; } +void FontData::set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel) { + if (subpixel_positioning != p_subpixel) { + subpixel_positioning = p_subpixel; + for (int i = 0; i < cache.size(); i++) { + _ensure_rid(i); + TS->font_set_subpixel_positioning(cache[i], subpixel_positioning); + } + emit_changed(); + } +} + +TextServer::SubpixelPositioning FontData::get_subpixel_positioning() const { + return subpixel_positioning; +} + +void FontData::set_embolden(float p_strength) { + if (embolden != p_strength) { + embolden = p_strength; + for (int i = 0; i < cache.size(); i++) { + _ensure_rid(i); + TS->font_set_embolden(cache[i], embolden); + } + emit_changed(); + } +} + +float FontData::get_embolden() const { + return embolden; +} + +void FontData::set_transform(Transform2D p_transform) { + if (transform != p_transform) { + transform = p_transform; + for (int i = 0; i < cache.size(); i++) { + _ensure_rid(i); + TS->font_set_transform(cache[i], transform); + } + emit_changed(); + } +} + +Transform2D FontData::get_transform() const { + return transform; +} + void FontData::set_oversampling(real_t p_oversampling) { if (oversampling != p_oversampling) { oversampling = p_oversampling; diff --git a/scene/resources/font.h b/scene/resources/font.h index 93351a3493..0185b019f1 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -55,7 +55,10 @@ class FontData : public Resource { int fixed_size = 0; bool force_autohinter = false; TextServer::Hinting hinting = TextServer::HINTING_LIGHT; + TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; real_t oversampling = 0.f; + real_t embolden = 0.f; + Transform2D transform; // Cache. mutable Vector<RID> cache; @@ -118,6 +121,15 @@ public: virtual void set_hinting(TextServer::Hinting p_hinting); virtual TextServer::Hinting get_hinting() const; + virtual void set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel); + virtual TextServer::SubpixelPositioning get_subpixel_positioning() const; + + virtual void set_embolden(float p_strength); + virtual float get_embolden() const; + + virtual void set_transform(Transform2D p_transform); + virtual Transform2D get_transform() const; + virtual void set_oversampling(real_t p_oversampling); virtual real_t get_oversampling() const; diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 92ab091b86..30deb5ccd5 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -275,6 +275,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli PackedInt32Array indices = surfaces[i].arrays[RS::ARRAY_INDEX]; Vector<Vector3> normals = surfaces[i].arrays[RS::ARRAY_NORMAL]; Vector<Vector2> uvs = surfaces[i].arrays[RS::ARRAY_TEX_UV]; + Vector<Vector2> uv2s = surfaces[i].arrays[RS::ARRAY_TEX_UV2]; unsigned int index_count = indices.size(); unsigned int vertex_count = vertices.size(); @@ -287,7 +288,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli const int *indices_ptr = indices.ptr(); if (normals.is_empty()) { - normals.resize(vertices.size()); + normals.resize(index_count); Vector3 *n_ptr = normals.ptrw(); for (unsigned int j = 0; j < index_count; j += 3) { const Vector3 &v0 = vertices_ptr[indices_ptr[j + 0]]; @@ -313,6 +314,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli LocalVector<Vector3> merged_normals; LocalVector<int> merged_normals_counts; const Vector2 *uvs_ptr = uvs.ptr(); + const Vector2 *uv2s_ptr = uv2s.ptr(); for (unsigned int j = 0; j < vertex_count; j++) { const Vector3 &v = vertices_ptr[j]; @@ -327,8 +329,10 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli for (unsigned int k = 0; k < close_verts.size(); k++) { const Pair<int, int> &idx = close_verts[k]; - // TODO check more attributes? - if ((!uvs_ptr || uvs_ptr[j].distance_squared_to(uvs_ptr[idx.second]) < CMP_EPSILON2) && normals[idx.second].dot(n) > normal_merge_threshold) { + bool is_uvs_close = (!uvs_ptr || uvs_ptr[j].distance_squared_to(uvs_ptr[idx.second]) < CMP_EPSILON2); + bool is_uv2s_close = (!uv2s_ptr || uv2s_ptr[j].distance_squared_to(uv2s_ptr[idx.second]) < CMP_EPSILON2); + bool is_normals_close = normals[idx.second].dot(n) > normal_merge_threshold; + if (is_uvs_close && is_uv2s_close && is_normals_close) { vertex_remap.push_back(idx.first); merged_normals[idx.first] += normals[idx.second]; merged_normals_counts[idx.first]++; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index f3e5ece1f9..a0e6cc28ce 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -88,6 +88,37 @@ void Material::inspect_native_shader_code() { } } +RID Material::get_shader_rid() const { + RID ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_shader_rid, ret)) { + return ret; + } + return RID(); +} +Shader::Mode Material::get_shader_mode() const { + Shader::Mode ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_shader_mode, ret)) { + return ret; + } + + return Shader::MODE_MAX; +} + +bool Material::_can_do_next_pass() const { + bool ret; + if (GDVIRTUAL_CALL(_can_do_next_pass, ret)) { + return ret; + } + return false; +} +bool Material::_can_use_render_priority() const { + bool ret; + if (GDVIRTUAL_CALL(_can_use_render_priority, ret)) { + return ret; + } + return false; +} + void Material::_bind_methods() { ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass); ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass); @@ -103,6 +134,11 @@ void Material::_bind_methods() { BIND_CONSTANT(RENDER_PRIORITY_MAX); BIND_CONSTANT(RENDER_PRIORITY_MIN); + + GDVIRTUAL_BIND(_get_shader_rid) + GDVIRTUAL_BIND(_get_shader_mode) + GDVIRTUAL_BIND(_can_do_next_pass) + GDVIRTUAL_BIND(_can_use_render_priority) } Material::Material() { @@ -330,7 +366,7 @@ void BaseMaterial3D::init_shaders() { shader_names->rim = "rim"; shader_names->rim_tint = "rim_tint"; shader_names->clearcoat = "clearcoat"; - shader_names->clearcoat_gloss = "clearcoat_gloss"; + shader_names->clearcoat_roughness = "clearcoat_roughness"; shader_names->anisotropy = "anisotropy_ratio"; shader_names->heightmap_scale = "heightmap_scale"; shader_names->subsurface_scattering_strength = "subsurface_scattering_strength"; @@ -541,12 +577,6 @@ void BaseMaterial3D::_update_shader() { case SPECULAR_SCHLICK_GGX: code += ",specular_schlick_ggx"; break; - case SPECULAR_BLINN: - code += ",specular_blinn"; - break; - case SPECULAR_PHONG: - code += ",specular_phong"; - break; case SPECULAR_TOON: code += ",specular_toon"; break; @@ -690,7 +720,7 @@ void BaseMaterial3D::_update_shader() { } if (features[FEATURE_CLEARCOAT]) { code += "uniform float clearcoat : hint_range(0,1);\n"; - code += "uniform float clearcoat_gloss : hint_range(0,1);\n"; + code += "uniform float clearcoat_roughness : hint_range(0,1);\n"; code += "uniform sampler2D texture_clearcoat : hint_white," + texfilter_str + ";\n"; } if (features[FEATURE_ANISOTROPY]) { @@ -1166,7 +1196,7 @@ void BaseMaterial3D::_update_shader() { code += " vec2 clearcoat_tex = texture(texture_clearcoat,base_uv).xy;\n"; } code += " CLEARCOAT = clearcoat*clearcoat_tex.x;"; - code += " CLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n"; + code += " CLEARCOAT_ROUGHNESS = clearcoat_roughness*clearcoat_tex.y;\n"; } if (features[FEATURE_ANISOTROPY]) { @@ -1408,13 +1438,13 @@ float BaseMaterial3D::get_clearcoat() const { return clearcoat; } -void BaseMaterial3D::set_clearcoat_gloss(float p_clearcoat_gloss) { - clearcoat_gloss = p_clearcoat_gloss; - RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_gloss, p_clearcoat_gloss); +void BaseMaterial3D::set_clearcoat_roughness(float p_clearcoat_roughness) { + clearcoat_roughness = p_clearcoat_roughness; + RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_roughness, p_clearcoat_roughness); } -float BaseMaterial3D::get_clearcoat_gloss() const { - return clearcoat_gloss; +float BaseMaterial3D::get_clearcoat_roughness() const { + return clearcoat_roughness; } void BaseMaterial3D::set_anisotropy(float p_anisotropy) { @@ -2215,7 +2245,9 @@ BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const { RID BaseMaterial3D::get_shader_rid() const { MutexLock lock(material_mutex); - ((BaseMaterial3D *)this)->_update_shader(); + if (element.in_list()) { // _is_shader_dirty() would create anoder mutex lock + ((BaseMaterial3D *)this)->_update_shader(); + } ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); return shader_map[current_key].shader; } @@ -2269,8 +2301,8 @@ void BaseMaterial3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_clearcoat", "clearcoat"), &BaseMaterial3D::set_clearcoat); ClassDB::bind_method(D_METHOD("get_clearcoat"), &BaseMaterial3D::get_clearcoat); - ClassDB::bind_method(D_METHOD("set_clearcoat_gloss", "clearcoat_gloss"), &BaseMaterial3D::set_clearcoat_gloss); - ClassDB::bind_method(D_METHOD("get_clearcoat_gloss"), &BaseMaterial3D::get_clearcoat_gloss); + ClassDB::bind_method(D_METHOD("set_clearcoat_roughness", "clearcoat_roughness"), &BaseMaterial3D::set_clearcoat_roughness); + ClassDB::bind_method(D_METHOD("get_clearcoat_roughness"), &BaseMaterial3D::get_clearcoat_roughness); ClassDB::bind_method(D_METHOD("set_anisotropy", "anisotropy"), &BaseMaterial3D::set_anisotropy); ClassDB::bind_method(D_METHOD("get_anisotropy"), &BaseMaterial3D::get_anisotropy); @@ -2436,7 +2468,7 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Shading", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,Per-Pixel,Per-Vertex"), "set_shading_mode", "get_shading_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Toon"), "set_diffuse_mode", "get_diffuse_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Toon,Disabled"), "set_specular_mode", "get_specular_mode"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT); ADD_GROUP("Vertex Color", "vertex_color"); @@ -2484,7 +2516,7 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Clearcoat", "clearcoat_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "clearcoat_enabled"), "set_feature", "get_feature", FEATURE_CLEARCOAT); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clearcoat", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat", "get_clearcoat"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clearcoat_gloss", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat_gloss", "get_clearcoat_gloss"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clearcoat_roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat_roughness", "get_clearcoat_roughness"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "clearcoat_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_CLEARCOAT); ADD_GROUP("Anisotropy", "anisotropy_"); @@ -2691,8 +2723,6 @@ void BaseMaterial3D::_bind_methods() { BIND_ENUM_CONSTANT(DIFFUSE_TOON); BIND_ENUM_CONSTANT(SPECULAR_SCHLICK_GGX); - BIND_ENUM_CONSTANT(SPECULAR_BLINN); - BIND_ENUM_CONSTANT(SPECULAR_PHONG); BIND_ENUM_CONSTANT(SPECULAR_TOON); BIND_ENUM_CONSTANT(SPECULAR_DISABLED); @@ -2730,7 +2760,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_rim(1.0); set_rim_tint(0.5); set_clearcoat(1); - set_clearcoat_gloss(0.5); + set_clearcoat_roughness(0.5); set_anisotropy(0); set_heightmap_scale(0.05); set_subsurface_scattering_strength(0); diff --git a/scene/resources/material.h b/scene/resources/material.h index 57591bee2f..07227c037c 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -51,11 +51,15 @@ class Material : public Resource { protected: _FORCE_INLINE_ RID _get_material() const { return material; } static void _bind_methods(); - virtual bool _can_do_next_pass() const { return false; } - virtual bool _can_use_render_priority() const { return false; } + virtual bool _can_do_next_pass() const; + virtual bool _can_use_render_priority() const; void _validate_property(PropertyInfo &property) const override; + GDVIRTUAL0RC(RID, _get_shader_rid) + GDVIRTUAL0RC(Shader::Mode, _get_shader_mode) + GDVIRTUAL0RC(bool, _can_do_next_pass) + GDVIRTUAL0RC(bool, _can_use_render_priority) public: enum { RENDER_PRIORITY_MAX = RS::MATERIAL_RENDER_PRIORITY_MAX, @@ -68,9 +72,8 @@ public: int get_render_priority() const; virtual RID get_rid() const override; - virtual RID get_shader_rid() const = 0; - - virtual Shader::Mode get_shader_mode() const = 0; + virtual RID get_shader_rid() const; + virtual Shader::Mode get_shader_mode() const; Material(); virtual ~Material(); }; @@ -252,8 +255,6 @@ public: enum SpecularMode { SPECULAR_SCHLICK_GGX, - SPECULAR_BLINN, - SPECULAR_PHONG, SPECULAR_TOON, SPECULAR_DISABLED, SPECULAR_MAX @@ -387,7 +388,7 @@ private: StringName rim; StringName rim_tint; StringName clearcoat; - StringName clearcoat_gloss; + StringName clearcoat_roughness; StringName anisotropy; StringName heightmap_scale; StringName subsurface_scattering_strength; @@ -454,7 +455,7 @@ private: float rim; float rim_tint; float clearcoat; - float clearcoat_gloss; + float clearcoat_roughness; float anisotropy; float heightmap_scale; float subsurface_scattering_strength; @@ -572,8 +573,8 @@ public: void set_clearcoat(float p_clearcoat); float get_clearcoat() const; - void set_clearcoat_gloss(float p_clearcoat_gloss); - float get_clearcoat_gloss() const; + void set_clearcoat_roughness(float p_clearcoat_roughness); + float get_clearcoat_roughness() const; void set_anisotropy(float p_anisotropy); float get_anisotropy() const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 441e84eccc..3c67a20f50 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -40,6 +40,122 @@ Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr; +int Mesh::get_surface_count() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_surface_count, ret)) { + return ret; + } + return 0; +} + +int Mesh::surface_get_array_len(int p_idx) const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_surface_get_array_len, p_idx, ret)) { + return ret; + } + return 0; +} + +int Mesh::surface_get_array_index_len(int p_idx) const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_surface_get_array_index_len, p_idx, ret)) { + return ret; + } + return 0; +} + +Array Mesh::surface_get_arrays(int p_surface) const { + Array ret; + if (GDVIRTUAL_REQUIRED_CALL(_surface_get_arrays, p_surface, ret)) { + return ret; + } + return Array(); +} + +Array Mesh::surface_get_blend_shape_arrays(int p_surface) const { + Array ret; + if (GDVIRTUAL_REQUIRED_CALL(_surface_get_blend_shape_arrays, p_surface, ret)) { + return ret; + } + + return Array(); +} + +Dictionary Mesh::surface_get_lods(int p_surface) const { + Dictionary ret; + if (GDVIRTUAL_REQUIRED_CALL(_surface_get_lods, p_surface, ret)) { + return ret; + } + + return Dictionary(); +} + +uint32_t Mesh::surface_get_format(int p_idx) const { + uint32_t ret; + if (GDVIRTUAL_REQUIRED_CALL(_surface_get_format, p_idx, ret)) { + return ret; + } + + return 0; +} + +Mesh::PrimitiveType Mesh::surface_get_primitive_type(int p_idx) const { + uint32_t ret; + if (GDVIRTUAL_REQUIRED_CALL(_surface_get_primitive_type, p_idx, ret)) { + return (Mesh::PrimitiveType)ret; + } + + return PRIMITIVE_MAX; +} + +void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) { + if (GDVIRTUAL_REQUIRED_CALL(_surface_set_material, p_idx, p_material)) { + return; + } +} + +Ref<Material> Mesh::surface_get_material(int p_idx) const { + Ref<Material> ret; + if (GDVIRTUAL_REQUIRED_CALL(_surface_get_material, p_idx, ret)) { + return ret; + } + + return Ref<Material>(); +} + +int Mesh::get_blend_shape_count() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_count, ret)) { + return ret; + } + + return 0; +} + +StringName Mesh::get_blend_shape_name(int p_index) const { + StringName ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_name, p_index, ret)) { + return ret; + } + + return StringName(); +} + +void Mesh::set_blend_shape_name(int p_index, const StringName &p_name) { + if (GDVIRTUAL_REQUIRED_CALL(_set_blend_shape_name, p_index, p_name)) { + return; + } +} + +AABB Mesh::get_aabb() const { + AABB ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_aabb, ret)) { + return ret; + } + + return AABB(); +} + Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { if (triangle_mesh.is_valid()) { return triangle_mesh; @@ -502,6 +618,21 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); + + GDVIRTUAL_BIND(_get_surface_count) + GDVIRTUAL_BIND(_surface_get_array_len, "index") + GDVIRTUAL_BIND(_surface_get_array_index_len, "index") + GDVIRTUAL_BIND(_surface_get_arrays, "index") + GDVIRTUAL_BIND(_surface_get_blend_shape_arrays, "index") + GDVIRTUAL_BIND(_surface_get_lods, "index") + GDVIRTUAL_BIND(_surface_get_format, "index") + GDVIRTUAL_BIND(_surface_get_primitive_type, "index") + GDVIRTUAL_BIND(_surface_set_material, "index", "material") + GDVIRTUAL_BIND(_surface_get_material, "index") + GDVIRTUAL_BIND(_get_blend_shape_count) + GDVIRTUAL_BIND(_get_blend_shape_name, "index") + GDVIRTUAL_BIND(_set_blend_shape_name, "index", "name") + GDVIRTUAL_BIND(_get_aabb) } void Mesh::clear_cache() const { @@ -1684,6 +1815,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform3D &p_base_transform, float p_te Error ArrayMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache, bool p_generate_cache) { ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED); ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes."); + ERR_FAIL_COND_V_MSG(p_texel_size <= 0.0f, ERR_PARAMETER_RANGE_ERROR, "Texel size must be greater than 0."); LocalVector<float> vertices; LocalVector<float> normals; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 08d834bdb9..652c045a24 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -45,9 +45,34 @@ class Mesh : public Resource { mutable Vector<Vector3> debug_lines; Size2i lightmap_size_hint; +public: + enum PrimitiveType { + PRIMITIVE_POINTS = RenderingServer::PRIMITIVE_POINTS, + PRIMITIVE_LINES = RenderingServer::PRIMITIVE_LINES, + PRIMITIVE_LINE_STRIP = RenderingServer::PRIMITIVE_LINE_STRIP, + PRIMITIVE_TRIANGLES = RenderingServer::PRIMITIVE_TRIANGLES, + PRIMITIVE_TRIANGLE_STRIP = RenderingServer::PRIMITIVE_TRIANGLE_STRIP, + PRIMITIVE_MAX = RenderingServer::PRIMITIVE_MAX, + }; + protected: static void _bind_methods(); + GDVIRTUAL0RC(int, _get_surface_count) + GDVIRTUAL1RC(int, _surface_get_array_len, int) + GDVIRTUAL1RC(int, _surface_get_array_index_len, int) + GDVIRTUAL1RC(Array, _surface_get_arrays, int) + GDVIRTUAL1RC(Array, _surface_get_blend_shape_arrays, int) + GDVIRTUAL1RC(Dictionary, _surface_get_lods, int) + GDVIRTUAL1RC(uint32_t, _surface_get_format, int) + GDVIRTUAL1RC(uint32_t, _surface_get_primitive_type, int) + GDVIRTUAL2(_surface_set_material, int, Ref<Material>) + GDVIRTUAL1RC(Ref<Material>, _surface_get_material, int) + GDVIRTUAL0RC(int, _get_blend_shape_count) + GDVIRTUAL1RC(StringName, _get_blend_shape_name, int) + GDVIRTUAL2(_set_blend_shape_name, int, StringName) + GDVIRTUAL0RC(AABB, _get_aabb) + public: enum { NO_INDEX_ARRAY = RenderingServer::NO_INDEX_ARRAY, @@ -120,28 +145,20 @@ public: }; - enum PrimitiveType { - PRIMITIVE_POINTS = RenderingServer::PRIMITIVE_POINTS, - PRIMITIVE_LINES = RenderingServer::PRIMITIVE_LINES, - PRIMITIVE_LINE_STRIP = RenderingServer::PRIMITIVE_LINE_STRIP, - PRIMITIVE_TRIANGLES = RenderingServer::PRIMITIVE_TRIANGLES, - PRIMITIVE_TRIANGLE_STRIP = RenderingServer::PRIMITIVE_TRIANGLE_STRIP, - PRIMITIVE_MAX = RenderingServer::PRIMITIVE_MAX, - }; - - virtual int get_surface_count() const = 0; - virtual int surface_get_array_len(int p_idx) const = 0; - virtual int surface_get_array_index_len(int p_idx) const = 0; - virtual Array surface_get_arrays(int p_surface) const = 0; - virtual Array surface_get_blend_shape_arrays(int p_surface) const = 0; - virtual Dictionary surface_get_lods(int p_surface) const = 0; - virtual uint32_t surface_get_format(int p_idx) const = 0; - virtual PrimitiveType surface_get_primitive_type(int p_idx) const = 0; - virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) = 0; - virtual Ref<Material> surface_get_material(int p_idx) const = 0; - virtual int get_blend_shape_count() const = 0; - virtual StringName get_blend_shape_name(int p_index) const = 0; - virtual void set_blend_shape_name(int p_index, const StringName &p_name) = 0; + virtual int get_surface_count() const; + virtual int surface_get_array_len(int p_idx) const; + virtual int surface_get_array_index_len(int p_idx) const; + virtual Array surface_get_arrays(int p_surface) const; + virtual Array surface_get_blend_shape_arrays(int p_surface) const; + virtual Dictionary surface_get_lods(int p_surface) const; + virtual uint32_t surface_get_format(int p_idx) const; + virtual PrimitiveType surface_get_primitive_type(int p_idx) const; + virtual void surface_set_material(int p_idx, const Ref<Material> &p_material); + virtual Ref<Material> surface_get_material(int p_idx) const; + virtual int get_blend_shape_count() const; + virtual StringName get_blend_shape_name(int p_index) const; + virtual void set_blend_shape_name(int p_index, const StringName &p_name); + virtual AABB get_aabb() const; Vector<Face3> get_faces() const; Ref<TriangleMesh> generate_triangle_mesh() const; @@ -153,8 +170,6 @@ public: Ref<Mesh> create_outline(float p_margin) const; - virtual AABB get_aabb() const = 0; - void set_lightmap_size_hint(const Size2i &p_size); Size2i get_lightmap_size_hint() const; void clear_cache() const; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index f9a4eba978..2f1ac7a83a 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -529,10 +529,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map if (!gi.persistent) { continue; } - /* - if (instance_state_node>=0 && instance_state->is_node_in_group(instance_state_node,gi.name)) - continue; //group was instantiated, don't add here - */ bool skip = false; for (const SceneState::PackState &ia : states_stack) { @@ -1657,7 +1653,7 @@ void PackedScene::recreate_state() { #endif } -Ref<SceneState> PackedScene::get_state() { +Ref<SceneState> PackedScene::get_state() const { return state; } diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index 81b38840d9..96222937d0 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -228,7 +228,7 @@ public: virtual void set_last_modified_time(uint64_t p_time) override { state->set_last_modified_time(p_time); } #endif - Ref<SceneState> get_state(); + Ref<SceneState> get_state() const; PackedScene(); }; diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 38acd0af0a..781e219f1f 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -36,11 +36,17 @@ */ void PrimitiveMesh::_update() const { Array arr; - arr.resize(RS::ARRAY_MAX); - _create_mesh_array(arr); + if (GDVIRTUAL_CALL(_create_mesh_array, arr)) { + ERR_FAIL_COND_MSG(arr.size() != RS::ARRAY_MAX, "_create_mesh_array must return an array of Mesh.ARRAY_MAX elements."); + } else { + arr.resize(RS::ARRAY_MAX); + _create_mesh_array(arr); + } Vector<Vector3> points = arr[RS::ARRAY_VERTEX]; + ERR_FAIL_COND_MSG(points.size() == 0, "_create_mesh_array must return at least a vertex array."); + aabb = AABB(); int pc = points.size(); @@ -210,6 +216,8 @@ void PrimitiveMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material"); ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces"); + + GDVIRTUAL_BIND(_create_mesh_array); } void PrimitiveMesh::set_material(const Ref<Material> &p_material) { diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 3fc5fd4a16..eef5eb3f7d 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -64,8 +64,9 @@ protected: static void _bind_methods(); - virtual void _create_mesh_array(Array &p_arr) const = 0; + virtual void _create_mesh_array(Array &p_arr) const {} void _request_update(); + GDVIRTUAL0RC(Array, _create_mesh_array) public: virtual int get_surface_count() const override; diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp index 27659f724e..5e88c9974c 100644 --- a/scene/resources/rectangle_shape_2d.cpp +++ b/scene/resources/rectangle_shape_2d.cpp @@ -58,6 +58,7 @@ bool RectangleShape2D::_get(const StringName &p_name, Variant &r_property) const #endif // DISABLE_DEPRECATED void RectangleShape2D::set_size(const Vector2 &p_size) { + ERR_FAIL_COND_MSG(p_size.x < 0 || p_size.y < 0, "RectangleShape2D size cannot be negative."); size = p_size; _update_shape(); } diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index c03faa2c2d..fd6f018651 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -153,7 +153,7 @@ Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, R RES res = ResourceLoader::load_threaded_get(path); if (res.is_null()) { if (ResourceLoader::get_abort_on_missing_resources()) { - error = ERR_FILE_CORRUPT; + error = ERR_FILE_MISSING_DEPENDENCIES; error_text = "[ext_resource] referenced nonexistent resource at: " + path; _printerr(); return error; @@ -165,7 +165,7 @@ Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, R r_res = res; } } else { - error = ERR_FILE_CORRUPT; + error = ERR_FILE_MISSING_DEPENDENCIES; error_text = "[ext_resource] referenced non-loaded resource at: " + path; _printerr(); return error; @@ -265,7 +265,9 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &parser); if (error) { - if (error != ERR_FILE_EOF) { + if (error == ERR_FILE_MISSING_DEPENDENCIES) { + // Resource loading error, just skip it. + } else if (error != ERR_FILE_EOF) { _printerr(); return Ref<PackedScene>(); } else { @@ -906,10 +908,9 @@ Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_p return ERR_CANT_CREATE; } - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); da->remove(p_path); da->rename(p_path + ".depren", p_path); - memdelete(da); return OK; } diff --git a/scene/resources/skeleton_modification_2d_jiggle.cpp b/scene/resources/skeleton_modification_2d_jiggle.cpp index eee6067dae..0921417656 100644 --- a/scene/resources/skeleton_modification_2d_jiggle.cpp +++ b/scene/resources/skeleton_modification_2d_jiggle.cpp @@ -29,7 +29,9 @@ /*************************************************************************/ #include "skeleton_modification_2d_jiggle.h" + #include "scene/2d/skeleton_2d.h" +#include "scene/resources/world_2d.h" bool SkeletonModification2DJiggle::_set(const StringName &p_path, const Variant &p_value) { String path = p_path; diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index c5d5ba2912..54543782f6 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -71,6 +71,25 @@ float ProceduralSkyMaterial::get_sky_energy() const { return sky_energy; } +void ProceduralSkyMaterial::set_sky_cover(const Ref<Texture2D> &p_sky_cover) { + sky_cover = p_sky_cover; + RID tex_rid = p_sky_cover.is_valid() ? p_sky_cover->get_rid() : RID(); + RS::get_singleton()->material_set_param(_get_material(), "sky_cover", tex_rid); +} + +Ref<Texture2D> ProceduralSkyMaterial::get_sky_cover() const { + return sky_cover; +} + +void ProceduralSkyMaterial::set_sky_cover_modulate(const Color &p_sky_cover_modulate) { + sky_cover_modulate = p_sky_cover_modulate; + RS::get_singleton()->material_set_param(_get_material(), "sky_cover_modulate", sky_cover_modulate); +} + +Color ProceduralSkyMaterial::get_sky_cover_modulate() const { + return sky_cover_modulate; +} + void ProceduralSkyMaterial::set_ground_bottom_color(const Color &p_ground_bottom) { ground_bottom_color = p_ground_bottom; RS::get_singleton()->material_set_param(_get_material(), "ground_bottom_color", ground_bottom_color); @@ -156,6 +175,12 @@ void ProceduralSkyMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSkyMaterial::set_sky_energy); ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSkyMaterial::get_sky_energy); + ClassDB::bind_method(D_METHOD("set_sky_cover", "sky_cover"), &ProceduralSkyMaterial::set_sky_cover); + ClassDB::bind_method(D_METHOD("get_sky_cover"), &ProceduralSkyMaterial::get_sky_cover); + + ClassDB::bind_method(D_METHOD("set_sky_cover_modulate", "color"), &ProceduralSkyMaterial::set_sky_cover_modulate); + ClassDB::bind_method(D_METHOD("get_sky_cover_modulate"), &ProceduralSkyMaterial::get_sky_cover_modulate); + ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSkyMaterial::set_ground_bottom_color); ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSkyMaterial::get_ground_bottom_color); @@ -179,6 +204,8 @@ void ProceduralSkyMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_sky_horizon_color", "get_sky_horizon_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky_cover", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_sky_cover", "get_sky_cover"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_cover_modulate"), "set_sky_cover_modulate", "get_sky_cover_modulate"); ADD_GROUP("Ground", "ground_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ground_bottom_color", "get_ground_bottom_color"); @@ -208,16 +235,18 @@ void ProceduralSkyMaterial::_update_shader() { shader_type sky; -uniform vec4 sky_top_color : hint_color = vec4(0.35, 0.46, 0.71, 1.0); -uniform vec4 sky_horizon_color : hint_color = vec4(0.55, 0.69, 0.81, 1.0); -uniform float sky_curve : hint_range(0, 1) = 0.09; +uniform vec4 sky_top_color : hint_color = vec4(0.385, 0.454, 0.55, 1.0); +uniform vec4 sky_horizon_color : hint_color = vec4(0.646, 0.656, 0.67, 1.0); +uniform float sky_curve : hint_range(0, 1) = 0.15; uniform float sky_energy = 1.0; -uniform vec4 ground_bottom_color : hint_color = vec4(0.12, 0.12, 0.13, 1.0); -uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0); +uniform sampler2D sky_cover : hint_black_albedo; +uniform vec4 sky_cover_modulate : hint_color = vec4(1.0, 1.0, 1.0, 1.0); +uniform vec4 ground_bottom_color : hint_color = vec4(0.2, 0.169, 0.133, 1.0); +uniform vec4 ground_horizon_color : hint_color = vec4(0.646, 0.656, 0.67, 1.0); uniform float ground_curve : hint_range(0, 1) = 0.02; uniform float ground_energy = 1.0; -uniform float sun_angle_max = 1.74; -uniform float sun_curve : hint_range(0, 1) = 0.05; +uniform float sun_angle_max = 30.0; +uniform float sun_curve : hint_range(0, 1) = 0.15; void sky() { float v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0)); @@ -265,6 +294,9 @@ void sky() { } } + vec4 sky_cover_texture = texture(sky_cover, SKY_COORDS); + sky += (sky_cover_texture.rgb * sky_cover_modulate.rgb) * sky_cover_texture.a * sky_cover_modulate.a * sky_energy; + c = (v_angle - (PI * 0.5)) / (PI * 0.5); vec3 ground = mix(ground_horizon_color.rgb, ground_bottom_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / ground_curve), 0.0, 1.0)); ground *= ground_energy; @@ -277,18 +309,19 @@ void sky() { } ProceduralSkyMaterial::ProceduralSkyMaterial() { - set_sky_top_color(Color(0.35, 0.46, 0.71)); - set_sky_horizon_color(Color(0.55, 0.69, 0.81)); - set_sky_curve(0.09); + set_sky_top_color(Color(0.385, 0.454, 0.55)); + set_sky_horizon_color(Color(0.6463, 0.6558, 0.6708)); + set_sky_curve(0.15); set_sky_energy(1.0); + set_sky_cover_modulate(Color(1, 1, 1)); - set_ground_bottom_color(Color(0.12, 0.12, 0.13)); - set_ground_horizon_color(Color(0.37, 0.33, 0.31)); + set_ground_bottom_color(Color(0.2, 0.169, 0.133)); + set_ground_horizon_color(Color(0.6463, 0.6558, 0.6708)); set_ground_curve(0.02); set_ground_energy(1.0); - set_sun_angle_max(100.0); - set_sun_curve(0.05); + set_sun_angle_max(30.0); + set_sun_curve(0.15); } ProceduralSkyMaterial::~ProceduralSkyMaterial() { @@ -583,14 +616,14 @@ void PhysicalSkyMaterial::_update_shader() { shader_type sky; uniform float rayleigh : hint_range(0, 64) = 2.0; -uniform vec4 rayleigh_color : hint_color = vec4(0.26, 0.41, 0.58, 1.0); +uniform vec4 rayleigh_color : hint_color = vec4(0.3, 0.405, 0.6, 1.0); uniform float mie : hint_range(0, 1) = 0.005; uniform float mie_eccentricity : hint_range(-1, 1) = 0.8; -uniform vec4 mie_color : hint_color = vec4(0.63, 0.77, 0.92, 1.0); +uniform vec4 mie_color : hint_color = vec4(0.69, 0.729, 0.812, 1.0); uniform float turbidity : hint_range(0, 1000) = 10.0; uniform float sun_disk_scale : hint_range(0, 360) = 1.0; -uniform vec4 ground_color : hint_color = vec4(1.0); +uniform vec4 ground_color : hint_color = vec4(0.1, 0.07, 0.034, 1.0); uniform float exposure : hint_range(0, 128) = 0.1; uniform float dither_strength : hint_range(0, 10) = 1.0; @@ -680,13 +713,13 @@ void sky() { PhysicalSkyMaterial::PhysicalSkyMaterial() { set_rayleigh_coefficient(2.0); - set_rayleigh_color(Color(0.26, 0.41, 0.58)); + set_rayleigh_color(Color(0.3, 0.405, 0.6)); set_mie_coefficient(0.005); set_mie_eccentricity(0.8); - set_mie_color(Color(0.63, 0.77, 0.92)); + set_mie_color(Color(0.69, 0.729, 0.812)); set_turbidity(10.0); set_sun_disk_scale(1.0); - set_ground_color(Color(1.0, 1.0, 1.0)); + set_ground_color(Color(0.1, 0.07, 0.034)); set_exposure(0.1); set_dither_strength(1.0); } diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index 7f421beb8d..5c791a185a 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -42,6 +42,8 @@ private: Color sky_horizon_color; float sky_curve; float sky_energy; + Ref<Texture2D> sky_cover; + Color sky_cover_modulate; Color ground_bottom_color; Color ground_horizon_color; @@ -72,6 +74,12 @@ public: void set_sky_energy(float p_energy); float get_sky_energy() const; + void set_sky_cover(const Ref<Texture2D> &p_sky_cover); + Ref<Texture2D> get_sky_cover() const; + + void set_sky_cover_modulate(const Color &p_sky_cover_modulate); + Color get_sky_cover_modulate() const; + void set_ground_bottom_color(const Color &p_ground_bottom); Color get_ground_bottom_color() const; diff --git a/scene/resources/sphere_shape_3d.cpp b/scene/resources/sphere_shape_3d.cpp index ee789362c9..8282992401 100644 --- a/scene/resources/sphere_shape_3d.cpp +++ b/scene/resources/sphere_shape_3d.cpp @@ -63,6 +63,7 @@ void SphereShape3D::_update_shape() { } void SphereShape3D::set_radius(float p_radius) { + ERR_FAIL_COND_MSG(p_radius < 0, "SphereShape3D radius cannot be negative."); radius = p_radius; _update_shape(); notify_change_to_owners(); diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 5afd424e03..fe52761482 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -34,10 +34,28 @@ #include <limits.h> +float StyleBox::get_style_margin(Side p_side) const { + float ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_style_margin, p_side, ret)) { + return ret; + } + return 0; +} bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const { + bool ret; + if (GDVIRTUAL_CALL(_test_mask, p_point, p_rect, ret)) { + return ret; + } + return true; } +void StyleBox::draw(RID p_canvas_item, const Rect2 &p_rect) const { + if (GDVIRTUAL_REQUIRED_CALL(_draw, p_canvas_item, p_rect)) { + return; + } +} + void StyleBox::set_default_margin(Side p_side, float p_value) { ERR_FAIL_INDEX((int)p_side, 4); @@ -74,10 +92,19 @@ Point2 StyleBox::get_offset() const { } Size2 StyleBox::get_center_size() const { + Size2 ret; + if (GDVIRTUAL_CALL(_get_center_size, ret)) { + return ret; + } + return Size2(); } Rect2 StyleBox::get_draw_rect(const Rect2 &p_rect) const { + Rect2 ret; + if (GDVIRTUAL_CALL(_get_draw_rect, p_rect, ret)) { + return ret; + } return p_rect; } @@ -100,6 +127,12 @@ void StyleBox::_bind_methods() { 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_bottom", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", SIDE_BOTTOM); + + GDVIRTUAL_BIND(_get_style_margin, "side") + GDVIRTUAL_BIND(_test_mask, "point", "rect") + GDVIRTUAL_BIND(_get_center_size) + GDVIRTUAL_BIND(_get_draw_rect, "rect") + GDVIRTUAL_BIND(_draw, "to_canvas_item", "rect") } StyleBox::StyleBox() { diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 4c41f42293..68ad41b69c 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -44,9 +44,15 @@ class StyleBox : public Resource { float margin[4]; protected: - virtual float get_style_margin(Side p_side) const = 0; + virtual float get_style_margin(Side p_side) const; static void _bind_methods(); + GDVIRTUAL1RC(float, _get_style_margin, Side) + GDVIRTUAL2RC(bool, _test_mask, Point2, Rect2) + GDVIRTUAL0RC(Size2, _get_center_size) + GDVIRTUAL1RC(Rect2, _get_draw_rect, Rect2) + GDVIRTUAL2C(_draw, RID, Rect2) + public: virtual bool test_mask(const Point2 &p_point, const Rect2 &p_rect) const; @@ -56,7 +62,7 @@ public: virtual Size2 get_center_size() const; virtual Rect2 get_draw_rect(const Rect2 &p_rect) const; - virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const = 0; + virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const; CanvasItem *get_current_item_drawn() const; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 52151ae846..8ff1fde2cf 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -150,12 +150,15 @@ uint32_t SurfaceTool::TriangleHasher::hash(const int *p_triangle) { int t1 = p_triangle[1]; int t2 = p_triangle[2]; - if (t0 > t1) + if (t0 > t1) { SWAP(t0, t1); - if (t1 > t2) + } + if (t1 > t2) { SWAP(t1, t2); - if (t0 > t1) + } + if (t0 > t1) { SWAP(t0, t1); + } return (t0 * 73856093) ^ (t1 * 19349663) ^ (t2 * 83492791); } @@ -165,23 +168,29 @@ bool SurfaceTool::TriangleHasher::compare(const int *p_lhs, const int *p_rhs) { int r1 = p_rhs[1]; int r2 = p_rhs[2]; - if (r0 > r1) + if (r0 > r1) { SWAP(r0, r1); - if (r1 > r2) + } + if (r1 > r2) { SWAP(r1, r2); - if (r0 > r1) + } + if (r0 > r1) { SWAP(r0, r1); + } int l0 = p_lhs[0]; int l1 = p_lhs[1]; int l2 = p_lhs[2]; - if (l0 > l1) + if (l0 > l1) { SWAP(l0, l1); - if (l1 > l2) + } + if (l1 > l2) { SWAP(l1, l2); - if (l0 > l1) + } + if (l0 > l1) { SWAP(l0, l1); + } return l0 == r0 && l1 == r1 && l2 == r2; } diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 0ee0e4b33e..1930fa2682 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -38,23 +38,61 @@ #include "scene/resources/bit_map.h" #include "servers/camera/camera_feed.h" +int Texture2D::get_width() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) { + return ret; + } + return 0; +} + +int Texture2D::get_height() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_height, ret)) { + return ret; + } + return 0; +} + Size2 Texture2D::get_size() const { return Size2(get_width(), get_height()); } bool Texture2D::is_pixel_opaque(int p_x, int p_y) const { + bool ret; + if (GDVIRTUAL_CALL(_is_pixel_opaque, p_x, p_y, ret)) { + return ret; + } + + return true; +} +bool Texture2D::has_alpha() const { + bool ret; + if (GDVIRTUAL_CALL(_has_alpha, ret)) { + return ret; + } + return true; } void Texture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { + if (GDVIRTUAL_CALL(_draw, p_canvas_item, p_pos, p_modulate, p_transpose)) { + return; + } RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose); } void Texture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { + if (GDVIRTUAL_CALL(_draw_rect, p_canvas_item, p_rect, p_tile, p_modulate, p_transpose)) { + return; + } RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose); } void Texture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const { + if (GDVIRTUAL_CALL(_draw_rect_region, p_canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_clip_uv)) { + return; + } RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, p_clip_uv); } @@ -75,6 +113,15 @@ void Texture2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_image"), &Texture2D::get_image); ADD_GROUP("", ""); + + GDVIRTUAL_BIND(_get_width); + GDVIRTUAL_BIND(_get_height); + GDVIRTUAL_BIND(_is_pixel_opaque, "x", "y"); + GDVIRTUAL_BIND(_has_alpha); + + GDVIRTUAL_BIND(_draw, "to_canvas_item", "pos", "modulate", "transpose") + GDVIRTUAL_BIND(_draw_rect, "to_canvas_item", "rect", "tile", "modulate", "transpose") + GDVIRTUAL_BIND(_draw_rect_region, "tp_canvas_item", "rect", "src_rect", "modulate", "transpose", "clip_uv"); } Texture2D::Texture2D() { @@ -293,7 +340,7 @@ ImageTexture::~ImageTexture() { ////////////////////////////////////////// -Ref<Image> StreamTexture2D::load_image_from_file(FileAccess *f, int p_size_limit) { +Ref<Image> CompressedTexture2D::load_image_from_file(FileAccess *f, int p_size_limit) { uint32_t data_format = f->get_32(); uint32_t w = f->get_16(); uint32_t h = f->get_16(); @@ -426,7 +473,7 @@ Ref<Image> StreamTexture2D::load_image_from_file(FileAccess *f, int p_size_limit return Ref<Image>(); } -void StreamTexture2D::set_path(const String &p_path, bool p_take_over) { +void CompressedTexture2D::set_path(const String &p_path, bool p_take_over) { if (texture.is_valid()) { RenderingServer::get_singleton()->texture_set_path(texture, p_path); } @@ -434,36 +481,36 @@ void StreamTexture2D::set_path(const String &p_path, bool p_take_over) { Resource::set_path(p_path, p_take_over); } -void StreamTexture2D::_requested_3d(void *p_ud) { - StreamTexture2D *st = (StreamTexture2D *)p_ud; - Ref<StreamTexture2D> stex(st); +void CompressedTexture2D::_requested_3d(void *p_ud) { + CompressedTexture2D *ct = (CompressedTexture2D *)p_ud; + Ref<CompressedTexture2D> ctex(ct); ERR_FAIL_COND(!request_3d_callback); - request_3d_callback(stex); + request_3d_callback(ctex); } -void StreamTexture2D::_requested_roughness(void *p_ud, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel) { - StreamTexture2D *st = (StreamTexture2D *)p_ud; - Ref<StreamTexture2D> stex(st); +void CompressedTexture2D::_requested_roughness(void *p_ud, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel) { + CompressedTexture2D *ct = (CompressedTexture2D *)p_ud; + Ref<CompressedTexture2D> ctex(ct); ERR_FAIL_COND(!request_roughness_callback); - request_roughness_callback(stex, p_normal_path, p_roughness_channel); + request_roughness_callback(ctex, p_normal_path, p_roughness_channel); } -void StreamTexture2D::_requested_normal(void *p_ud) { - StreamTexture2D *st = (StreamTexture2D *)p_ud; - Ref<StreamTexture2D> stex(st); +void CompressedTexture2D::_requested_normal(void *p_ud) { + CompressedTexture2D *ct = (CompressedTexture2D *)p_ud; + Ref<CompressedTexture2D> ctex(ct); ERR_FAIL_COND(!request_normal_callback); - request_normal_callback(stex); + request_normal_callback(ctex); } -StreamTexture2D::TextureFormatRequestCallback StreamTexture2D::request_3d_callback = nullptr; -StreamTexture2D::TextureFormatRoughnessRequestCallback StreamTexture2D::request_roughness_callback = nullptr; -StreamTexture2D::TextureFormatRequestCallback StreamTexture2D::request_normal_callback = nullptr; +CompressedTexture2D::TextureFormatRequestCallback CompressedTexture2D::request_3d_callback = nullptr; +CompressedTexture2D::TextureFormatRoughnessRequestCallback CompressedTexture2D::request_roughness_callback = nullptr; +CompressedTexture2D::TextureFormatRequestCallback CompressedTexture2D::request_normal_callback = nullptr; -Image::Format StreamTexture2D::get_format() const { +Image::Format CompressedTexture2D::get_format() const { return format; } -Error StreamTexture2D::_load_data(const String &p_path, int &r_width, int &r_height, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) { +Error CompressedTexture2D::_load_data(const String &p_path, int &r_width, int &r_height, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) { alpha_cache.unref(); ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER); @@ -475,14 +522,14 @@ Error StreamTexture2D::_load_data(const String &p_path, int &r_width, int &r_hei f->get_buffer(header, 4); if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != '2') { memdelete(f); - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is corrupt (Bad header)."); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is corrupt (Bad header)."); } uint32_t version = f->get_32(); if (version > FORMAT_VERSION) { memdelete(f); - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new."); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is too new."); } r_width = f->get_32(); r_height = f->get_32(); @@ -523,7 +570,7 @@ Error StreamTexture2D::_load_data(const String &p_path, int &r_width, int &r_hei return OK; } -Error StreamTexture2D::load(const String &p_path) { +Error CompressedTexture2D::load(const String &p_path) { int lw, lh; Ref<Image> image; image.instantiate(); @@ -590,51 +637,51 @@ Error StreamTexture2D::load(const String &p_path) { return OK; } -String StreamTexture2D::get_load_path() const { +String CompressedTexture2D::get_load_path() const { return path_to_file; } -int StreamTexture2D::get_width() const { +int CompressedTexture2D::get_width() const { return w; } -int StreamTexture2D::get_height() const { +int CompressedTexture2D::get_height() const { return h; } -RID StreamTexture2D::get_rid() const { +RID CompressedTexture2D::get_rid() const { if (!texture.is_valid()) { texture = RS::get_singleton()->texture_2d_placeholder_create(); } return texture; } -void StreamTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { +void CompressedTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { if ((w | h) == 0) { return; } RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose); } -void StreamTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { +void CompressedTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { if ((w | h) == 0) { return; } RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose); } -void StreamTexture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const { +void CompressedTexture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const { if ((w | h) == 0) { return; } RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, p_clip_uv); } -bool StreamTexture2D::has_alpha() const { +bool CompressedTexture2D::has_alpha() const { return false; } -Ref<Image> StreamTexture2D::get_image() const { +Ref<Image> CompressedTexture2D::get_image() const { if (texture.is_valid()) { return RS::get_singleton()->texture_2d_get(texture); } else { @@ -642,7 +689,7 @@ Ref<Image> StreamTexture2D::get_image() const { } } -bool StreamTexture2D::is_pixel_opaque(int p_x, int p_y) const { +bool CompressedTexture2D::is_pixel_opaque(int p_x, int p_y) const { if (!alpha_cache.is_valid()) { Ref<Image> img = get_image(); if (img.is_valid()) { @@ -676,7 +723,7 @@ bool StreamTexture2D::is_pixel_opaque(int p_x, int p_y) const { return true; } -void StreamTexture2D::reload_from_file() { +void CompressedTexture2D::reload_from_file() { String path = get_path(); if (!path.is_resource_file()) { return; @@ -691,26 +738,26 @@ void StreamTexture2D::reload_from_file() { load(path); } -void StreamTexture2D::_validate_property(PropertyInfo &property) const { +void CompressedTexture2D::_validate_property(PropertyInfo &property) const { } -void StreamTexture2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture2D::load); - ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture2D::get_load_path); +void CompressedTexture2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("load", "path"), &CompressedTexture2D::load); + ClassDB::bind_method(D_METHOD("get_load_path"), &CompressedTexture2D::get_load_path); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.ctex"), "load", "get_load_path"); } -StreamTexture2D::StreamTexture2D() {} +CompressedTexture2D::CompressedTexture2D() {} -StreamTexture2D::~StreamTexture2D() { +CompressedTexture2D::~CompressedTexture2D() { if (texture.is_valid()) { RS::get_singleton()->free(texture); } } -RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { - Ref<StreamTexture2D> st; +RES ResourceFormatLoaderCompressedTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { + Ref<CompressedTexture2D> st; st.instantiate(); Error err = st->load(p_path); if (r_error) { @@ -723,24 +770,24 @@ RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String return st; } -void ResourceFormatLoaderStreamTexture2D::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("stex"); +void ResourceFormatLoaderCompressedTexture2D::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("ctex"); } -bool ResourceFormatLoaderStreamTexture2D::handles_type(const String &p_type) const { - return p_type == "StreamTexture2D"; +bool ResourceFormatLoaderCompressedTexture2D::handles_type(const String &p_type) const { + return p_type == "CompressedTexture2D"; } -String ResourceFormatLoaderStreamTexture2D::get_resource_type(const String &p_path) const { - if (p_path.get_extension().to_lower() == "stex") { - return "StreamTexture2D"; +String ResourceFormatLoaderCompressedTexture2D::get_resource_type(const String &p_path) const { + if (p_path.get_extension().to_lower() == "ctex") { + return "CompressedTexture2D"; } return ""; } //////////////////////////////////// -TypedArray<Image> Texture3D::_get_data() const { +TypedArray<Image> Texture3D::_get_datai() const { Vector<Ref<Image>> data = get_data(); TypedArray<Image> ret; @@ -751,13 +798,73 @@ TypedArray<Image> Texture3D::_get_data() const { return ret; } +Image::Format Texture3D::get_format() const { + Image::Format ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_format, ret)) { + return ret; + } + return Image::FORMAT_MAX; +} + +int Texture3D::get_width() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) { + return ret; + } + return 0; +} + +int Texture3D::get_height() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_height, ret)) { + return ret; + } + return 0; +} + +int Texture3D::get_depth() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_depth, ret)) { + return ret; + } + + return 0; +} + +bool Texture3D::has_mipmaps() const { + bool ret; + if (GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret)) { + return ret; + } + return 0; +} + +Vector<Ref<Image>> Texture3D::get_data() const { + TypedArray<Image> ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_data, ret)) { + Vector<Ref<Image>> data; + data.resize(ret.size()); + for (int i = 0; i < data.size(); i++) { + data.write[i] = ret[i]; + } + return data; + } + return Vector<Ref<Image>>(); +} void Texture3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_format"), &Texture3D::get_format); ClassDB::bind_method(D_METHOD("get_width"), &Texture3D::get_width); ClassDB::bind_method(D_METHOD("get_height"), &Texture3D::get_height); ClassDB::bind_method(D_METHOD("get_depth"), &Texture3D::get_depth); ClassDB::bind_method(D_METHOD("has_mipmaps"), &Texture3D::has_mipmaps); - ClassDB::bind_method(D_METHOD("get_data"), &Texture3D::_get_data); + ClassDB::bind_method(D_METHOD("get_data"), &Texture3D::_get_datai); + + GDVIRTUAL_BIND(_get_format); + GDVIRTUAL_BIND(_get_width); + GDVIRTUAL_BIND(_get_height); + GDVIRTUAL_BIND(_get_depth); + GDVIRTUAL_BIND(_has_mipmaps); + GDVIRTUAL_BIND(_get_data); } ////////////////////////////////////////// @@ -846,7 +953,7 @@ ImageTexture3D::~ImageTexture3D() { //////////////////////////////////////////// -void StreamTexture3D::set_path(const String &p_path, bool p_take_over) { +void CompressedTexture3D::set_path(const String &p_path, bool p_take_over) { if (texture.is_valid()) { RenderingServer::get_singleton()->texture_set_path(texture, p_path); } @@ -854,11 +961,11 @@ void StreamTexture3D::set_path(const String &p_path, bool p_take_over) { Resource::set_path(p_path, p_take_over); } -Image::Format StreamTexture3D::get_format() const { +Image::Format CompressedTexture3D::get_format() const { return format; } -Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps) { +Error CompressedTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps) { FileAccessRef f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, vformat("Unable to open file: %s.", p_path)); @@ -866,11 +973,11 @@ Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_da f->get_buffer(header, 4); ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L', ERR_FILE_UNRECOGNIZED); - //stored as stream textures (used for lossless and lossy compression) + //stored as compressed textures (used for lossless and lossy compression) uint32_t version = f->get_32(); if (version > FORMAT_VERSION) { - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new."); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is too new."); } r_depth = f->get_32(); //depth @@ -887,7 +994,7 @@ Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_da r_data.clear(); for (int i = 0; i < (r_depth + mipmaps); i++) { - Ref<Image> image = StreamTexture2D::load_image_from_file(f, 0); + Ref<Image> image = CompressedTexture2D::load_image_from_file(f, 0); ERR_FAIL_COND_V(image.is_null() || image->is_empty(), ERR_CANT_OPEN); if (i == 0) { r_format = image->get_format(); @@ -900,7 +1007,7 @@ Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_da return OK; } -Error StreamTexture3D::load(const String &p_path) { +Error CompressedTexture3D::load(const String &p_path) { Vector<Ref<Image>> data; int tw, th, td; @@ -937,34 +1044,34 @@ Error StreamTexture3D::load(const String &p_path) { return OK; } -String StreamTexture3D::get_load_path() const { +String CompressedTexture3D::get_load_path() const { return path_to_file; } -int StreamTexture3D::get_width() const { +int CompressedTexture3D::get_width() const { return w; } -int StreamTexture3D::get_height() const { +int CompressedTexture3D::get_height() const { return h; } -int StreamTexture3D::get_depth() const { +int CompressedTexture3D::get_depth() const { return d; } -bool StreamTexture3D::has_mipmaps() const { +bool CompressedTexture3D::has_mipmaps() const { return mipmaps; } -RID StreamTexture3D::get_rid() const { +RID CompressedTexture3D::get_rid() const { if (!texture.is_valid()) { texture = RS::get_singleton()->texture_3d_placeholder_create(); } return texture; } -Vector<Ref<Image>> StreamTexture3D::get_data() const { +Vector<Ref<Image>> CompressedTexture3D::get_data() const { if (texture.is_valid()) { return RS::get_singleton()->texture_3d_get(texture); } else { @@ -972,7 +1079,7 @@ Vector<Ref<Image>> StreamTexture3D::get_data() const { } } -void StreamTexture3D::reload_from_file() { +void CompressedTexture3D::reload_from_file() { String path = get_path(); if (!path.is_resource_file()) { return; @@ -987,19 +1094,19 @@ void StreamTexture3D::reload_from_file() { load(path); } -void StreamTexture3D::_validate_property(PropertyInfo &property) const { +void CompressedTexture3D::_validate_property(PropertyInfo &property) const { } -void StreamTexture3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture3D::load); - ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture3D::get_load_path); +void CompressedTexture3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("load", "path"), &CompressedTexture3D::load); + ClassDB::bind_method(D_METHOD("get_load_path"), &CompressedTexture3D::get_load_path); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.ctex"), "load", "get_load_path"); } -StreamTexture3D::StreamTexture3D() {} +CompressedTexture3D::CompressedTexture3D() {} -StreamTexture3D::~StreamTexture3D() { +CompressedTexture3D::~CompressedTexture3D() { if (texture.is_valid()) { RS::get_singleton()->free(texture); } @@ -1007,8 +1114,8 @@ StreamTexture3D::~StreamTexture3D() { ///////////////////////////// -RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { - Ref<StreamTexture3D> st; +RES ResourceFormatLoaderCompressedTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { + Ref<CompressedTexture3D> st; st.instantiate(); Error err = st->load(p_path); if (r_error) { @@ -1021,17 +1128,17 @@ RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String return st; } -void ResourceFormatLoaderStreamTexture3D::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("stex3d"); +void ResourceFormatLoaderCompressedTexture3D::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("ctex3d"); } -bool ResourceFormatLoaderStreamTexture3D::handles_type(const String &p_type) const { - return p_type == "StreamTexture3D"; +bool ResourceFormatLoaderCompressedTexture3D::handles_type(const String &p_type) const { + return p_type == "CompressedTexture3D"; } -String ResourceFormatLoaderStreamTexture3D::get_resource_type(const String &p_path) const { - if (p_path.get_extension().to_lower() == "stex3d") { - return "StreamTexture3D"; +String ResourceFormatLoaderCompressedTexture3D::get_resource_type(const String &p_path) const { + if (p_path.get_extension().to_lower() == "ctex3d") { + return "CompressedTexture3D"; } return ""; } @@ -2446,6 +2553,63 @@ AnimatedTexture::~AnimatedTexture() { /////////////////////////////// +Image::Format TextureLayered::get_format() const { + Image::Format ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_format, ret)) { + return ret; + } + return Image::FORMAT_MAX; +} + +TextureLayered::LayeredType TextureLayered::get_layered_type() const { + uint32_t ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_layered_type, ret)) { + return (LayeredType)ret; + } + return LAYERED_TYPE_2D_ARRAY; +} + +int TextureLayered::get_width() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) { + return ret; + } + return 0; +} + +int TextureLayered::get_height() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_height, ret)) { + return ret; + } + return 0; +} + +int TextureLayered::get_layers() const { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_layers, ret)) { + return ret; + } + + return 0; +} + +bool TextureLayered::has_mipmaps() const { + bool ret; + if (GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret)) { + return ret; + } + return false; +} + +Ref<Image> TextureLayered::get_layer_data(int p_layer) const { + Ref<Image> ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_layer_data, p_layer, ret)) { + return ret; + } + return Ref<Image>(); +} + void TextureLayered::_bind_methods() { ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format); ClassDB::bind_method(D_METHOD("get_layered_type"), &TextureLayered::get_layered_type); @@ -2458,6 +2622,14 @@ void TextureLayered::_bind_methods() { BIND_ENUM_CONSTANT(LAYERED_TYPE_2D_ARRAY); BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP); BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP_ARRAY); + + GDVIRTUAL_BIND(_get_format); + GDVIRTUAL_BIND(_get_layered_type); + GDVIRTUAL_BIND(_get_width); + GDVIRTUAL_BIND(_get_height); + GDVIRTUAL_BIND(_get_layers); + GDVIRTUAL_BIND(_has_mipmaps); + GDVIRTUAL_BIND(_get_layer_data, "layer_index"); } /////////////////////////////// @@ -2599,7 +2771,7 @@ ImageTextureLayered::~ImageTextureLayered() { /////////////////////////////////////////// -void StreamTextureLayered::set_path(const String &p_path, bool p_take_over) { +void CompressedTextureLayered::set_path(const String &p_path, bool p_take_over) { if (texture.is_valid()) { RenderingServer::get_singleton()->texture_set_path(texture, p_path); } @@ -2607,11 +2779,11 @@ void StreamTextureLayered::set_path(const String &p_path, bool p_take_over) { Resource::set_path(p_path, p_take_over); } -Image::Format StreamTextureLayered::get_format() const { +Image::Format CompressedTextureLayered::get_format() const { return format; } -Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit) { +Error CompressedTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit) { ERR_FAIL_COND_V(images.size() != 0, ERR_INVALID_PARAMETER); FileAccessRef f = FileAccess::open(p_path, FileAccess::READ); @@ -2620,13 +2792,13 @@ Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> uint8_t header[4]; f->get_buffer(header, 4); if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L') { - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture layered file is corrupt (Bad header)."); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture layered file is corrupt (Bad header)."); } uint32_t version = f->get_32(); if (version > FORMAT_VERSION) { - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new."); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is too new."); } uint32_t layer_count = f->get_32(); //layer count @@ -2647,7 +2819,7 @@ Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> images.resize(layer_count); for (uint32_t i = 0; i < layer_count; i++) { - Ref<Image> image = StreamTexture2D::load_image_from_file(f, p_size_limit); + Ref<Image> image = CompressedTexture2D::load_image_from_file(f, p_size_limit); ERR_FAIL_COND_V(image.is_null() || image->is_empty(), ERR_CANT_OPEN); images.write[i] = image; } @@ -2655,7 +2827,7 @@ Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> return OK; } -Error StreamTextureLayered::load(const String &p_path) { +Error CompressedTextureLayered::load(const String &p_path) { Vector<Ref<Image>> images; int mipmap_limit; @@ -2690,38 +2862,38 @@ Error StreamTextureLayered::load(const String &p_path) { return OK; } -String StreamTextureLayered::get_load_path() const { +String CompressedTextureLayered::get_load_path() const { return path_to_file; } -int StreamTextureLayered::get_width() const { +int CompressedTextureLayered::get_width() const { return w; } -int StreamTextureLayered::get_height() const { +int CompressedTextureLayered::get_height() const { return h; } -int StreamTextureLayered::get_layers() const { +int CompressedTextureLayered::get_layers() const { return layers; } -bool StreamTextureLayered::has_mipmaps() const { +bool CompressedTextureLayered::has_mipmaps() const { return mipmaps; } -TextureLayered::LayeredType StreamTextureLayered::get_layered_type() const { +TextureLayered::LayeredType CompressedTextureLayered::get_layered_type() const { return layered_type; } -RID StreamTextureLayered::get_rid() const { +RID CompressedTextureLayered::get_rid() const { if (!texture.is_valid()) { texture = RS::get_singleton()->texture_2d_layered_placeholder_create(RS::TextureLayeredType(layered_type)); } return texture; } -Ref<Image> StreamTextureLayered::get_layer_data(int p_layer) const { +Ref<Image> CompressedTextureLayered::get_layer_data(int p_layer) const { if (texture.is_valid()) { return RS::get_singleton()->texture_2d_layer_get(texture, p_layer); } else { @@ -2729,7 +2901,7 @@ Ref<Image> StreamTextureLayered::get_layer_data(int p_layer) const { } } -void StreamTextureLayered::reload_from_file() { +void CompressedTextureLayered::reload_from_file() { String path = get_path(); if (!path.is_resource_file()) { return; @@ -2744,21 +2916,21 @@ void StreamTextureLayered::reload_from_file() { load(path); } -void StreamTextureLayered::_validate_property(PropertyInfo &property) const { +void CompressedTextureLayered::_validate_property(PropertyInfo &property) const { } -void StreamTextureLayered::_bind_methods() { - ClassDB::bind_method(D_METHOD("load", "path"), &StreamTextureLayered::load); - ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTextureLayered::get_load_path); +void CompressedTextureLayered::_bind_methods() { + ClassDB::bind_method(D_METHOD("load", "path"), &CompressedTextureLayered::load); + ClassDB::bind_method(D_METHOD("get_load_path"), &CompressedTextureLayered::get_load_path); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.ctex"), "load", "get_load_path"); } -StreamTextureLayered::StreamTextureLayered(LayeredType p_type) { +CompressedTextureLayered::CompressedTextureLayered(LayeredType p_type) { layered_type = p_type; } -StreamTextureLayered::~StreamTextureLayered() { +CompressedTextureLayered::~CompressedTextureLayered() { if (texture.is_valid()) { RS::get_singleton()->free(texture); } @@ -2766,27 +2938,27 @@ StreamTextureLayered::~StreamTextureLayered() { ///////////////////////////////////////////////// -RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { - Ref<StreamTextureLayered> st; - if (p_path.get_extension().to_lower() == "stexarray") { - Ref<StreamTexture2DArray> s; - s.instantiate(); - st = s; - } else if (p_path.get_extension().to_lower() == "scube") { - Ref<StreamCubemap> s; - s.instantiate(); - st = s; - } else if (p_path.get_extension().to_lower() == "scubearray") { - Ref<StreamCubemapArray> s; - s.instantiate(); - st = s; +RES ResourceFormatLoaderCompressedTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { + Ref<CompressedTextureLayered> ct; + if (p_path.get_extension().to_lower() == "ctexarray") { + Ref<CompressedTexture2DArray> c; + c.instantiate(); + ct = c; + } else if (p_path.get_extension().to_lower() == "ccube") { + Ref<CompressedCubemap> c; + c.instantiate(); + ct = c; + } else if (p_path.get_extension().to_lower() == "ccubearray") { + Ref<CompressedCubemapArray> c; + c.instantiate(); + ct = c; } else { if (r_error) { *r_error = ERR_FILE_UNRECOGNIZED; } return RES(); } - Error err = st->load(p_path); + Error err = ct->load(p_path); if (r_error) { *r_error = err; } @@ -2794,28 +2966,28 @@ RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const S return RES(); } - return st; + return ct; } -void ResourceFormatLoaderStreamTextureLayered::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("stexarray"); - p_extensions->push_back("scube"); - p_extensions->push_back("scubearray"); +void ResourceFormatLoaderCompressedTextureLayered::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("ctexarray"); + p_extensions->push_back("ccube"); + p_extensions->push_back("ccubearray"); } -bool ResourceFormatLoaderStreamTextureLayered::handles_type(const String &p_type) const { - return p_type == "StreamTexture2DArray" || p_type == "StreamCubemap" || p_type == "StreamCubemapArray"; +bool ResourceFormatLoaderCompressedTextureLayered::handles_type(const String &p_type) const { + return p_type == "CompressedTexture2DArray" || p_type == "CompressedCubemap" || p_type == "CompressedCubemapArray"; } -String ResourceFormatLoaderStreamTextureLayered::get_resource_type(const String &p_path) const { - if (p_path.get_extension().to_lower() == "stexarray") { - return "StreamTexture2DArray"; +String ResourceFormatLoaderCompressedTextureLayered::get_resource_type(const String &p_path) const { + if (p_path.get_extension().to_lower() == "ctexarray") { + return "CompressedTexture2DArray"; } - if (p_path.get_extension().to_lower() == "scube") { - return "StreamCubemap"; + if (p_path.get_extension().to_lower() == "ccube") { + return "CompressedCubemap"; } - if (p_path.get_extension().to_lower() == "scubearray") { - return "StreamCubemapArray"; + if (p_path.get_extension().to_lower() == "ccubearray") { + return "CompressedCubemapArray"; } return ""; } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 8075497c42..1e07b83547 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -57,14 +57,23 @@ class Texture2D : public Texture { protected: static void _bind_methods(); + GDVIRTUAL0RC(int, _get_width) + GDVIRTUAL0RC(int, _get_height) + GDVIRTUAL2RC(bool, _is_pixel_opaque, int, int) + GDVIRTUAL0RC(bool, _has_alpha) + + GDVIRTUAL4C(_draw, RID, Point2, Color, bool) + GDVIRTUAL5C(_draw_rect, RID, Rect2, bool, Color, bool) + GDVIRTUAL6C(_draw_rect_region, RID, Rect2, Rect2, Color, bool, bool) + public: - virtual int get_width() const = 0; - virtual int get_height() const = 0; + virtual int get_width() const; + virtual int get_height() const; virtual Size2 get_size() const; virtual bool is_pixel_opaque(int p_x, int p_y) const; - virtual bool has_alpha() const = 0; + virtual bool has_alpha() const; virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; @@ -128,8 +137,8 @@ public: ~ImageTexture(); }; -class StreamTexture2D : public Texture2D { - GDCLASS(StreamTexture2D, Texture2D); +class CompressedTexture2D : public Texture2D { + GDCLASS(CompressedTexture2D, Texture2D); public: enum DataFormat { @@ -174,8 +183,8 @@ protected: public: static Ref<Image> load_image_from_file(FileAccess *p_file, int p_size_limit); - typedef void (*TextureFormatRequestCallback)(const Ref<StreamTexture2D> &); - typedef void (*TextureFormatRoughnessRequestCallback)(const Ref<StreamTexture2D> &, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel); + typedef void (*TextureFormatRequestCallback)(const Ref<CompressedTexture2D> &); + typedef void (*TextureFormatRoughnessRequestCallback)(const Ref<CompressedTexture2D> &, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel); static TextureFormatRequestCallback request_3d_callback; static TextureFormatRoughnessRequestCallback request_roughness_callback; @@ -200,11 +209,11 @@ public: virtual Ref<Image> get_image() const override; - StreamTexture2D(); - ~StreamTexture2D(); + CompressedTexture2D(); + ~CompressedTexture2D(); }; -class ResourceFormatLoaderStreamTexture2D : public ResourceFormatLoader { +class ResourceFormatLoaderCompressedTexture2D : public ResourceFormatLoader { public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; @@ -300,6 +309,13 @@ class TextureLayered : public Texture { protected: static void _bind_methods(); + GDVIRTUAL0RC(Image::Format, _get_format) + GDVIRTUAL0RC(uint32_t, _get_layered_type) + GDVIRTUAL0RC(int, _get_width) + GDVIRTUAL0RC(int, _get_height) + GDVIRTUAL0RC(int, _get_layers) + GDVIRTUAL0RC(bool, _has_mipmaps) + GDVIRTUAL1RC(Ref<Image>, _get_layer_data, int) public: enum LayeredType { LAYERED_TYPE_2D_ARRAY, @@ -307,13 +323,15 @@ public: LAYERED_TYPE_CUBEMAP_ARRAY }; - virtual Image::Format get_format() const = 0; - virtual LayeredType get_layered_type() const = 0; - virtual int get_width() const = 0; - virtual int get_height() const = 0; - virtual int get_layers() const = 0; - virtual bool has_mipmaps() const = 0; - virtual Ref<Image> get_layer_data(int p_layer) const = 0; + virtual Image::Format get_format() const; + virtual LayeredType get_layered_type() const; + virtual int get_width() const; + virtual int get_height() const; + virtual int get_layers() const; + virtual bool has_mipmaps() const; + virtual Ref<Image> get_layer_data(int p_layer) const; + + TextureLayered() {} }; VARIANT_ENUM_CAST(TextureLayered::LayeredType) @@ -380,8 +398,8 @@ public: ImageTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {} }; -class StreamTextureLayered : public TextureLayered { - GDCLASS(StreamTextureLayered, TextureLayered); +class CompressedTextureLayered : public TextureLayered { + GDCLASS(CompressedTextureLayered, TextureLayered); public: enum DataFormat { @@ -433,34 +451,34 @@ public: virtual Ref<Image> get_layer_data(int p_layer) const override; - StreamTextureLayered(LayeredType p_layered_type); - ~StreamTextureLayered(); + CompressedTextureLayered(LayeredType p_layered_type); + ~CompressedTextureLayered(); }; -class StreamTexture2DArray : public StreamTextureLayered { - GDCLASS(StreamTexture2DArray, StreamTextureLayered) +class CompressedTexture2DArray : public CompressedTextureLayered { + GDCLASS(CompressedTexture2DArray, CompressedTextureLayered) public: - StreamTexture2DArray() : - StreamTextureLayered(LAYERED_TYPE_2D_ARRAY) {} + CompressedTexture2DArray() : + CompressedTextureLayered(LAYERED_TYPE_2D_ARRAY) {} }; -class StreamCubemap : public StreamTextureLayered { - GDCLASS(StreamCubemap, StreamTextureLayered); +class CompressedCubemap : public CompressedTextureLayered { + GDCLASS(CompressedCubemap, CompressedTextureLayered); public: - StreamCubemap() : - StreamTextureLayered(LAYERED_TYPE_CUBEMAP) {} + CompressedCubemap() : + CompressedTextureLayered(LAYERED_TYPE_CUBEMAP) {} }; -class StreamCubemapArray : public StreamTextureLayered { - GDCLASS(StreamCubemapArray, StreamTextureLayered); +class CompressedCubemapArray : public CompressedTextureLayered { + GDCLASS(CompressedCubemapArray, CompressedTextureLayered); public: - StreamCubemapArray() : - StreamTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {} + CompressedCubemapArray() : + CompressedTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {} }; -class ResourceFormatLoaderStreamTextureLayered : public ResourceFormatLoader { +class ResourceFormatLoaderCompressedTextureLayered : public ResourceFormatLoader { public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; @@ -474,15 +492,21 @@ class Texture3D : public Texture { protected: static void _bind_methods(); - TypedArray<Image> _get_data() const; - -public: - virtual Image::Format get_format() const = 0; - virtual int get_width() const = 0; - virtual int get_height() const = 0; - virtual int get_depth() const = 0; - virtual bool has_mipmaps() const = 0; - virtual Vector<Ref<Image>> get_data() const = 0; + TypedArray<Image> _get_datai() const; + + GDVIRTUAL0RC(Image::Format, _get_format) + GDVIRTUAL0RC(int, _get_width) + GDVIRTUAL0RC(int, _get_height) + GDVIRTUAL0RC(int, _get_depth) + GDVIRTUAL0RC(bool, _has_mipmaps) + GDVIRTUAL0RC(TypedArray<Image>, _get_data) +public: + virtual Image::Format get_format() const; + virtual int get_width() const; + virtual int get_height() const; + virtual int get_depth() const; + virtual bool has_mipmaps() const; + virtual Vector<Ref<Image>> get_data() const; }; class ImageTexture3D : public Texture3D { @@ -520,8 +544,8 @@ public: ~ImageTexture3D(); }; -class StreamTexture3D : public Texture3D { - GDCLASS(StreamTexture3D, Texture3D); +class CompressedTexture3D : public Texture3D { + GDCLASS(CompressedTexture3D, Texture3D); public: enum DataFormat { @@ -571,11 +595,11 @@ public: virtual Vector<Ref<Image>> get_data() const override; - StreamTexture3D(); - ~StreamTexture3D(); + CompressedTexture3D(); + ~CompressedTexture3D(); }; -class ResourceFormatLoaderStreamTexture3D : public ResourceFormatLoader { +class ResourceFormatLoaderCompressedTexture3D : public ResourceFormatLoader { public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index f962e55666..373fbb94ea 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "theme.h" + #include "core/string/print_string.h" // Universal Theme resources used when no other theme has the item. @@ -401,6 +402,26 @@ void Theme::add_icon_type(const StringName &p_theme_type) { icon_map[p_theme_type] = HashMap<StringName, Ref<Texture2D>>(); } +void Theme::remove_icon_type(const StringName &p_theme_type) { + if (!icon_map.has(p_theme_type)) { + return; + } + + _freeze_change_propagation(); + + const StringName *L = nullptr; + while ((L = icon_map[p_theme_type].next(L))) { + Ref<Texture2D> icon = icon_map[p_theme_type][*L]; + if (icon.is_valid()) { + icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + } + } + + icon_map.erase(p_theme_type); + + _unfreeze_and_propagate_changes(); +} + void Theme::get_icon_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -488,6 +509,26 @@ void Theme::add_stylebox_type(const StringName &p_theme_type) { style_map[p_theme_type] = HashMap<StringName, Ref<StyleBox>>(); } +void Theme::remove_stylebox_type(const StringName &p_theme_type) { + if (!style_map.has(p_theme_type)) { + return; + } + + _freeze_change_propagation(); + + const StringName *L = nullptr; + while ((L = style_map[p_theme_type].next(L))) { + Ref<StyleBox> style = style_map[p_theme_type][*L]; + if (style.is_valid()) { + style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + } + } + + style_map.erase(p_theme_type); + + _unfreeze_and_propagate_changes(); +} + void Theme::get_stylebox_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -577,6 +618,26 @@ void Theme::add_font_type(const StringName &p_theme_type) { font_map[p_theme_type] = HashMap<StringName, Ref<Font>>(); } +void Theme::remove_font_type(const StringName &p_theme_type) { + if (!font_map.has(p_theme_type)) { + return; + } + + _freeze_change_propagation(); + + const StringName *L = nullptr; + while ((L = font_map[p_theme_type].next(L))) { + Ref<Font> font = font_map[p_theme_type][*L]; + if (font.is_valid()) { + font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + } + } + + font_map.erase(p_theme_type); + + _unfreeze_and_propagate_changes(); +} + void Theme::get_font_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -653,6 +714,14 @@ void Theme::add_font_size_type(const StringName &p_theme_type) { font_size_map[p_theme_type] = HashMap<StringName, int>(); } +void Theme::remove_font_size_type(const StringName &p_theme_type) { + if (!font_size_map.has(p_theme_type)) { + return; + } + + font_size_map.erase(p_theme_type); +} + void Theme::get_font_size_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -727,6 +796,14 @@ void Theme::add_color_type(const StringName &p_theme_type) { color_map[p_theme_type] = HashMap<StringName, Color>(); } +void Theme::remove_color_type(const StringName &p_theme_type) { + if (!color_map.has(p_theme_type)) { + return; + } + + color_map.erase(p_theme_type); +} + void Theme::get_color_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -801,6 +878,14 @@ void Theme::add_constant_type(const StringName &p_theme_type) { constant_map[p_theme_type] = HashMap<StringName, int>(); } +void Theme::remove_constant_type(const StringName &p_theme_type) { + if (!constant_map.has(p_theme_type)) { + return; + } + + constant_map.erase(p_theme_type); +} + void Theme::get_constant_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -1017,6 +1102,31 @@ void Theme::add_theme_item_type(DataType p_data_type, const StringName &p_theme_ } } +void Theme::remove_theme_item_type(DataType p_data_type, const StringName &p_theme_type) { + switch (p_data_type) { + case DATA_TYPE_COLOR: + remove_color_type(p_theme_type); + break; + case DATA_TYPE_CONSTANT: + remove_constant_type(p_theme_type); + break; + case DATA_TYPE_FONT: + remove_font_type(p_theme_type); + break; + case DATA_TYPE_FONT_SIZE: + remove_font_size_type(p_theme_type); + break; + case DATA_TYPE_ICON: + remove_icon_type(p_theme_type); + break; + case DATA_TYPE_STYLEBOX: + remove_stylebox_type(p_theme_type); + break; + case DATA_TYPE_MAX: + break; // Can't happen, but silences warning. + } +} + void Theme::get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const { switch (p_data_type) { case DATA_TYPE_COLOR: @@ -1101,6 +1211,38 @@ void Theme::get_type_variation_list(const StringName &p_base_type, List<StringNa } // Theme types. +void Theme::add_type(const StringName &p_theme_type) { + // Add a record to every data type map. + for (int i = 0; i < Theme::DATA_TYPE_MAX; i++) { + Theme::DataType dt = (Theme::DataType)i; + add_theme_item_type(dt, p_theme_type); + } + + _emit_theme_changed(true); +} + +void Theme::remove_type(const StringName &p_theme_type) { + // Gracefully remove the record from every data type map. + for (int i = 0; i < Theme::DATA_TYPE_MAX; i++) { + Theme::DataType dt = (Theme::DataType)i; + remove_theme_item_type(dt, p_theme_type); + } + + // If type is a variation, remove that connection. + if (get_type_variation_base(p_theme_type) != StringName()) { + clear_type_variation(p_theme_type); + } + + // If type is a variation base, remove all those connections. + List<StringName> names; + get_type_variation_list(p_theme_type, &names); + for (const StringName &E : names) { + clear_type_variation(E); + } + + _emit_theme_changed(true); +} + void Theme::get_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -1668,6 +1810,8 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("get_type_variation_base", "theme_type"), &Theme::get_type_variation_base); ClassDB::bind_method(D_METHOD("get_type_variation_list", "base_type"), &Theme::_get_type_variation_list); + ClassDB::bind_method(D_METHOD("add_type", "theme_type"), &Theme::add_type); + ClassDB::bind_method(D_METHOD("remove_type", "theme_type"), &Theme::remove_type); ClassDB::bind_method(D_METHOD("get_type_list"), &Theme::_get_type_list); ClassDB::bind_method(D_METHOD("merge_with", "other"), &Theme::merge_with); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 822743a1fe..9afe05007d 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -32,7 +32,6 @@ #define THEME_H #include "core/io/resource.h" -#include "core/io/resource_loader.h" #include "scene/resources/font.h" #include "scene/resources/style_box.h" #include "scene/resources/texture.h" @@ -158,6 +157,7 @@ public: void clear_icon(const StringName &p_name, const StringName &p_theme_type); void get_icon_list(StringName p_theme_type, List<StringName> *p_list) const; void add_icon_type(const StringName &p_theme_type); + void remove_icon_type(const StringName &p_theme_type); void get_icon_type_list(List<StringName> *p_list) const; void set_stylebox(const StringName &p_name, const StringName &p_theme_type, const Ref<StyleBox> &p_style); @@ -168,6 +168,7 @@ public: void clear_stylebox(const StringName &p_name, const StringName &p_theme_type); void get_stylebox_list(StringName p_theme_type, List<StringName> *p_list) const; void add_stylebox_type(const StringName &p_theme_type); + void remove_stylebox_type(const StringName &p_theme_type); void get_stylebox_type_list(List<StringName> *p_list) const; void set_font(const StringName &p_name, const StringName &p_theme_type, const Ref<Font> &p_font); @@ -178,6 +179,7 @@ public: void clear_font(const StringName &p_name, const StringName &p_theme_type); void get_font_list(StringName p_theme_type, List<StringName> *p_list) const; void add_font_type(const StringName &p_theme_type); + void remove_font_type(const StringName &p_theme_type); void get_font_type_list(List<StringName> *p_list) const; void set_font_size(const StringName &p_name, const StringName &p_theme_type, int p_font_size); @@ -188,6 +190,7 @@ public: void clear_font_size(const StringName &p_name, const StringName &p_theme_type); void get_font_size_list(StringName p_theme_type, List<StringName> *p_list) const; void add_font_size_type(const StringName &p_theme_type); + void remove_font_size_type(const StringName &p_theme_type); void get_font_size_type_list(List<StringName> *p_list) const; void set_color(const StringName &p_name, const StringName &p_theme_type, const Color &p_color); @@ -198,6 +201,7 @@ public: void clear_color(const StringName &p_name, const StringName &p_theme_type); void get_color_list(StringName p_theme_type, List<StringName> *p_list) const; void add_color_type(const StringName &p_theme_type); + void remove_color_type(const StringName &p_theme_type); void get_color_type_list(List<StringName> *p_list) const; void set_constant(const StringName &p_name, const StringName &p_theme_type, int p_constant); @@ -208,6 +212,7 @@ public: void clear_constant(const StringName &p_name, const StringName &p_theme_type); void get_constant_list(StringName p_theme_type, List<StringName> *p_list) const; void add_constant_type(const StringName &p_theme_type); + void remove_constant_type(const StringName &p_theme_type); void get_constant_type_list(List<StringName> *p_list) const; void set_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type, const Variant &p_value); @@ -218,6 +223,7 @@ public: void clear_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type); void get_theme_item_list(DataType p_data_type, StringName p_theme_type, List<StringName> *p_list) const; void add_theme_item_type(DataType p_data_type, const StringName &p_theme_type); + void remove_theme_item_type(DataType p_data_type, const StringName &p_theme_type); void get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const; void set_type_variation(const StringName &p_theme_type, const StringName &p_base_type); @@ -226,6 +232,8 @@ public: StringName get_type_variation_base(const StringName &p_theme_type) const; void get_type_variation_list(const StringName &p_base_type, List<StringName> *p_list) const; + void add_type(const StringName &p_theme_type); + void remove_type(const StringName &p_theme_type); void get_type_list(List<StringName> *p_list) const; void get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variant, List<StringName> *p_list); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 1e84947b87..1174117028 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -4432,6 +4432,10 @@ void TileSetAtlasSource::_update_padded_texture() { Ref<Image> src = texture->get_image(); + if (!src.is_valid()) { + return; + } + Ref<Image> image; image.instantiate(); image->create(size.x, size.y, false, src->get_format()); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index dae61c8609..d3e61dbc84 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -455,32 +455,69 @@ String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader:: for (int i = 0; i < get_output_port_count(); i++) { output_vars.push_back(p_output_vars[i]); } - String code = " {\n"; + String _code; GDVIRTUAL_CALL(_get_code, input_vars, output_vars, p_mode, p_type, _code); - bool nend = _code.ends_with("\n"); - _code = _code.insert(0, " "); - _code = _code.replace("\n", "\n "); - code += _code; - if (!nend) { - code += "\n }"; - } else { - code.remove_at(code.size() - 1); - code += "}"; + if (_is_valid_code(_code)) { + String code = " {\n"; + bool nend = _code.ends_with("\n"); + _code = _code.insert(0, " "); + _code = _code.replace("\n", "\n "); + code += _code; + if (!nend) { + code += "\n }"; + } else { + code.remove_at(code.size() - 1); + code += "}"; + } + code += "\n"; + return code; } - code += "\n"; - return code; + return String(); } String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, int p_id) const { - String ret; - if (GDVIRTUAL_CALL(_get_global_code, p_mode, ret)) { - String code = "// " + get_caption() + "\n"; - code += ret; - code += "\n"; - return code; + String _code; + if (GDVIRTUAL_CALL(_get_global_code, p_mode, _code)) { + if (_is_valid_code(_code)) { + String code = "// " + get_caption() + "\n"; + code += _code; + code += "\n"; + return code; + } } - return ""; + return String(); +} + +String VisualShaderNodeCustom::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String _code; + if (GDVIRTUAL_CALL(_get_func_code, p_mode, p_type, _code)) { + if (_is_valid_code(_code)) { + bool nend = _code.ends_with("\n"); + String code = "// " + get_caption() + "\n"; + code += " {\n"; + _code = _code.insert(0, " "); + _code = _code.replace("\n", "\n "); + code += _code; + if (!nend) { + code += "\n }"; + } else { + code.remove_at(code.size() - 1); + code += "}"; + } + code += "\n"; + return code; + } + } + return String(); +} + +bool VisualShaderNodeCustom::is_available(Shader::Mode p_mode, VisualShader::Type p_type) const { + bool ret; + if (GDVIRTUAL_CALL(_is_available, p_mode, p_type, ret)) { + return ret; + } + return true; } void VisualShaderNodeCustom::set_input_port_default_value(int p_port, const Variant &p_value, const Variant &p_prev_value) { @@ -511,6 +548,13 @@ void VisualShaderNodeCustom::_set_input_port_default_value(int p_port, const Var VisualShaderNode::set_input_port_default_value(p_port, p_value); } +bool VisualShaderNodeCustom::_is_valid_code(const String &p_code) const { + if (p_code.is_empty() || p_code == "null") { + return false; + } + return true; +} + bool VisualShaderNodeCustom::_is_initialized() { return is_initialized; } @@ -531,8 +575,10 @@ void VisualShaderNodeCustom::_bind_methods() { GDVIRTUAL_BIND(_get_output_port_type, "port"); GDVIRTUAL_BIND(_get_output_port_name, "port"); GDVIRTUAL_BIND(_get_code, "input_vars", "output_vars", "mode", "type"); + GDVIRTUAL_BIND(_get_func_code, "mode", "type"); GDVIRTUAL_BIND(_get_global_code, "mode"); GDVIRTUAL_BIND(_is_highend); + GDVIRTUAL_BIND(_is_available, "mode", "type"); ClassDB::bind_method(D_METHOD("_set_initialized", "enabled"), &VisualShaderNodeCustom::_set_initialized); ClassDB::bind_method(D_METHOD("_is_initialized"), &VisualShaderNodeCustom::_is_initialized); @@ -555,6 +601,72 @@ VisualShader::Type VisualShader::get_shader_type() const { return current_type; } +void VisualShader::add_varying(const String &p_name, VaryingMode p_mode, VaryingType p_type) { + ERR_FAIL_COND(!p_name.is_valid_identifier()); + ERR_FAIL_INDEX((int)p_mode, (int)VARYING_MODE_MAX); + ERR_FAIL_INDEX((int)p_type, (int)VARYING_TYPE_MAX); + ERR_FAIL_COND(varyings.has(p_name)); + Varying var = Varying(p_name, p_mode, p_type); + varyings[p_name] = var; + varyings_list.push_back(var); + _queue_update(); +} + +void VisualShader::remove_varying(const String &p_name) { + ERR_FAIL_COND(!varyings.has(p_name)); + varyings.erase(p_name); + for (List<Varying>::Element *E = varyings_list.front(); E; E = E->next()) { + if (E->get().name == p_name) { + varyings_list.erase(E); + break; + } + } + _queue_update(); +} + +bool VisualShader::has_varying(const String &p_name) const { + return varyings.has(p_name); +} + +int VisualShader::get_varyings_count() const { + return varyings_list.size(); +} + +const VisualShader::Varying *VisualShader::get_varying_by_index(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, varyings_list.size(), nullptr); + return &varyings_list[p_idx]; +} + +void VisualShader::set_varying_mode(const String &p_name, VaryingMode p_mode) { + ERR_FAIL_INDEX((int)p_mode, (int)VARYING_MODE_MAX); + ERR_FAIL_COND(!varyings.has(p_name)); + if (varyings[p_name].mode == p_mode) { + return; + } + varyings[p_name].mode = p_mode; + _queue_update(); +} + +VisualShader::VaryingMode VisualShader::get_varying_mode(const String &p_name) { + ERR_FAIL_COND_V(!varyings.has(p_name), VARYING_MODE_MAX); + return varyings[p_name].mode; +} + +void VisualShader::set_varying_type(const String &p_name, VaryingType p_type) { + ERR_FAIL_INDEX((int)p_type, (int)VARYING_TYPE_MAX); + ERR_FAIL_COND(!varyings.has(p_name)); + if (varyings[p_name].type == p_type) { + return; + } + varyings[p_name].type = p_type; + _queue_update(); +} + +VisualShader::VaryingType VisualShader::get_varying_type(const String &p_name) { + ERR_FAIL_COND_V(!varyings.has(p_name), VARYING_TYPE_MAX); + return varyings[p_name].type; +} + void VisualShader::set_engine_version(const Dictionary &p_engine_version) { ERR_FAIL_COND(!p_engine_version.has("major")); ERR_FAIL_COND(!p_engine_version.has("minor")); @@ -1072,7 +1184,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port code += "\nvoid fragment() {\n"; Set<int> processed; - Error err = _write_node(p_type, global_code, global_code_per_node, global_code_per_func, code, default_tex_params, input_connections, output_connections, p_node, processed, true, classes); + Error err = _write_node(p_type, &global_code, &global_code_per_node, &global_code_per_func, code, default_tex_params, input_connections, output_connections, p_node, processed, true, classes); ERR_FAIL_COND_V(err != OK, String()); switch (node->get_output_port_type(p_port)) { @@ -1253,6 +1365,16 @@ bool VisualShader::_set(const StringName &p_name, const Variant &p_value) { } _queue_update(); return true; + } else if (name.begins_with("varyings/")) { + String var_name = name.get_slicec('/', 1); + Varying value = Varying(); + value.name = var_name; + if (value.from_string(p_value) && !varyings.has(var_name)) { + varyings[var_name] = value; + varyings_list.push_back(value); + } + _queue_update(); + return true; } else if (name.begins_with("nodes/")) { String typestr = name.get_slicec('/', 1); Type type = TYPE_VERTEX; @@ -1317,6 +1439,14 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const { r_ret = 0; } return true; + } else if (name.begins_with("varyings/")) { + String var_name = name.get_slicec('/', 1); + if (varyings.has(var_name)) { + r_ret = varyings[var_name].to_string(); + } else { + r_ret = String(); + } + return true; } else if (name.begins_with("nodes/")) { String typestr = name.get_slicec('/', 1); Type type = TYPE_VERTEX; @@ -1411,6 +1541,10 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::BOOL, "flags/" + E->get())); } + for (const KeyValue<String, Varying> &E : varyings) { + p_list->push_back(PropertyInfo(Variant::STRING, "varyings/" + E.key)); + } + for (int i = 0; i < TYPE_MAX; i++) { for (const KeyValue<int, Node> &E : graph[i].nodes) { String prop_name = "nodes/"; @@ -1435,7 +1569,7 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { } } -Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const { +Error VisualShader::_write_node(Type type, StringBuilder *global_code, StringBuilder *global_code_per_node, Map<Type, StringBuilder> *global_code_per_func, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const { const Ref<VisualShaderNode> vsnode = graph[type].nodes[node].node; if (vsnode->is_disabled()) { @@ -1477,7 +1611,9 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui if (!skip_global) { Ref<VisualShaderNodeUniform> uniform = vsnode; if (!uniform.is_valid() || !uniform->is_global_code_generated()) { - global_code += vsnode->generate_global(get_mode(), type, node); + if (global_code) { + *global_code += vsnode->generate_global(get_mode(), type, node); + } } String class_name = vsnode->get_class_name(); @@ -1485,9 +1621,13 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui class_name = vsnode->get_script_instance()->get_script()->get_path(); } if (!r_classes.has(class_name)) { - global_code_per_node += vsnode->generate_global_per_node(get_mode(), node); + if (global_code_per_node) { + *global_code_per_node += vsnode->generate_global_per_node(get_mode(), node); + } for (int i = 0; i < TYPE_MAX; i++) { - global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node); + if (global_code_per_func) { + (*global_code_per_func)[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node); + } } r_classes.insert(class_name); } @@ -1940,6 +2080,7 @@ void VisualShader::_update_shader() const { Set<String> used_uniform_names; List<VisualShaderNodeUniform *> uniforms; Map<int, List<int>> emitters; + Map<int, List<int>> varying_setters; for (int i = 0, index = 0; i < TYPE_MAX; i++) { if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) { @@ -1964,18 +2105,19 @@ void VisualShader::_update_shader() const { if (uniform.is_valid()) { uniforms.push_back(uniform.ptr()); } + Ref<VisualShaderNodeVaryingSetter> varying_setter = Object::cast_to<VisualShaderNodeVaryingSetter>(E->get().node.ptr()); + if (varying_setter.is_valid() && varying_setter->is_input_port_connected(0)) { + if (!varying_setters.has(i)) { + varying_setters.insert(i, List<int>()); + } + varying_setters[i].push_back(E->key()); + } Ref<VisualShaderNodeParticleEmit> emit_particle = Object::cast_to<VisualShaderNodeParticleEmit>(E->get().node.ptr()); if (emit_particle.is_valid()) { if (!emitters.has(i)) { emitters.insert(i, List<int>()); } - - for (const KeyValue<int, Node> &M : graph[i].nodes) { - if (M.value.node == emit_particle.ptr()) { - emitters[i].push_back(M.key); - break; - } - } + emitters[i].push_back(E->key()); } } } @@ -1990,6 +2132,36 @@ void VisualShader::_update_shader() const { } } + if (!varyings.is_empty()) { + global_code += "\n// Varyings\n"; + + for (const KeyValue<String, Varying> &E : varyings) { + global_code += "varying "; + switch (E.value.type) { + case VaryingType::VARYING_TYPE_FLOAT: + global_code += "float "; + break; + case VaryingType::VARYING_TYPE_VECTOR_2D: + global_code += "vec2 "; + break; + case VaryingType::VARYING_TYPE_VECTOR_3D: + global_code += "vec3 "; + break; + case VaryingType::VARYING_TYPE_COLOR: + global_code += "vec4 "; + break; + case VaryingType::VARYING_TYPE_TRANSFORM: + global_code += "mat4 "; + break; + default: + break; + } + global_code += E.key + ";\n"; + } + + global_code += "\n"; + } + Map<int, String> code_map; Set<int> empty_funcs; @@ -2003,12 +2175,54 @@ void VisualShader::_update_shader() const { VMap<ConnectionKey, const List<Connection>::Element *> output_connections; StringBuilder func_code; + Set<int> processed; bool is_empty_func = false; if (shader_mode != Shader::MODE_PARTICLES && shader_mode != Shader::MODE_SKY && shader_mode != Shader::MODE_FOG) { is_empty_func = true; } + String varying_code; + if (shader_mode == Shader::MODE_SPATIAL || shader_mode == Shader::MODE_CANVAS_ITEM) { + for (const KeyValue<String, Varying> &E : varyings) { + if ((E.value.mode == VARYING_MODE_VERTEX_TO_FRAG_LIGHT && i == TYPE_VERTEX) || (E.value.mode == VARYING_MODE_FRAG_TO_LIGHT && i == TYPE_FRAGMENT)) { + bool found = false; + for (int key : varying_setters[i]) { + Ref<VisualShaderNodeVaryingSetter> setter = Object::cast_to<VisualShaderNodeVaryingSetter>(const_cast<VisualShaderNode *>(graph[i].nodes[key].node.ptr())); + if (setter.is_valid() && E.value.name == setter->get_varying_name()) { + found = true; + break; + } + } + + if (!found) { + String code2; + switch (E.value.type) { + case VaryingType::VARYING_TYPE_FLOAT: + code2 += "0.0"; + break; + case VaryingType::VARYING_TYPE_VECTOR_2D: + code2 += "vec2(0.0)"; + break; + case VaryingType::VARYING_TYPE_VECTOR_3D: + code2 += "vec3(0.0)"; + break; + case VaryingType::VARYING_TYPE_COLOR: + code2 += "vec4(0.0)"; + break; + case VaryingType::VARYING_TYPE_TRANSFORM: + code2 += "mat4(1.0)"; + break; + default: + break; + } + varying_code += vformat(" %s = %s;\n", E.key, code2); + } + is_empty_func = false; + } + } + } + for (const List<Connection>::Element *E = graph[i].connections.front(); E; E = E->next()) { ConnectionKey from_key; from_key.node = E->get().from_node; @@ -2037,13 +2251,19 @@ void VisualShader::_update_shader() const { } insertion_pos.insert(i, code.get_string_length() + func_code.get_string_length()); - Set<int> processed; - Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes); + Error err = _write_node(Type(i), &global_code, &global_code_per_node, &global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes); ERR_FAIL_COND(err != OK); + if (varying_setters.has(i)) { + for (int &E : varying_setters[i]) { + err = _write_node(Type(i), nullptr, nullptr, nullptr, func_code, default_tex_params, input_connections, output_connections, E, processed, false, classes); + ERR_FAIL_COND(err != OK); + } + } + if (emitters.has(i)) { for (int &E : emitters[i]) { - err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, E, processed, false, classes); + err = _write_node(Type(i), &global_code, &global_code_per_node, &global_code_per_func, func_code, default_tex_params, input_connections, output_connections, E, processed, false, classes); ERR_FAIL_COND(err != OK); } } @@ -2051,6 +2271,7 @@ void VisualShader::_update_shader() const { if (shader_mode == Shader::MODE_PARTICLES) { code_map.insert(i, func_code); } else { + func_code += varying_code; func_code += "}\n"; code += func_code; } @@ -2276,6 +2497,10 @@ void VisualShader::_bind_methods() { ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &VisualShader::set_graph_offset); ClassDB::bind_method(D_METHOD("get_graph_offset"), &VisualShader::get_graph_offset); + ClassDB::bind_method(D_METHOD("add_varying", "name", "mode", "type"), &VisualShader::add_varying); + ClassDB::bind_method(D_METHOD("remove_varying", "name"), &VisualShader::remove_varying); + ClassDB::bind_method(D_METHOD("has_varying", "name"), &VisualShader::has_varying); + ClassDB::bind_method(D_METHOD("_update_shader"), &VisualShader::_update_shader); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_graph_offset", "get_graph_offset"); @@ -2295,6 +2520,17 @@ void VisualShader::_bind_methods() { BIND_ENUM_CONSTANT(TYPE_FOG); BIND_ENUM_CONSTANT(TYPE_MAX); + BIND_ENUM_CONSTANT(VARYING_MODE_VERTEX_TO_FRAG_LIGHT); + BIND_ENUM_CONSTANT(VARYING_MODE_FRAG_TO_LIGHT); + BIND_ENUM_CONSTANT(VARYING_MODE_MAX); + + BIND_ENUM_CONSTANT(VARYING_TYPE_FLOAT); + BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_3D); + BIND_ENUM_CONSTANT(VARYING_TYPE_COLOR); + BIND_ENUM_CONSTANT(VARYING_TYPE_TRANSFORM); + BIND_ENUM_CONSTANT(VARYING_TYPE_MAX); + BIND_CONSTANT(NODE_ID_INVALID); BIND_CONSTANT(NODE_ID_OUTPUT); } @@ -2327,6 +2563,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { // Node3D, Vertex { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "vertex", "VERTEX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "vertex_id", "VERTEX_ID" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "normal", "NORMAL" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "tangent", "TANGENT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "binormal", "BINORMAL" }, @@ -2348,6 +2585,9 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "VIEWPORT_SIZE" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" }, // Node3D, Fragment { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "fragcoord", "FRAGCOORD.xyz" }, @@ -2374,6 +2614,9 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "normal_roughness_texture", "NORMAL_ROUGHNESS_TEXTURE" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "depth_texture", "DEPTH_TEXTURE" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" }, // Node3D, Light { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "fragcoord", "FRAGCOORD.xyz" }, @@ -2384,6 +2627,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "light", "LIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "light_color", "LIGHT_COLOR" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "attenuation", "ATTENUATION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "shadow_attenuation", "SHADOW_ATTENUATION" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "albedo", "ALBEDO" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "backlight", "BACKLIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "diffuse", "DIFFUSE_LIGHT" }, @@ -2415,6 +2659,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_light_pass", "AT_LIGHT_PASS" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "instance_custom", "INSTANCE_CUSTOM.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "instance_custom_alpha", "INSTANCE_CUSTOM.a" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "instance_id", "INSTANCE_ID" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "vertex_id", "VERTEX_ID" }, // Canvas Item, Fragment { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "fragcoord", "FRAGCOORD.xyz" }, @@ -3144,6 +3390,7 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "color", "COLOR.rgb" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "model_view_matrix", "MODELVIEW_MATRIX" }, //////////////////////////////////////////////////////////////////////// // Node3D, Fragment. @@ -3155,6 +3402,7 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "specular", "SPECULAR" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "emission", "EMISSION" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao", "AO" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao_light_affect", "AO_LIGHT_AFFECT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "normal", "NORMAL" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "normal_map", "NORMAL_MAP" }, @@ -3163,14 +3411,17 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "rim", "RIM" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "rim_tint", "RIM_TINT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "clearcoat", "CLEARCOAT" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "clearcoat_gloss", "CLEARCOAT_GLOSS" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "clearcoat_roughness", "CLEARCOAT_ROUGHNESS" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "anisotropy", "ANISOTROPY" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "anisotropy_flow", "ANISOTROPY_FLOW" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "subsurf_scatter", "SSS_STRENGTH" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "backlight", "BACKLIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha_scissor_threshold", "ALPHA_SCISSOR_THRESHOLD" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao_light_affect", "AO_LIGHT_AFFECT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha_hash_scale", "ALPHA_HASH_SCALE" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha_aa_edge", "ALPHA_ANTIALIASING_EDGE" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "alpha_uv", "ALPHA_TEXTURE_COORDINATE" }, + //////////////////////////////////////////////////////////////////////// // Node3D, Light. //////////////////////////////////////////////////////////////////////// @@ -3294,7 +3545,7 @@ bool VisualShaderNodeOutput::is_port_separator(int p_index) const { } if (shader_mode == Shader::MODE_SPATIAL && shader_type == VisualShader::TYPE_FRAGMENT) { String name = get_input_port_name(p_index); - return bool(name == "Normal" || name == "Rim" || name == "Alpha Scissor Threshold"); + return bool(name == "Ao" || name == "Normal" || name == "Rim" || name == "Clearcoat" || name == "Anisotropy" || name == "Subsurf Scatter" || name == "Alpha Scissor Threshold"); } return false; } @@ -4199,3 +4450,299 @@ String VisualShaderNodeGlobalExpression::generate_global(Shader::Mode p_mode, Vi VisualShaderNodeGlobalExpression::VisualShaderNodeGlobalExpression() { set_editable(false); } + +////////////// Varying + +List<VisualShaderNodeVarying::Varying> varyings; + +void VisualShaderNodeVarying::add_varying(const String &p_name, VisualShader::VaryingMode p_mode, VisualShader::VaryingType p_type) { // static + varyings.push_back({ p_name, p_mode, p_type }); +} + +void VisualShaderNodeVarying::clear_varyings() { // static + varyings.clear(); +} + +bool VisualShaderNodeVarying::has_varying(const String &p_name) { // static + for (const VisualShaderNodeVarying::Varying &E : varyings) { + if (E.name == p_name) { + return true; + } + } + return false; +} + +int VisualShaderNodeVarying::get_varyings_count() const { + return varyings.size(); +} + +String VisualShaderNodeVarying::get_varying_name_by_index(int p_idx) const { + if (p_idx >= 0 && p_idx < varyings.size()) { + return varyings[p_idx].name; + } + return ""; +} + +VisualShader::VaryingType VisualShaderNodeVarying::get_varying_type_by_name(const String &p_name) const { + for (int i = 0; i < varyings.size(); i++) { + if (varyings[i].name == p_name) { + return varyings[i].type; + } + } + return VisualShader::VARYING_TYPE_FLOAT; +} + +VisualShader::VaryingType VisualShaderNodeVarying::get_varying_type_by_index(int p_idx) const { + if (p_idx >= 0 && p_idx < varyings.size()) { + return varyings[p_idx].type; + } + return VisualShader::VARYING_TYPE_FLOAT; +} + +VisualShader::VaryingMode VisualShaderNodeVarying::get_varying_mode_by_name(const String &p_name) const { + for (int i = 0; i < varyings.size(); i++) { + if (varyings[i].name == p_name) { + return varyings[i].mode; + } + } + return VisualShader::VARYING_MODE_VERTEX_TO_FRAG_LIGHT; +} + +VisualShader::VaryingMode VisualShaderNodeVarying::get_varying_mode_by_index(int p_idx) const { + if (p_idx >= 0 && p_idx < varyings.size()) { + return varyings[p_idx].mode; + } + return VisualShader::VARYING_MODE_VERTEX_TO_FRAG_LIGHT; +} + +VisualShaderNodeVarying::PortType VisualShaderNodeVarying::get_port_type_by_index(int p_idx) const { + if (p_idx >= 0 && p_idx < varyings.size()) { + return get_port_type(varyings[p_idx].type, 0); + } + return PORT_TYPE_SCALAR; +} + +////////////// + +void VisualShaderNodeVarying::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_varying_name", "name"), &VisualShaderNodeVarying::set_varying_name); + ClassDB::bind_method(D_METHOD("get_varying_name"), &VisualShaderNodeVarying::get_varying_name); + + ClassDB::bind_method(D_METHOD("set_varying_type", "type"), &VisualShaderNodeVarying::set_varying_type); + ClassDB::bind_method(D_METHOD("get_varying_type"), &VisualShaderNodeVarying::get_varying_type); + + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "varying_name"), "set_varying_name", "get_varying_name"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "varying_type", PROPERTY_HINT_ENUM, "Float,Vector,Transform"), "set_varying_type", "get_varying_type"); +} + +String VisualShaderNodeVarying::get_type_str() const { + switch (varying_type) { + case VisualShader::VARYING_TYPE_FLOAT: + return "float"; + case VisualShader::VARYING_TYPE_VECTOR_2D: + return "vec2"; + case VisualShader::VARYING_TYPE_VECTOR_3D: + return "vec3"; + case VisualShader::VARYING_TYPE_COLOR: + return "vec4"; + case VisualShader::VARYING_TYPE_TRANSFORM: + return "mat4"; + default: + break; + } + return ""; +} + +VisualShaderNodeVarying::PortType VisualShaderNodeVarying::get_port_type(VisualShader::VaryingType p_type, int p_port) const { + switch (p_type) { + case VisualShader::VARYING_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case VisualShader::VARYING_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + case VisualShader::VARYING_TYPE_COLOR: + if (p_port == 1) { + break; // scalar + } + return PORT_TYPE_VECTOR_3D; + case VisualShader::VARYING_TYPE_TRANSFORM: + return PORT_TYPE_TRANSFORM; + default: + break; + } + return PORT_TYPE_SCALAR; +} + +void VisualShaderNodeVarying::set_varying_name(String p_varying_name) { + if (varying_name == p_varying_name) { + return; + } + varying_name = p_varying_name; + emit_changed(); +} + +String VisualShaderNodeVarying::get_varying_name() const { + return varying_name; +} + +void VisualShaderNodeVarying::set_varying_type(VisualShader::VaryingType p_varying_type) { + ERR_FAIL_INDEX(p_varying_type, VisualShader::VARYING_TYPE_MAX); + if (varying_type == p_varying_type) { + return; + } + varying_type = p_varying_type; + emit_changed(); +} + +VisualShader::VaryingType VisualShaderNodeVarying::get_varying_type() const { + return varying_type; +} + +VisualShaderNodeVarying::VisualShaderNodeVarying() { +} + +////////////// Varying Setter + +String VisualShaderNodeVaryingSetter::get_caption() const { + return vformat("VaryingSetter"); +} + +int VisualShaderNodeVaryingSetter::get_input_port_count() const { + if (varying_type == VisualShader::VARYING_TYPE_COLOR) { + return 2; + } + return 1; +} + +VisualShaderNodeVaryingSetter::PortType VisualShaderNodeVaryingSetter::get_input_port_type(int p_port) const { + return get_port_type(varying_type, p_port); +} + +String VisualShaderNodeVaryingSetter::get_input_port_name(int p_port) const { + if (varying_type == VisualShader::VARYING_TYPE_COLOR) { + if (p_port == 0) { + return "color"; + } else { + return "alpha"; + } + } + return ""; +} + +int VisualShaderNodeVaryingSetter::get_output_port_count() const { + return 0; +} + +VisualShaderNodeVaryingSetter::PortType VisualShaderNodeVaryingSetter::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeVaryingSetter::get_output_port_name(int p_port) const { + return ""; +} + +String VisualShaderNodeVaryingSetter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + return vformat("varying %s %s;\n", get_type_str(), varying_name); +} + +String VisualShaderNodeVaryingSetter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + if (varying_name == "[None]") { + return code; + } + if (varying_type == VisualShader::VARYING_TYPE_COLOR) { + code += vformat(" %s = vec4(%s, %s);\n", varying_name, p_input_vars[0], p_input_vars[1]); + } else { + code += vformat(" %s = %s;\n", varying_name, p_input_vars[0]); + } + return code; +} + +VisualShaderNodeVaryingSetter::VisualShaderNodeVaryingSetter() { +} + +////////////// Varying Getter + +String VisualShaderNodeVaryingGetter::get_caption() const { + return vformat("VaryingGetter"); +} + +int VisualShaderNodeVaryingGetter::get_input_port_count() const { + return 0; +} + +VisualShaderNodeVaryingGetter::PortType VisualShaderNodeVaryingGetter::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeVaryingGetter::get_input_port_name(int p_port) const { + return ""; +} + +int VisualShaderNodeVaryingGetter::get_output_port_count() const { + if (varying_type == VisualShader::VARYING_TYPE_COLOR) { + return 2; + } + return 1; +} + +VisualShaderNodeVaryingGetter::PortType VisualShaderNodeVaryingGetter::get_output_port_type(int p_port) const { + return get_port_type(varying_type, p_port); +} + +String VisualShaderNodeVaryingGetter::get_output_port_name(int p_port) const { + if (varying_type == VisualShader::VARYING_TYPE_COLOR) { + if (p_port == 0) { + return "color"; + } else { + return "alpha"; + } + } + return ""; +} + +bool VisualShaderNodeVaryingGetter::has_output_port_preview(int p_port) const { + return false; +} + +String VisualShaderNodeVaryingGetter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String from = varying_name; + String from2; + + if (varying_name == "[None]") { + switch (varying_type) { + case VisualShader::VARYING_TYPE_FLOAT: + from = "0.0"; + break; + case VisualShader::VARYING_TYPE_VECTOR_2D: + from = "vec2(0.0)"; + break; + case VisualShader::VARYING_TYPE_VECTOR_3D: + from = "vec3(0.0)"; + break; + case VisualShader::VARYING_TYPE_COLOR: + from = "vec3(0.0)"; + from2 = "0.0"; + break; + case VisualShader::VARYING_TYPE_TRANSFORM: + from = "mat4(1.0)"; + break; + default: + break; + } + } else if (varying_type == VisualShader::VARYING_TYPE_COLOR) { + from = varying_name + ".rgb"; + from2 = varying_name + ".a"; + } + + if (varying_type == VisualShader::VARYING_TYPE_COLOR) { + String code; + code += vformat(" %s = %s;\n", p_output_vars[0], from); + code += vformat(" %s = %s;\n", p_output_vars[1], from2); + return code; + } + return vformat(" %s = %s;\n", p_output_vars[0], from); +} + +VisualShaderNodeVaryingGetter::VisualShaderNodeVaryingGetter() { + varying_name = "[None]"; +} diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index d3b5365893..2d4b2852e9 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -73,6 +73,49 @@ public: List<Ref<Texture2D>> params; }; + enum VaryingMode { + VARYING_MODE_VERTEX_TO_FRAG_LIGHT, + VARYING_MODE_FRAG_TO_LIGHT, + VARYING_MODE_MAX, + }; + + enum VaryingType { + VARYING_TYPE_FLOAT, + VARYING_TYPE_VECTOR_2D, + VARYING_TYPE_VECTOR_3D, + VARYING_TYPE_COLOR, + VARYING_TYPE_TRANSFORM, + VARYING_TYPE_MAX, + }; + + struct Varying { + String name; + VaryingMode mode; + VaryingType type; + + Varying() { + } + + Varying(String p_name, VaryingMode p_mode, VaryingType p_type) : + name(p_name), mode(p_mode), type(p_type) {} + + bool from_string(const String &p_str) { + Vector<String> arr = p_str.split(","); + if (arr.size() != 2) { + return false; + } + + mode = (VaryingMode)arr[0].to_int(); + type = (VaryingType)arr[1].to_int(); + + return true; + } + + String to_string() const { + return vformat("%s,%s", itos((int)mode), itos((int)type)); + } + }; + private: Type current_type; @@ -94,14 +137,12 @@ private: Vector2 graph_offset; - struct RenderModeEnums { - Shader::Mode mode = Shader::Mode::MODE_MAX; - const char *string; - }; - HashMap<String, int> modes; Set<StringName> flags; + Map<String, Varying> varyings; + List<Varying> varyings_list; + mutable SafeFlag dirty; void _queue_update(); @@ -116,7 +157,7 @@ private: } }; - Error _write_node(Type p_type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const; + Error _write_node(Type p_type, StringBuilder *global_code, StringBuilder *global_code_per_node, Map<Type, StringBuilder> *global_code_per_func, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const; void _input_type_changed(Type p_type, int p_id); bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const; @@ -151,6 +192,18 @@ public: void add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id); void set_node_position(Type p_type, int p_id, const Vector2 &p_position); + void add_varying(const String &p_name, VaryingMode p_mode, VaryingType p_type); + void remove_varying(const String &p_name); + bool has_varying(const String &p_name) const; + int get_varyings_count() const; + const Varying *get_varying_by_index(int p_idx) const; + + void set_varying_mode(const String &p_name, VaryingMode p_mode); + VaryingMode get_varying_mode(const String &p_name); + + void set_varying_type(const String &p_name, VaryingType p_type); + VaryingType get_varying_type(const String &p_name); + Vector2 get_node_position(Type p_type, int p_id) const; Ref<VisualShaderNode> get_node(Type p_type, int p_id) const; @@ -190,6 +243,8 @@ public: }; VARIANT_ENUM_CAST(VisualShader::Type) +VARIANT_ENUM_CAST(VisualShader::VaryingMode) +VARIANT_ENUM_CAST(VisualShader::VaryingType) /// /// /// @@ -328,14 +383,20 @@ protected: GDVIRTUAL1RC(int, _get_output_port_type, int) GDVIRTUAL1RC(String, _get_output_port_name, int) GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type) + GDVIRTUAL2RC(String, _get_func_code, Shader::Mode, VisualShader::Type) GDVIRTUAL1RC(String, _get_global_code, Shader::Mode) GDVIRTUAL0RC(bool, _is_highend) + GDVIRTUAL2RC(bool, _is_available, Shader::Mode, VisualShader::Type) + + bool _is_valid_code(const String &p_code) const; protected: void _set_input_port_default_value(int p_port, const Variant &p_value); + bool is_available(Shader::Mode p_mode, VisualShader::Type p_type) const; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; + virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; static void _bind_methods(); @@ -697,6 +758,103 @@ public: VisualShaderNodeGlobalExpression(); }; +class VisualShaderNodeVarying : public VisualShaderNode { + GDCLASS(VisualShaderNodeVarying, VisualShaderNode); + +public: + struct Varying { + String name; + VisualShader::VaryingMode mode; + VisualShader::VaryingType type; + bool assigned = false; + }; + +protected: + VisualShader::VaryingType varying_type = VisualShader::VARYING_TYPE_FLOAT; + String varying_name = "[None]"; + +public: // internal + static void add_varying(const String &p_name, VisualShader::VaryingMode p_mode, VisualShader::VaryingType p_type); + static void clear_varyings(); + static bool has_varying(const String &p_name); + + int get_varyings_count() const; + String get_varying_name_by_index(int p_idx) const; + VisualShader::VaryingMode get_varying_mode_by_name(const String &p_name) const; + VisualShader::VaryingMode get_varying_mode_by_index(int p_idx) const; + VisualShader::VaryingType get_varying_type_by_name(const String &p_name) const; + VisualShader::VaryingType get_varying_type_by_index(int p_idx) const; + PortType get_port_type_by_index(int p_idx) const; + +protected: + static void _bind_methods(); + +protected: + String get_type_str() const; + PortType get_port_type(VisualShader::VaryingType p_type, int p_port) const; + +public: + virtual String get_caption() const override = 0; + + virtual int get_input_port_count() const override = 0; + virtual PortType get_input_port_type(int p_port) const override = 0; + virtual String get_input_port_name(int p_port) const override = 0; + + virtual int get_output_port_count() const override = 0; + virtual PortType get_output_port_type(int p_port) const override = 0; + virtual String get_output_port_name(int p_port) const override = 0; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override = 0; + + void set_varying_name(String p_varying_name); + String get_varying_name() const; + + void set_varying_type(VisualShader::VaryingType p_varying_type); + VisualShader::VaryingType get_varying_type() const; + + VisualShaderNodeVarying(); +}; + +class VisualShaderNodeVaryingSetter : public VisualShaderNodeVarying { + GDCLASS(VisualShaderNodeVaryingSetter, VisualShaderNodeVarying); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeVaryingSetter(); +}; + +class VisualShaderNodeVaryingGetter : public VisualShaderNodeVarying { + GDCLASS(VisualShaderNodeVaryingGetter, VisualShaderNodeVarying); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + virtual bool has_output_port_preview(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeVaryingGetter(); +}; + extern String make_unique_id(VisualShader::Type p_type, int p_id, const String &p_name); #endif // VISUAL_SHADER_H diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index f2479199ee..7b4d7e66d4 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -2843,8 +2843,7 @@ String VisualShaderNodeColorFunc::generate_code(Shader::Mode p_mode, VisualShade code += " vec3 c = " + p_input_vars[0] + ";\n"; code += " float max1 = max(c.r, c.g);\n"; code += " float max2 = max(max1, c.b);\n"; - code += " float max3 = max(max1, max2);\n"; - code += " " + p_output_vars[0] + " = vec3(max3, max3, max3);\n"; + code += " " + p_output_vars[0] + " = vec3(max2, max2, max2);\n"; code += " }\n"; break; case FUNC_SEPIA: @@ -5697,7 +5696,7 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String code; - code += "// TRIPLANAR FUNCTION GLOBAL CODE\n"; + code += "// " + get_caption() + "\n"; code += " vec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n"; code += " vec4 samp = vec4(0.0);\n"; code += " samp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n"; @@ -5720,11 +5719,13 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader: String code; if (p_type == VisualShader::TYPE_VERTEX) { - code += " // TRIPLANAR FUNCTION VERTEX CODE\n"; + code += "// " + get_caption() + "\n"; + code += " {\n"; code += " triplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n"; code += " triplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n"; code += " triplanar_pos = VERTEX * triplanar_scale + triplanar_offset;\n"; code += " triplanar_pos *= vec3(1.0, -1.0, 1.0);\n"; + code += " }\n"; } return code; diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp index 1885211d57..398c33c452 100644 --- a/scene/resources/visual_shader_particle_nodes.cpp +++ b/scene/resources/visual_shader_particle_nodes.cpp @@ -1318,7 +1318,7 @@ String VisualShaderNodeParticleOutput::generate_code(Shader::Mode p_mode, Visual code += tab + "TRANSFORM = " + p_input_vars[5] + ";\n"; } } else { - if (!p_input_vars[0].is_empty()) { // active (begin) + if (!p_input_vars[0].is_empty()) { // Active (begin). code += tab + "ACTIVE = " + p_input_vars[0] + ";\n"; code += tab + "if(ACTIVE) {\n"; tab += " "; @@ -1381,7 +1381,7 @@ String VisualShaderNodeParticleOutput::generate_code(Shader::Mode p_mode, Visual code += tab + "TRANSFORM " + op + " mat4(vec4(" + p_input_vars[scale] + ", 0, 0, 0), vec4(0, " + p_input_vars[scale] + ", 0, 0), vec4(0, 0, " + p_input_vars[scale] + ", 0), vec4(0, 0, 0, 1));\n"; } } - if (!p_input_vars[0].is_empty()) { // active (end) + if (!p_input_vars[0].is_empty()) { // Active (end). code += " }\n"; } } diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index 91f9a026d3..4a277c3d84 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -31,8 +31,8 @@ #ifndef WORLD_2D_H #define WORLD_2D_H -#include "core/config/project_settings.h" #include "core/io/resource.h" +#include "scene/resources/world_2d.h" #include "servers/physics_server_2d.h" class VisibleOnScreenNotifier2D; diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp index c012ab6177..0088236112 100644 --- a/scene/resources/world_3d.cpp +++ b/scene/resources/world_3d.cpp @@ -30,7 +30,7 @@ #include "world_3d.h" -#include "core/math/camera_matrix.h" +#include "core/config/project_settings.h" #include "core/math/octree.h" #include "scene/3d/camera_3d.h" #include "scene/3d/visible_on_screen_notifier_3d.h" |