diff options
125 files changed, 2625 insertions, 1965 deletions
diff --git a/.travis.yml b/.travis.yml index 9376fbcc06..2639cf9661 100644 --- a/.travis.yml +++ b/.travis.yml @@ -100,15 +100,15 @@ matrix: packages: - *linux_deps -# - name: Javascript export template (release, emscripten latest) -# stage: build -# env: PLATFORM=javascript TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-emcc-latest EXTRA_ARGS="use_closure_compiler=yes" -# os: linux -# compiler: clang -# addons: -# apt: -# packages: -# - *linux_deps + - name: JavaScript export template (release, emscripten latest) + stage: build + env: PLATFORM=javascript TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-emcc-latest EXTRA_ARGS="use_closure_compiler=yes" + os: linux + compiler: clang + addons: + apt: + packages: + - *linux_deps before_install: - eval "${MATRIX_EVAL}" diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 267391c4d6..cb82dc7f8f 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -454,7 +454,7 @@ Dictionary _OS::get_datetime_from_unix_time(int64_t unix_time_val) const { } else { dayno = (unix_time_val - SECS_DAY + 1) / SECS_DAY; dayclock = unix_time_val - dayno * SECS_DAY; - date.weekday = static_cast<OS::Weekday>((dayno - 3) % 7 + 7); + date.weekday = static_cast<OS::Weekday>(((dayno % 7) + 11) % 7); do { year--; dayno += YEARSIZE(year); diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index 62f600c5e5..9d55e1312e 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -373,6 +373,7 @@ struct RemoteDebugger::VisualProfiler { struct RemoteDebugger::PerformanceProfiler { Object *performance = nullptr; int last_perf_time = 0; + uint64_t last_monitor_modification_time = 0; void toggle(bool p_enable, const Array &p_opts) {} void add(const Array &p_data) {} @@ -386,12 +387,31 @@ struct RemoteDebugger::PerformanceProfiler { return; } last_perf_time = pt; + + Array custom_monitor_names = performance->call("get_custom_monitor_names"); + + uint64_t monitor_modification_time = performance->call("get_monitor_modification_time"); + if (monitor_modification_time > last_monitor_modification_time) { + last_monitor_modification_time = monitor_modification_time; + EngineDebugger::get_singleton()->send_message("performance:profile_names", custom_monitor_names); + } + int max = performance->get("MONITOR_MAX"); Array arr; - arr.resize(max); + arr.resize(max + custom_monitor_names.size()); for (int i = 0; i < max; i++) { arr[i] = performance->call("get_monitor", i); } + + for (int i = 0; i < custom_monitor_names.size(); i++) { + Variant monitor_value = performance->call("get_custom_monitor", custom_monitor_names[i]); + if (!monitor_value.is_num()) { + ERR_PRINT("Value of custom monitor '" + String(custom_monitor_names[i]) + "' is not a number"); + arr[i + max] = Variant(); + } + arr[i + max] = monitor_value; + } + EngineDebugger::get_singleton()->send_message("performance:profile_frame", arr); } diff --git a/core/image.cpp b/core/image.cpp index 45f10625a9..e2b184fcde 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -30,6 +30,7 @@ #include "image.h" +#include "core/error_macros.h" #include "core/hash_map.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" @@ -2629,6 +2630,7 @@ void Image::fill(const Color &c) { ImageMemLoadFunc Image::_png_mem_loader_func = nullptr; ImageMemLoadFunc Image::_jpg_mem_loader_func = nullptr; ImageMemLoadFunc Image::_webp_mem_loader_func = nullptr; +ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr; void (*Image::_image_compress_bc_func)(Image *, float, Image::UsedChannels) = nullptr; void (*Image::_image_compress_bptc_func)(Image *, float, Image::UsedChannels) = nullptr; @@ -3058,6 +3060,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("load_png_from_buffer", "buffer"), &Image::load_png_from_buffer); ClassDB::bind_method(D_METHOD("load_jpg_from_buffer", "buffer"), &Image::load_jpg_from_buffer); ClassDB::bind_method(D_METHOD("load_webp_from_buffer", "buffer"), &Image::load_webp_from_buffer); + ClassDB::bind_method(D_METHOD("load_tga_from_buffer", "buffer"), &Image::load_tga_from_buffer); ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data"); @@ -3389,6 +3392,11 @@ Error Image::load_webp_from_buffer(const Vector<uint8_t> &p_array) { return _load_from_buffer(p_array, _webp_mem_loader_func); } +Error Image::load_tga_from_buffer(const Vector<uint8_t> &p_array) { + ERR_FAIL_NULL_V_MSG(_tga_mem_loader_func, ERR_UNAVAILABLE, "TGA module was not installed."); + return _load_from_buffer(p_array, _tga_mem_loader_func); +} + void Image::convert_rg_to_ra_rgba8() { ERR_FAIL_COND(format != FORMAT_RGBA8); ERR_FAIL_COND(!data.size()); diff --git a/core/image.h b/core/image.h index 53c203998e..711bf5721c 100644 --- a/core/image.h +++ b/core/image.h @@ -135,6 +135,7 @@ public: static ImageMemLoadFunc _png_mem_loader_func; static ImageMemLoadFunc _jpg_mem_loader_func; static ImageMemLoadFunc _webp_mem_loader_func; + static ImageMemLoadFunc _tga_mem_loader_func; static void (*_image_compress_bc_func)(Image *, float, UsedChannels p_channels); static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, UsedChannels p_channels); @@ -360,6 +361,7 @@ public: Error load_png_from_buffer(const Vector<uint8_t> &p_array); Error load_jpg_from_buffer(const Vector<uint8_t> &p_array); Error load_webp_from_buffer(const Vector<uint8_t> &p_array); + Error load_tga_from_buffer(const Vector<uint8_t> &p_array); void convert_rg_to_ra_rgba8(); void convert_ra_rgba8_to_rg(); diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 6421606ca2..13a49feb6b 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -1064,7 +1064,7 @@ Error Expression::_get_token(Token &r_token) { if (is_float) { r_token.value = num.to_double(); } else { - r_token.value = num.to_int64(); + r_token.value = num.to_int(); } return OK; diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp index dc68c2a9f9..434f6fa300 100644 --- a/core/os/main_loop.cpp +++ b/core/os/main_loop.cpp @@ -48,8 +48,10 @@ void MainLoop::_bind_methods() { BIND_CONSTANT(NOTIFICATION_WM_ABOUT); BIND_CONSTANT(NOTIFICATION_CRASH); BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE); - BIND_CONSTANT(NOTIFICATION_APP_RESUMED); - BIND_CONSTANT(NOTIFICATION_APP_PAUSED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_RESUMED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_PAUSED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_IN); + BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT); ADD_SIGNAL(MethodInfo("on_request_permissions_result", PropertyInfo(Variant::STRING, "permission"), PropertyInfo(Variant::BOOL, "granted"))); }; diff --git a/core/os/main_loop.h b/core/os/main_loop.h index 90790a45a1..2c34cf193c 100644 --- a/core/os/main_loop.h +++ b/core/os/main_loop.h @@ -52,8 +52,10 @@ public: NOTIFICATION_WM_ABOUT = 2011, NOTIFICATION_CRASH = 2012, NOTIFICATION_OS_IME_UPDATE = 2013, - NOTIFICATION_APP_RESUMED = 2014, - NOTIFICATION_APP_PAUSED = 2015, + NOTIFICATION_APPLICATION_RESUMED = 2014, + NOTIFICATION_APPLICATION_PAUSED = 2015, + NOTIFICATION_APPLICATION_FOCUS_IN = 2016, + NOTIFICATION_APPLICATION_FOCUS_OUT = 2017, }; virtual void init(); diff --git a/core/os/os.cpp b/core/os/os.cpp index c842be333c..231069fcfb 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -41,6 +41,7 @@ #include <stdarg.h> OS *OS::singleton = nullptr; +uint64_t OS::target_ticks = 0; OS *OS::get_singleton() { return singleton; @@ -468,6 +469,41 @@ void OS::close_midi_inputs() { } } +void OS::add_frame_delay(bool p_can_draw) { + const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay(); + if (frame_delay) { + // Add fixed frame delay to decrease CPU/GPU usage. This doesn't take + // the actual frame time into account. + // Due to the high fluctuation of the actual sleep duration, it's not recommended + // to use this as a FPS limiter. + delay_usec(frame_delay * 1000); + } + + // Add a dynamic frame delay to decrease CPU/GPU usage. This takes the + // previous frame time into account for a smoother result. + uint64_t dynamic_delay = 0; + if (is_in_low_processor_usage_mode() || !p_can_draw) { + dynamic_delay = get_low_processor_usage_mode_sleep_usec(); + } + const int target_fps = Engine::get_singleton()->get_target_fps(); + if (target_fps > 0 && !Engine::get_singleton()->is_editor_hint()) { + // Override the low processor usage mode sleep delay if the target FPS is lower. + dynamic_delay = MAX(dynamic_delay, (uint64_t)(1000000 / target_fps)); + } + + if (dynamic_delay > 0) { + target_ticks += dynamic_delay; + uint64_t current_ticks = get_ticks_usec(); + + if (current_ticks < target_ticks) { + delay_usec(target_ticks - current_ticks); + } + + current_ticks = get_ticks_usec(); + target_ticks = MIN(MAX(target_ticks, current_ticks - dynamic_delay), current_ticks + dynamic_delay); + } +} + OS::OS() { void *volatile stack_bottom; diff --git a/core/os/os.h b/core/os/os.h index 04e10518dc..f21c0d4df7 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -43,6 +43,7 @@ class OS { static OS *singleton; + static uint64_t target_ticks; String _execpath; List<String> _cmdline; bool _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0. @@ -212,6 +213,8 @@ public: virtual double get_unix_time() const; virtual void delay_usec(uint32_t p_usec) const = 0; + virtual void add_frame_delay(bool p_can_draw); + virtual uint64_t get_ticks_usec() const = 0; uint32_t get_ticks_msec() const; uint64_t get_splash_tick_msec() const; diff --git a/core/ustring.cpp b/core/ustring.cpp index 444338d5ae..be242140a2 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -1618,49 +1618,7 @@ String::String(const StrRange &p_range) { copy_from(p_range.c_str, p_range.len); } -int String::hex_to_int(bool p_with_prefix) const { - if (p_with_prefix && length() < 3) { - return 0; - } - - const CharType *s = ptr(); - - int sign = s[0] == '-' ? -1 : 1; - - if (sign < 0) { - s++; - } - - if (p_with_prefix) { - if (s[0] != '0' || s[1] != 'x') { - return 0; - } - s += 2; - } - - int hex = 0; - - while (*s) { - CharType c = LOWERCASE(*s); - int n; - if (c >= '0' && c <= '9') { - n = c - '0'; - } else if (c >= 'a' && c <= 'f') { - n = (c - 'a') + 10; - } else { - return 0; - } - - ERR_FAIL_COND_V_MSG(hex > INT32_MAX / 16, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as integer, provided value is " + (sign == 1 ? "too big." : "too small.")); - hex *= 16; - hex += n; - s++; - } - - return hex * sign; -} - -int64_t String::hex_to_int64(bool p_with_prefix) const { +int64_t String::hex_to_int(bool p_with_prefix) const { if (p_with_prefix && length() < 3) { return 0; } @@ -1702,7 +1660,7 @@ int64_t String::hex_to_int64(bool p_with_prefix) const { return hex * sign; } -int64_t String::bin_to_int64(bool p_with_prefix) const { +int64_t String::bin_to_int(bool p_with_prefix) const { if (p_with_prefix && length() < 3) { return 0; } @@ -1742,32 +1700,7 @@ int64_t String::bin_to_int64(bool p_with_prefix) const { return binary * sign; } -int String::to_int() const { - if (length() == 0) { - return 0; - } - - int to = (find(".") >= 0) ? find(".") : length(); - - int integer = 0; - int sign = 1; - - for (int i = 0; i < to; i++) { - CharType c = operator[](i); - if (c >= '0' && c <= '9') { - ERR_FAIL_COND_V_MSG(integer > INT32_MAX / 10, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as integer, provided value is " + (sign == 1 ? "too big." : "too small.")); - integer *= 10; - integer += c - '0'; - - } else if (integer == 0 && c == '-') { - sign = -sign; - } - } - - return integer * sign; -} - -int64_t String::to_int64() const { +int64_t String::to_int() const { if (length() == 0) { return 0; } @@ -1780,7 +1713,7 @@ int64_t String::to_int64() const { for (int i = 0; i < to; i++) { CharType c = operator[](i); if (c >= '0' && c <= '9') { - ERR_FAIL_COND_V_MSG(integer > INT64_MAX / 10, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small.")); + ERR_FAIL_COND_V_MSG(integer > INT64_MAX / 10, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as an integer, provided value is " + (sign == 1 ? "too big." : "too small.")); integer *= 10; integer += c - '0'; @@ -1792,7 +1725,7 @@ int64_t String::to_int64() const { return integer * sign; } -int String::to_int(const char *p_str, int p_len) { +int64_t String::to_int(const char *p_str, int p_len) { int to = 0; if (p_len >= 0) { to = p_len; @@ -1802,13 +1735,13 @@ int String::to_int(const char *p_str, int p_len) { } } - int integer = 0; - int sign = 1; + int64_t integer = 0; + int64_t sign = 1; for (int i = 0; i < to; i++) { char c = p_str[i]; if (c >= '0' && c <= '9') { - ERR_FAIL_COND_V_MSG(integer > INT32_MAX / 10, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + String(p_str).substr(0, to) + " as integer, provided value is " + (sign == 1 ? "too big." : "too small.")); + ERR_FAIL_COND_V_MSG(integer > INT64_MAX / 10, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + String(p_str).substr(0, to) + " as an integer, provided value is " + (sign == 1 ? "too big." : "too small.")); integer *= 10; integer += c - '0'; @@ -3838,7 +3771,7 @@ bool String::is_valid_ip_address() const { continue; } if (n.is_valid_hex_number(false)) { - int nint = n.hex_to_int(false); + int64_t nint = n.hex_to_int(false); if (nint < 0 || nint > 0xffff) { return false; } diff --git a/core/ustring.h b/core/ustring.h index 5b13a1c704..a86849b932 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -245,13 +245,11 @@ public: bool is_numeric() const; double to_double() const; float to_float() const; - int hex_to_int(bool p_with_prefix = true) const; - int to_int() const; - int64_t hex_to_int64(bool p_with_prefix = true) const; - int64_t bin_to_int64(bool p_with_prefix = true) const; - int64_t to_int64() const; - static int to_int(const char *p_str, int p_len = -1); + int64_t hex_to_int(bool p_with_prefix = true) const; + int64_t bin_to_int(bool p_with_prefix = true) const; + int64_t to_int() const; + static int64_t to_int(const char *p_str, int p_len = -1); static double to_double(const char *p_str); static double to_double(const CharType *p_str, const CharType **r_end = nullptr); static int64_t to_int(const CharType *p_str, int p_len = -1, bool p_clamp = false); diff --git a/core/variant.cpp b/core/variant.cpp index 21aaa0fe9e..f6b7e2821a 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1409,7 +1409,7 @@ Variant::operator int64_t() const { case FLOAT: return _data._float; case STRING: - return operator String().to_int64(); + return operator String().to_int(); default: { return 0; } diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml index 99b566e74f..6b1864b679 100644 --- a/doc/classes/AcceptDialog.xml +++ b/doc/classes/AcceptDialog.xml @@ -67,6 +67,7 @@ <member name="dialog_text" type="String" setter="set_text" getter="get_text" default=""""> The text displayed by the dialog. </member> + <member name="exclusive" type="bool" setter="set_exclusive" getter="is_exclusive" override="true" default="true" /> <member name="title" type="String" setter="set_title" getter="get_title" override="true" default=""Alert!"" /> <member name="transient" type="bool" setter="set_transient" getter="is_transient" override="true" default="true" /> <member name="visible" type="bool" setter="set_visible" getter="is_visible" override="true" default="false" /> diff --git a/doc/classes/CameraEffects.xml b/doc/classes/CameraEffects.xml index ea9ab85b80..7a874d31db 100644 --- a/doc/classes/CameraEffects.xml +++ b/doc/classes/CameraEffects.xml @@ -34,9 +34,9 @@ The length of the transition between the near blur and no-blur area. </member> <member name="override_exposure" type="float" setter="set_override_exposure" getter="get_override_exposure" default="1.0"> - The exposure override value to use. Higher values will result in a brighter scene. Only effective if [member override_exposure_enable] is [code]true[/code]. + The exposure override value to use. Higher values will result in a brighter scene. Only effective if [member override_exposure_enabled] is [code]true[/code]. </member> - <member name="override_exposure_enable" type="bool" setter="set_override_exposure_enabled" getter="is_override_exposure_enabled" default="false"> + <member name="override_exposure_enabled" type="bool" setter="set_override_exposure_enabled" getter="is_override_exposure_enabled" default="false"> If [code]true[/code], overrides the manual or automatic exposure defined in the [Environment] with the value in [member override_exposure]. </member> </members> diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index f8306cbd72..1fb1de2c12 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -44,9 +44,9 @@ </return> <argument index="0" name="mode" type="int" enum="DisplayServer.WindowMode"> </argument> - <argument index="1" name="rect" type="int"> + <argument index="1" name="flags" type="int"> </argument> - <argument index="2" name="arg2" type="Rect2i" default="Rect2i( 0, 0, 0, 0 )"> + <argument index="2" name="rect" type="Rect2i" default="Rect2i( 0, 0, 0, 0 )"> </argument> <description> </description> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 3642d92771..bbab0bf8cf 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -24,7 +24,7 @@ Returns [code]true[/code] if the glow level [code]idx[/code] is specified, [code]false[/code] otherwise. </description> </method> - <method name="set_glow_level"> + <method name="set_glow_level_enabled"> <return type="void"> </return> <argument index="0" name="idx" type="int"> @@ -46,7 +46,7 @@ <member name="adjustment_contrast" type="float" setter="set_adjustment_contrast" getter="get_adjustment_contrast" default="1.0"> The global contrast value of the rendered scene (default value is 1). Effective only if [code]adjustment_enabled[/code] is [code]true[/code]. </member> - <member name="adjustment_enabled" type="bool" setter="set_adjustment_enable" getter="is_adjustment_enabled" default="false"> + <member name="adjustment_enabled" type="bool" setter="set_adjustment_enabled" getter="is_adjustment_enabled" default="false"> If [code]true[/code], enables the [code]adjustment_*[/code] properties provided by this resource. If [code]false[/code], modifications to the [code]adjustment_*[/code] properties will have no effect on the rendered scene. </member> <member name="adjustment_saturation" type="float" setter="set_adjustment_saturation" getter="get_adjustment_saturation" default="1.0"> @@ -65,7 +65,7 @@ </member> <member name="ambient_light_source" type="int" setter="set_ambient_source" getter="get_ambient_source" enum="Environment.AmbientSource" default="0"> </member> - <member name="auto_exposure_enabled" type="bool" setter="set_tonemap_auto_exposure" getter="get_tonemap_auto_exposure" default="false"> + <member name="auto_exposure_enabled" type="bool" setter="set_tonemap_auto_exposure_enabled" getter="is_tonemap_auto_exposure_enabled" default="false"> If [code]true[/code], enables the tonemapping auto exposure mode of the scene renderer. If [code]true[/code], the renderer will automatically determine the exposure setting to adapt to the scene's illumination and the observed light. </member> <member name="auto_exposure_max_luma" type="float" setter="set_tonemap_auto_exposure_max" getter="get_tonemap_auto_exposure_max" default="8.0"> @@ -158,25 +158,25 @@ <member name="glow_intensity" type="float" setter="set_glow_intensity" getter="get_glow_intensity" default="0.8"> The glow intensity. When using the GLES2 renderer, this should be increased to 1.5 to compensate for the lack of HDR rendering. </member> - <member name="glow_levels/1" type="bool" setter="set_glow_level" getter="is_glow_level_enabled" default="false"> + <member name="glow_levels/1" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false"> If [code]true[/code], the 1st level of glow is enabled. This is the most "local" level (least blurry). </member> - <member name="glow_levels/2" type="bool" setter="set_glow_level" getter="is_glow_level_enabled" default="false"> + <member name="glow_levels/2" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false"> If [code]true[/code], the 2th level of glow is enabled. </member> - <member name="glow_levels/3" type="bool" setter="set_glow_level" getter="is_glow_level_enabled" default="true"> + <member name="glow_levels/3" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="true"> If [code]true[/code], the 3th level of glow is enabled. </member> - <member name="glow_levels/4" type="bool" setter="set_glow_level" getter="is_glow_level_enabled" default="false"> + <member name="glow_levels/4" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false"> If [code]true[/code], the 4th level of glow is enabled. </member> - <member name="glow_levels/5" type="bool" setter="set_glow_level" getter="is_glow_level_enabled" default="true"> + <member name="glow_levels/5" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="true"> If [code]true[/code], the 5th level of glow is enabled. </member> - <member name="glow_levels/6" type="bool" setter="set_glow_level" getter="is_glow_level_enabled" default="false"> + <member name="glow_levels/6" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false"> If [code]true[/code], the 6th level of glow is enabled. </member> - <member name="glow_levels/7" type="bool" setter="set_glow_level" getter="is_glow_level_enabled" default="false"> + <member name="glow_levels/7" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false"> If [code]true[/code], the 7th level of glow is enabled. This is the most "global" level (blurriest). </member> <member name="glow_mix" type="float" setter="set_glow_mix" getter="get_glow_mix" default="0.05"> @@ -186,6 +186,30 @@ </member> <member name="reflected_light_source" type="int" setter="set_reflection_source" getter="get_reflection_source" enum="Environment.ReflectionSource" default="0"> </member> + <member name="sdfgi_cascade0_distance" type="float" setter="set_sdfgi_cascade0_distance" getter="get_sdfgi_cascade0_distance" default="12.8"> + </member> + <member name="sdfgi_cascades" type="int" setter="set_sdfgi_cascades" getter="get_sdfgi_cascades" enum="Environment.SDFGICascades" default="1"> + </member> + <member name="sdfgi_enabled" type="bool" setter="set_sdfgi_enabled" getter="is_sdfgi_enabled" default="false"> + </member> + <member name="sdfgi_energy" type="float" setter="set_sdfgi_energy" getter="get_sdfgi_energy" default="1.0"> + </member> + <member name="sdfgi_max_distance" type="float" setter="set_sdfgi_max_distance" getter="get_sdfgi_max_distance" default="819.2"> + </member> + <member name="sdfgi_min_cell_size" type="float" setter="set_sdfgi_min_cell_size" getter="get_sdfgi_min_cell_size" default="0.2"> + </member> + <member name="sdfgi_normal_bias" type="float" setter="set_sdfgi_normal_bias" getter="get_sdfgi_normal_bias" default="1.1"> + </member> + <member name="sdfgi_probe_bias" type="float" setter="set_sdfgi_probe_bias" getter="get_sdfgi_probe_bias" default="1.1"> + </member> + <member name="sdfgi_read_sky_light" type="bool" setter="set_sdfgi_read_sky_light" getter="is_sdfgi_reading_sky_light" default="false"> + </member> + <member name="sdfgi_use_multi_bounce" type="bool" setter="set_sdfgi_use_multi_bounce" getter="is_sdfgi_using_multi_bounce" default="false"> + </member> + <member name="sdfgi_use_occlusion" type="bool" setter="set_sdfgi_use_occlusion" getter="is_sdfgi_using_occlusion" default="false"> + </member> + <member name="sdfgi_y_scale" type="int" setter="set_sdfgi_y_scale" getter="get_sdfgi_y_scale" enum="Environment.SDFGIYScale" default="0"> + </member> <member name="sky" type="Sky" setter="set_sky" getter="get_sky"> The [Sky] resource used for this [Environment]. </member> @@ -285,6 +309,18 @@ <constant name="REFLECTION_SOURCE_SKY" value="2" enum="ReflectionSource"> Use the [Sky] for reflections regardless of what the background is. </constant> + <constant name="TONE_MAPPER_LINEAR" value="0" enum="ToneMapper"> + Linear tonemapper operator. Reads the linear data and passes it on unmodified. + </constant> + <constant name="TONE_MAPPER_REINHARDT" value="1" enum="ToneMapper"> + Reinhardt tonemapper operator. Performs a variation on rendered pixels' colors by this formula: [code]color = color / (1 + color)[/code]. + </constant> + <constant name="TONE_MAPPER_FILMIC" value="2" enum="ToneMapper"> + Filmic tonemapper operator. + </constant> + <constant name="TONE_MAPPER_ACES" value="3" enum="ToneMapper"> + Academy Color Encoding System tonemapper operator. + </constant> <constant name="GLOW_BLEND_MODE_ADDITIVE" value="0" enum="GlowBlendMode"> Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources. </constant> @@ -300,18 +336,6 @@ <constant name="GLOW_BLEND_MODE_MIX" value="4" enum="GlowBlendMode"> Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect. </constant> - <constant name="TONE_MAPPER_LINEAR" value="0" enum="ToneMapper"> - Linear tonemapper operator. Reads the linear data and passes it on unmodified. - </constant> - <constant name="TONE_MAPPER_REINHARDT" value="1" enum="ToneMapper"> - Reinhardt tonemapper operator. Performs a variation on rendered pixels' colors by this formula: [code]color = color / (1 + color)[/code]. - </constant> - <constant name="TONE_MAPPER_FILMIC" value="2" enum="ToneMapper"> - Filmic tonemapper operator. - </constant> - <constant name="TONE_MAPPER_ACES" value="3" enum="ToneMapper"> - Academy Color Encoding System tonemapper operator. - </constant> <constant name="SSAO_BLUR_DISABLED" value="0" enum="SSAOBlur"> No blur for the screen-space ambient occlusion effect (fastest). </constant> @@ -324,5 +348,17 @@ <constant name="SSAO_BLUR_3x3" value="3" enum="SSAOBlur"> 3×3 blur for the screen-space ambient occlusion effect. Increases the radius of the blur for a smoother look, but can result in checkerboard-like artifacts. </constant> + <constant name="SDFGI_CASCADES_4" value="0" enum="SDFGICascades"> + </constant> + <constant name="SDFGI_CASCADES_6" value="1" enum="SDFGICascades"> + </constant> + <constant name="SDFGI_CASCADES_8" value="2" enum="SDFGICascades"> + </constant> + <constant name="SDFGI_Y_SCALE_DISABLED" value="0" enum="SDFGIYScale"> + </constant> + <constant name="SDFGI_Y_SCALE_75_PERCENT" value="1" enum="SDFGIYScale"> + </constant> + <constant name="SDFGI_Y_SCALE_50_PERCENT" value="2" enum="SDFGIYScale"> + </constant> </constants> </class> diff --git a/doc/classes/FileSystemDock.xml b/doc/classes/FileSystemDock.xml index fdf29f89b2..c553f90e37 100644 --- a/doc/classes/FileSystemDock.xml +++ b/doc/classes/FileSystemDock.xml @@ -10,11 +10,11 @@ <method name="can_drop_data_fw" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="arg0" type="Vector2"> + <argument index="0" name="position" type="Vector2"> </argument> - <argument index="1" name="arg1" type="Variant"> + <argument index="1" name="data" type="Variant"> </argument> - <argument index="2" name="arg2" type="Control"> + <argument index="2" name="from" type="Control"> </argument> <description> </description> @@ -22,11 +22,11 @@ <method name="drop_data_fw"> <return type="void"> </return> - <argument index="0" name="arg0" type="Vector2"> + <argument index="0" name="position" type="Vector2"> </argument> - <argument index="1" name="arg1" type="Variant"> + <argument index="1" name="data" type="Variant"> </argument> - <argument index="2" name="arg2" type="Control"> + <argument index="2" name="from" type="Control"> </argument> <description> </description> @@ -34,9 +34,9 @@ <method name="get_drag_data_fw"> <return type="Variant"> </return> - <argument index="0" name="arg0" type="Vector2"> + <argument index="0" name="position" type="Vector2"> </argument> - <argument index="1" name="arg1" type="Control"> + <argument index="1" name="from" type="Control"> </argument> <description> </description> @@ -44,7 +44,7 @@ <method name="navigate_to_path"> <return type="void"> </return> - <argument index="0" name="arg0" type="String"> + <argument index="0" name="path" type="String"> </argument> <description> </description> diff --git a/doc/classes/GIProbe.xml b/doc/classes/GIProbe.xml index 23dd562653..8885f360a3 100644 --- a/doc/classes/GIProbe.xml +++ b/doc/classes/GIProbe.xml @@ -19,7 +19,7 @@ <argument index="1" name="create_visual_debug" type="bool" default="false"> </argument> <description> - Bakes the effect from all [GeometryInstance3D]s marked with [constant GeometryInstance3D.GI_MODE_BAKED] and [Light3D]s marked with either [constant Light3D.BAKE_INDIRECT] or [constant Light3D.BAKE_ALL]. If [code]create_visual_debug[/code] is [code]true[/code], after baking the light, this will generate a [MultiMesh] that has a cube representing each solid cell with each cube colored to the cell's albedo color. This can be used to visualize the [GIProbe]'s data and debug any issues that may be occurring. + Bakes the effect from all [GeometryInstance3D]s marked with [constant GeometryInstance3D.GI_MODE_BAKED] and [Light3D]s marked with either [constant Light3D.BAKE_DYNAMIC] or [constant Light3D.BAKE_STATIC]. If [code]create_visual_debug[/code] is [code]true[/code], after baking the light, this will generate a [MultiMesh] that has a cube representing each solid cell with each cube colored to the cell's albedo color. This can be used to visualize the [GIProbe]'s data and debug any issues that may be occurring. </description> </method> <method name="debug_bake"> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index d29fcfd96f..5aa5de1dae 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -364,6 +364,15 @@ Loads an image from the binary contents of a PNG file. </description> </method> + <method name="load_tga_from_buffer"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="buffer" type="PackedByteArray"> + </argument> + <description> + Loads an image from the binary contents of a TGA file. + </description> + </method> <method name="load_webp_from_buffer"> <return type="int" enum="Error"> </return> diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index dda6faa80a..6979efa569 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -148,12 +148,9 @@ Light is ignored when baking. [b]Note:[/b] Hiding a light does [i]not[/i] affect baking. </constant> - <constant name="BAKE_INDIRECT" value="1" enum="BakeMode"> - Only indirect lighting will be baked (default). + <constant name="BAKE_DYNAMIC" value="1" enum="BakeMode"> </constant> - <constant name="BAKE_ALL" value="2" enum="BakeMode"> - Both direct and indirect light will be baked. - [b]Note:[/b] You should hide the light if you don't want it to appear twice (dynamic and baked). + <constant name="BAKE_STATIC" value="2" enum="BakeMode"> </constant> </constants> </class> diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml index 7bb478fce2..55ae54d12b 100644 --- a/doc/classes/MainLoop.xml +++ b/doc/classes/MainLoop.xml @@ -142,13 +142,21 @@ Notification received from the OS when an update of the Input Method Engine occurs (e.g. change of IME cursor position or composition string). Specific to the macOS platform. </constant> - <constant name="NOTIFICATION_APP_RESUMED" value="2014"> - Notification received from the OS when the app is resumed. + <constant name="NOTIFICATION_APPLICATION_RESUMED" value="2014"> + Notification received from the OS when the application is resumed. Specific to the Android platform. </constant> - <constant name="NOTIFICATION_APP_PAUSED" value="2015"> - Notification received from the OS when the app is paused. + <constant name="NOTIFICATION_APPLICATION_PAUSED" value="2015"> + Notification received from the OS when the application is paused. Specific to the Android platform. </constant> + <constant name="NOTIFICATION_APPLICATION_FOCUS_IN" value="2016"> + Notification received from the OS when the application is focused, i.e. when changing the focus from the OS desktop or a thirdparty application to any open window of the Godot instance. + Implemented on desktop platforms. + </constant> + <constant name="NOTIFICATION_APPLICATION_FOCUS_OUT" value="2017"> + Notification received from the OS when the application is defocused, i.e. when changing the focus from any open window of the Godot instance to the OS desktop or a thirdparty application. + Implemented on desktop platforms. + </constant> </constants> </class> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 9617ee0437..e921cbd58a 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -926,13 +926,11 @@ Notification received from the OS when the mouse leaves the game window. Implemented on desktop and web platforms. </constant> - <constant name="NOTIFICATION_WM_FOCUS_IN" value="1004"> - Notification received from the OS when the game window is focused. - Implemented on all platforms. + <constant name="NOTIFICATION_WM_WINDOW_FOCUS_IN" value="1004"> + Notification received from the OS when the node's parent [Window] is focused. This may be a change of focus between two windows of the same engine instance, or from the OS desktop or a third-party application to a window of the game (in which case [constant NOTIFICATION_APPLICATION_FOCUS_IN] is also emitted). </constant> - <constant name="NOTIFICATION_WM_FOCUS_OUT" value="1005"> - Notification received from the OS when the game window is unfocused. - Implemented on all platforms. + <constant name="NOTIFICATION_WM_WINDOW_FOCUS_OUT" value="1005"> + Notification received from the OS when the node's parent [Window] is defocused. This may be a change of focus between two windows of the same engine instance, or from a window of the game to the OS desktop or a third-party application (in which case [constant NOTIFICATION_APPLICATION_FOCUS_OUT] is also emitted). </constant> <constant name="NOTIFICATION_WM_CLOSE_REQUEST" value="1006"> Notification received from the OS when a close request is sent (e.g. closing the window with a "Close" button or [kbd]Alt + F4[/kbd]). @@ -963,14 +961,22 @@ Notification received from the OS when an update of the Input Method Engine occurs (e.g. change of IME cursor position or composition string). Specific to the macOS platform. </constant> - <constant name="NOTIFICATION_APP_RESUMED" value="2014"> - Notification received from the OS when the app is resumed. + <constant name="NOTIFICATION_APPLICATION_RESUMED" value="2014"> + Notification received from the OS when the application is resumed. Specific to the Android platform. </constant> - <constant name="NOTIFICATION_APP_PAUSED" value="2015"> - Notification received from the OS when the app is paused. + <constant name="NOTIFICATION_APPLICATION_PAUSED" value="2015"> + Notification received from the OS when the application is paused. Specific to the Android platform. </constant> + <constant name="NOTIFICATION_APPLICATION_FOCUS_IN" value="2016"> + Notification received from the OS when the application is focused, i.e. when changing the focus from the OS desktop or a thirdparty application to any open window of the Godot instance. + Implemented on desktop platforms. + </constant> + <constant name="NOTIFICATION_APPLICATION_FOCUS_OUT" value="2017"> + Notification received from the OS when the application is defocused, i.e. when changing the focus from any open window of the Godot instance to the OS desktop or a thirdparty application. + Implemented on desktop platforms. + </constant> <constant name="PAUSE_MODE_INHERIT" value="0" enum="PauseMode"> Inherits pause mode from the node's parent. For the root node, it is equivalent to [constant PAUSE_MODE_STOP]. Default. </constant> diff --git a/doc/classes/Performance.xml b/doc/classes/Performance.xml index 2a0c153267..0a9079ce71 100644 --- a/doc/classes/Performance.xml +++ b/doc/classes/Performance.xml @@ -5,12 +5,55 @@ </brief_description> <description> This class provides access to a number of different monitors related to performance, such as memory usage, draw calls, and FPS. These are the same as the values displayed in the [b]Monitor[/b] tab in the editor's [b]Debugger[/b] panel. By using the [method get_monitor] method of this class, you can access this data from your code. + You can add custom monitors using the [method add_custom_monitor] method. Custom monitors are available in [b]Monitor[/b] tab in the editor's [b]Debugger[/b] panel together with built-in monitors. [b]Note:[/b] A few of these monitors are only available in debug mode and will always return 0 when used in a release build. [b]Note:[/b] Many of these monitors are not updated in real-time, so there may be a short delay between changes. + [b]Note:[/b] Custom monitors do not support negative values. Negative values are clamped to 0. </description> <tutorials> </tutorials> <methods> + <method name="add_custom_monitor"> + <return type="void"> + </return> + <argument index="0" name="id" type="StringName"> + </argument> + <argument index="1" name="callable" type="Callable"> + </argument> + <argument index="2" name="arguments" type="Array" default="[ ]"> + </argument> + <description> + Adds a custom monitor with name same as id. You can specify the category of monitor using '/' in id. If there are more than one '/' then default category is used. Default category is "Custom". + [codeblock] + Performance.add_custom_monitor("MyCategory/MyMonitor", some_callable) # Adds monitor with name "MyName" to category "MyCategory" + Performance.add_custom_monitor("MyMonitor", some_callable) # Adds monitor with name "MyName" to category "Custom" + # Note: "MyCategory/MyMonitor" and "MyMonitor" have same name but different ids so above code is valid + Performance.add_custom_monitor("Custom/MyMonitor", some_callable) # Adds monitor with name "MyName" to category "Custom" + # Note: "MyMonitor" and "Custom/MyMonitor" have same name and same category but different ids so above code is valid + Performance.add_custom_monitor("MyCategoryOne/MyCategoryTwo/MyMonitor", some_callable) # Adds monitor with name "MyCategoryOne/MyCategoryTwo/MyMonitor" to category "Custom" + [/codeblock] + The debugger calls the callable to get the value of custom monitor. The callable must return a number. + Callables are called with arguments supplied in argument array. + [b]Note:[/b] It throws an error if given id is already present. + </description> + </method> + <method name="get_custom_monitor"> + <return type="Variant"> + </return> + <argument index="0" name="id" type="StringName"> + </argument> + <description> + Returns the value of custom monitor with given id. The callable is called to get the value of custom monitor. + [b]Note:[/b] It throws an error if the given id is absent. + </description> + </method> + <method name="get_custom_monitor_names"> + <return type="Array"> + </return> + <description> + Returns the names of active custom monitors in an array. + </description> + </method> <method name="get_monitor" qualifiers="const"> <return type="float"> </return> @@ -23,6 +66,32 @@ [/codeblock] </description> </method> + <method name="get_monitor_modification_time"> + <return type="int"> + </return> + <description> + Returns the last tick in which custom monitor was added/removed. + </description> + </method> + <method name="has_custom_monitor"> + <return type="bool"> + </return> + <argument index="0" name="id" type="StringName"> + </argument> + <description> + Returns true if custom monitor with the given id is present otherwise returns false. + </description> + </method> + <method name="remove_custom_monitor"> + <return type="void"> + </return> + <argument index="0" name="id" type="StringName"> + </argument> + <description> + Removes the custom monitor with given id. + [b]Note:[/b] It throws an error if the given id is already absent. + </description> + </method> </methods> <constants> <constant name="TIME_FPS" value="0" enum="Monitor"> diff --git a/doc/classes/PhysicsShapeQueryParameters2D.xml b/doc/classes/PhysicsShapeQueryParameters2D.xml index 9a162dabbb..63e13954ab 100644 --- a/doc/classes/PhysicsShapeQueryParameters2D.xml +++ b/doc/classes/PhysicsShapeQueryParameters2D.xml @@ -9,15 +9,6 @@ <tutorials> </tutorials> <methods> - <method name="set_shape"> - <return type="void"> - </return> - <argument index="0" name="shape" type="Resource"> - </argument> - <description> - Sets the [Shape2D] that will be used for collision/intersection queries. - </description> - </method> </methods> <members> <member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false"> @@ -38,8 +29,24 @@ <member name="motion" type="Vector2" setter="set_motion" getter="get_motion" default="Vector2( 0, 0 )"> The motion of the shape being queried for. </member> + <member name="shape" type="Resource" setter="set_shape" getter="get_shape"> + The [Shape2D] that will be used for collision/intersection queries. This stores the actual reference which avoids the shape to be released while being used for queries, so always prefer using this over [member shape_rid]. + </member> <member name="shape_rid" type="RID" setter="set_shape_rid" getter="get_shape_rid"> - The queried shape's [RID]. See also [method set_shape]. + The queried shape's [RID] that will be used for collision/intersection queries. Use this over [member shape] if you want to optimize for performance using the Servers API: + [codeblock] + var shape_rid = PhysicsServer2D.circle_shape_create() + var radius = 64 + PhysicsServer2D.shape_set_data(shape_rid, radius) + + var params = PhysicsShapeQueryParameters2D.new() + params.shape_rid = shape_rid + + # Execute physics queries here... + + # Release the shape when done with physics queries. + PhysicsServer2D.free_rid(shape_rid) + [/codeblock] </member> <member name="transform" type="Transform2D" setter="set_transform" getter="get_transform" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> The queried shape's transform matrix. diff --git a/doc/classes/PhysicsShapeQueryParameters3D.xml b/doc/classes/PhysicsShapeQueryParameters3D.xml index 6606cfbc59..f4191d4862 100644 --- a/doc/classes/PhysicsShapeQueryParameters3D.xml +++ b/doc/classes/PhysicsShapeQueryParameters3D.xml @@ -9,15 +9,6 @@ <tutorials> </tutorials> <methods> - <method name="set_shape"> - <return type="void"> - </return> - <argument index="0" name="shape" type="Resource"> - </argument> - <description> - Sets the [Shape3D] that will be used for collision/intersection queries. - </description> - </method> </methods> <members> <member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false"> @@ -35,8 +26,24 @@ <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0"> The collision margin for the shape. </member> + <member name="shape" type="Resource" setter="set_shape" getter="get_shape"> + The [Shape3D] that will be used for collision/intersection queries. This stores the actual reference which avoids the shape to be released while being used for queries, so always prefer using this over [member shape_rid]. + </member> <member name="shape_rid" type="RID" setter="set_shape_rid" getter="get_shape_rid"> - The queried shape's [RID]. See also [method set_shape]. + The queried shape's [RID] that will be used for collision/intersection queries. Use this over [member shape] if you want to optimize for performance using the Servers API: + [codeblock] + var shape_rid = PhysicsServer3D.shape_create(PhysicsServer3D.SHAPE_SPHERE) + var radius = 2.0 + PhysicsServer3D.shape_set_data(shape_rid, radius) + + var params = PhysicsShapeQueryParameters3D.new() + params.shape_rid = shape_rid + + # Execute physics queries here... + + # Release the shape when done with physics queries. + PhysicsServer3D.free_rid(shape_rid) + [/codeblock] </member> <member name="transform" type="Transform" setter="set_transform" getter="get_transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> The queried shape's transform matrix. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 7191492098..799c4d2e75 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1078,13 +1078,13 @@ </member> <member name="rendering/quality/screen_filters/screen_space_aa" type="int" setter="" getter="" default="0"> Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. - Another way to combat specular aliasing is to enable [member rendering/quality/screen_filters/screen_space_roughness_limiter]. + Another way to combat specular aliasing is to enable [member rendering/quality/screen_filters/screen_space_roughness_limiter_enabled]. </member> - <member name="rendering/quality/screen_filters/screen_space_roughness_limiter" type="int" setter="" getter="" default="0"> - Enables the screen-space roughness limiter which increases material roughness in areas with a high normal frequency (i.e. when normals change a lot from pixel to pixel). This helps to reduce the amount of specular aliasing in a scene. Specular aliasing looks like random bright pixels that occur in reflections. + <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_amount" type="float" setter="" getter="" default="0.25"> </member> - <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_curve" type="float" setter="" getter="" default="1.0"> - Curves the amount of the roughness limited effect. A higher value limits the effect to very sharply curved surfaces, while a lower threshold extends the effect to smoother surfaces. + <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_enabled" type="bool" setter="" getter="" default="true"> + </member> + <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_limit" type="float" setter="" getter="" default="0.18"> </member> <member name="rendering/quality/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1"> Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better. @@ -1152,6 +1152,10 @@ <member name="rendering/quality/texture_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false"> If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used. </member> + <member name="rendering/sdfgi/frames_to_converge" type="int" setter="" getter="" default="1"> + </member> + <member name="rendering/sdfgi/probe_ray_count" type="int" setter="" getter="" default="2"> + </member> <member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1"> Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter. </member> diff --git a/doc/classes/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml index 84f87c3e71..07d7b646a1 100644 --- a/doc/classes/ReflectionProbe.xml +++ b/doc/classes/ReflectionProbe.xml @@ -13,6 +13,12 @@ <methods> </methods> <members> + <member name="ambient_color" type="Color" setter="set_ambient_color" getter="get_ambient_color" default="Color( 0, 0, 0, 1 )"> + </member> + <member name="ambient_color_energy" type="float" setter="set_ambient_color_energy" getter="get_ambient_color_energy" default="1.0"> + </member> + <member name="ambient_mode" type="int" setter="set_ambient_mode" getter="get_ambient_mode" enum="ReflectionProbe.AmbientMode" default="1"> + </member> <member name="box_projection" type="bool" setter="set_enable_box_projection" getter="is_box_projection_enabled" default="false"> If [code]true[/code], enables box projection. This makes reflections look more correct in rectangle-shaped rooms by offsetting the reflection center depending on the camera's location. </member> @@ -28,17 +34,8 @@ <member name="intensity" type="float" setter="set_intensity" getter="get_intensity" default="1.0"> Defines the reflection intensity. Intensity modulates the strength of the reflection. </member> - <member name="interior_ambient_color" type="Color" setter="set_interior_ambient" getter="get_interior_ambient" default="Color( 0, 0, 0, 1 )"> - Sets the ambient light color to be used when this probe is set to [member interior_enable]. - </member> - <member name="interior_ambient_contrib" type="float" setter="set_interior_ambient_probe_contribution" getter="get_interior_ambient_probe_contribution" default="0.0"> - Sets the contribution value for how much the reflection affects the ambient light for this reflection probe when set to [member interior_enable]. Useful so that ambient light matches the color of the room. - </member> - <member name="interior_ambient_energy" type="float" setter="set_interior_ambient_energy" getter="get_interior_ambient_energy" default="1.0"> - Sets the energy multiplier for this reflection probe's ambient light contribution when set to [member interior_enable]. - </member> - <member name="interior_enable" type="bool" setter="set_as_interior" getter="is_set_as_interior" default="false"> - If [code]true[/code], reflections will ignore sky contribution. Ambient lighting is then controlled by the [code]interior_ambient_*[/code] properties. + <member name="interior" type="bool" setter="set_as_interior" getter="is_set_as_interior" default="false"> + If [code]true[/code], reflections will ignore sky contribution. </member> <member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="0.0"> Sets the max distance away from the probe an object can be before it is culled. @@ -57,5 +54,11 @@ <constant name="UPDATE_ALWAYS" value="1" enum="UpdateMode"> Update the probe every frame. This is needed when you want to capture dynamic objects. However, it results in an increased render time. Use [constant UPDATE_ONCE] whenever possible. </constant> + <constant name="AMBIENT_DISABLED" value="0" enum="AmbientMode"> + </constant> + <constant name="AMBIENT_ENVIRONMENT" value="1" enum="AmbientMode"> + </constant> + <constant name="AMBIENT_COLOR" value="2" enum="AmbientMode"> + </constant> </constants> </class> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index 8a44d213e8..7e5df9c40d 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -152,6 +152,8 @@ </argument> <argument index="8" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )"> </argument> + <argument index="9" name="storage_textures" type="Array" default="[ ]"> + </argument> <description> </description> </method> @@ -188,6 +190,8 @@ </argument> <argument index="9" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )"> </argument> + <argument index="10" name="storage_textures" type="RID[]" default="[ ]"> + </argument> <description> </description> </method> @@ -293,6 +297,16 @@ <description> </description> </method> + <method name="framebuffer_create_empty"> + <return type="RID"> + </return> + <argument index="0" name="size" type="Vector2i"> + </argument> + <argument index="1" name="validate_with_format" type="int" default="-1"> + </argument> + <description> + </description> + </method> <method name="framebuffer_format_create"> <return type="int"> </return> @@ -301,6 +315,14 @@ <description> </description> </method> + <method name="framebuffer_format_create_empty"> + <return type="int"> + </return> + <argument index="0" name="size" type="Vector2i"> + </argument> + <description> + </description> + </method> <method name="framebuffer_format_get_texture_samples"> <return type="int" enum="RenderingDevice.TextureSamples"> </return> @@ -496,6 +518,8 @@ </argument> <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )"> </argument> + <argument index="2" name="usage" type="int" default="0"> + </argument> <description> </description> </method> @@ -1285,6 +1309,8 @@ </constant> <constant name="INDEX_BUFFER_FORMAT_UINT32" value="1" enum="IndexBufferFormat"> </constant> + <constant name="STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT" value="1" enum="StorageBufferUsage"> + </constant> <constant name="UNIFORM_TYPE_SAMPLER" value="0" enum="UniformType"> </constant> <constant name="UNIFORM_TYPE_SAMPLER_WITH_TEXTURE" value="1" enum="UniformType"> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 8832c0ec4d..7539f8ff43 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1470,6 +1470,16 @@ Sets whether to use a dual paraboloid or a cubemap for the shadow map. Dual paraboloid is faster but may suffer from artifacts. Equivalent to [member OmniLight3D.omni_shadow_mode]. </description> </method> + <method name="light_set_bake_mode"> + <return type="void"> + </return> + <argument index="0" name="light" type="RID"> + </argument> + <argument index="1" name="bake_mode" type="int" enum="RenderingServer.LightBakeMode"> + </argument> + <description> + </description> + </method> <method name="light_set_color"> <return type="void"> </return> @@ -1560,17 +1570,6 @@ Sets the color of the shadow cast by the light. Equivalent to [member Light3D.shadow_color]. </description> </method> - <method name="light_set_use_gi"> - <return type="void"> - </return> - <argument index="0" name="light" type="RID"> - </argument> - <argument index="1" name="enabled" type="bool"> - </argument> - <description> - Sets whether GI probes capture light information from this light. - </description> - </method> <method name="make_sphere_mesh"> <return type="RID"> </return> @@ -2292,40 +2291,37 @@ To place in a scene, attach this reflection probe to an instance using [method instance_set_base] using the returned RID. </description> </method> - <method name="reflection_probe_set_as_interior"> + <method name="reflection_probe_set_ambient_color"> <return type="void"> </return> <argument index="0" name="probe" type="RID"> </argument> - <argument index="1" name="enable" type="bool"> + <argument index="1" name="color" type="Color"> </argument> <description> - If [code]true[/code], reflections will ignore sky contribution. Equivalent to [member ReflectionProbe.interior_enable]. </description> </method> - <method name="reflection_probe_set_cull_mask"> + <method name="reflection_probe_set_ambient_energy"> <return type="void"> </return> <argument index="0" name="probe" type="RID"> </argument> - <argument index="1" name="layers" type="int"> + <argument index="1" name="energy" type="float"> </argument> <description> - Sets the render cull mask for this reflection probe. Only instances with a matching cull mask will be rendered by this probe. Equivalent to [member ReflectionProbe.cull_mask]. </description> </method> - <method name="reflection_probe_set_enable_box_projection"> + <method name="reflection_probe_set_ambient_mode"> <return type="void"> </return> <argument index="0" name="probe" type="RID"> </argument> - <argument index="1" name="enable" type="bool"> + <argument index="1" name="mode" type="int" enum="RenderingServer.ReflectionProbeAmbientMode"> </argument> <description> - If [code]true[/code], uses box projection. This can make reflections look more correct in certain situations. Equivalent to [member ReflectionProbe.box_projection]. </description> </method> - <method name="reflection_probe_set_enable_shadows"> + <method name="reflection_probe_set_as_interior"> <return type="void"> </return> <argument index="0" name="probe" type="RID"> @@ -2333,62 +2329,62 @@ <argument index="1" name="enable" type="bool"> </argument> <description> - If [code]true[/code], computes shadows in the reflection probe. This makes the reflection much slower to compute. Equivalent to [member ReflectionProbe.enable_shadows]. + If [code]true[/code], reflections will ignore sky contribution. Equivalent to [member ReflectionProbe.interior]. </description> </method> - <method name="reflection_probe_set_extents"> + <method name="reflection_probe_set_cull_mask"> <return type="void"> </return> <argument index="0" name="probe" type="RID"> </argument> - <argument index="1" name="extents" type="Vector3"> + <argument index="1" name="layers" type="int"> </argument> <description> - Sets the size of the area that the reflection probe will capture. Equivalent to [member ReflectionProbe.extents]. + Sets the render cull mask for this reflection probe. Only instances with a matching cull mask will be rendered by this probe. Equivalent to [member ReflectionProbe.cull_mask]. </description> </method> - <method name="reflection_probe_set_intensity"> + <method name="reflection_probe_set_enable_box_projection"> <return type="void"> </return> <argument index="0" name="probe" type="RID"> </argument> - <argument index="1" name="intensity" type="float"> + <argument index="1" name="enable" type="bool"> </argument> <description> - Sets the intensity of the reflection probe. Intensity modulates the strength of the reflection. Equivalent to [member ReflectionProbe.intensity]. + If [code]true[/code], uses box projection. This can make reflections look more correct in certain situations. Equivalent to [member ReflectionProbe.box_projection]. </description> </method> - <method name="reflection_probe_set_interior_ambient"> + <method name="reflection_probe_set_enable_shadows"> <return type="void"> </return> <argument index="0" name="probe" type="RID"> </argument> - <argument index="1" name="color" type="Color"> + <argument index="1" name="enable" type="bool"> </argument> <description> - Sets the ambient light color for this reflection probe when set to interior mode. Equivalent to [member ReflectionProbe.interior_ambient_color]. + If [code]true[/code], computes shadows in the reflection probe. This makes the reflection much slower to compute. Equivalent to [member ReflectionProbe.enable_shadows]. </description> </method> - <method name="reflection_probe_set_interior_ambient_energy"> + <method name="reflection_probe_set_extents"> <return type="void"> </return> <argument index="0" name="probe" type="RID"> </argument> - <argument index="1" name="energy" type="float"> + <argument index="1" name="extents" type="Vector3"> </argument> <description> - Sets the energy multiplier for this reflection probes ambient light contribution when set to interior mode. Equivalent to [member ReflectionProbe.interior_ambient_energy]. + Sets the size of the area that the reflection probe will capture. Equivalent to [member ReflectionProbe.extents]. </description> </method> - <method name="reflection_probe_set_interior_ambient_probe_contribution"> + <method name="reflection_probe_set_intensity"> <return type="void"> </return> <argument index="0" name="probe" type="RID"> </argument> - <argument index="1" name="contrib" type="float"> + <argument index="1" name="intensity" type="float"> </argument> <description> - Sets the contribution value for how much the reflection affects the ambient light for this reflection probe when set to interior mode. Useful so that ambient light matches the color of the room. Equivalent to [member ReflectionProbe.interior_ambient_contrib]. + Sets the intensity of the reflection probe. Intensity modulates the strength of the reflection. Equivalent to [member ReflectionProbe.intensity]. </description> </method> <method name="reflection_probe_set_max_distance"> @@ -3261,6 +3257,12 @@ <constant name="LIGHT_PARAM_MAX" value="18" enum="LightParam"> Represents the size of the [enum LightParam] enum. </constant> + <constant name="LIGHT_BAKE_DISABLED" value="0" enum="LightBakeMode"> + </constant> + <constant name="LIGHT_BAKE_DYNAMIC" value="1" enum="LightBakeMode"> + </constant> + <constant name="LIGHT_BAKE_STATIC" value="2" enum="LightBakeMode"> + </constant> <constant name="LIGHT_OMNI_SHADOW_DUAL_PARABOLOID" value="0" enum="LightOmniShadowMode"> Use a dual paraboloid shadow map for omni lights. </constant> @@ -3288,6 +3290,12 @@ <constant name="REFLECTION_PROBE_UPDATE_ALWAYS" value="1" enum="ReflectionProbeUpdateMode"> Reflection probe will update each frame. This mode is necessary to capture moving objects. </constant> + <constant name="REFLECTION_PROBE_AMBIENT_DISABLED" value="0" enum="ReflectionProbeAmbientMode"> + </constant> + <constant name="REFLECTION_PROBE_AMBIENT_ENVIRONMENT" value="1" enum="ReflectionProbeAmbientMode"> + </constant> + <constant name="REFLECTION_PROBE_AMBIENT_COLOR" value="2" enum="ReflectionProbeAmbientMode"> + </constant> <constant name="DECAL_TEXTURE_ALBEDO" value="0" enum="DecalTexture"> </constant> <constant name="DECAL_TEXTURE_NORMAL" value="1" enum="DecalTexture"> @@ -3412,13 +3420,16 @@ <constant name="VIEWPORT_DEBUG_DRAW_SSAO" value="12" enum="ViewportDebugDraw"> Draws the screen space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment]. </constant> - <constant name="VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="ViewportDebugDraw"> - Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work. - </constant> - <constant name="VIEWPORT_DEBUG_DRAW_PSSM_SPLITS" value="14" enum="ViewportDebugDraw"> + <constant name="VIEWPORT_DEBUG_DRAW_PSSM_SPLITS" value="13" enum="ViewportDebugDraw"> Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order they will be colored red, green, blue, yellow. </constant> - <constant name="VIEWPORT_DEBUG_DRAW_DECAL_ATLAS" value="15" enum="ViewportDebugDraw"> + <constant name="VIEWPORT_DEBUG_DRAW_DECAL_ATLAS" value="14" enum="ViewportDebugDraw"> + </constant> + <constant name="VIEWPORT_DEBUG_DRAW_SDFGI" value="15" enum="ViewportDebugDraw"> + </constant> + <constant name="VIEWPORT_DEBUG_DRAW_SDFGI_PROBES" value="16" enum="ViewportDebugDraw"> + </constant> + <constant name="VIEWPORT_DEBUG_DRAW_GI_BUFFER" value="17" enum="ViewportDebugDraw"> </constant> <constant name="SKY_MODE_QUALITY" value="0" enum="SkyMode"> Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples]. diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 3b52c80c9a..8a2c6b73d8 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -377,15 +377,18 @@ <constant name="DEBUG_DRAW_SSAO" value="12" enum="DebugDraw"> Draws the screen-space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment]. </constant> - <constant name="DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="DebugDraw"> - Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work. - </constant> - <constant name="DEBUG_DRAW_PSSM_SPLITS" value="14" enum="DebugDraw"> + <constant name="DEBUG_DRAW_PSSM_SPLITS" value="13" enum="DebugDraw"> Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order, they will be colored red, green, blue, and yellow. </constant> - <constant name="DEBUG_DRAW_DECAL_ATLAS" value="15" enum="DebugDraw"> + <constant name="DEBUG_DRAW_DECAL_ATLAS" value="14" enum="DebugDraw"> Draws the decal atlas used by [Decal]s and light projector textures in the upper left quadrant of the [Viewport]. </constant> + <constant name="DEBUG_DRAW_SDFGI" value="15" enum="DebugDraw"> + </constant> + <constant name="DEBUG_DRAW_SDFGI_PROBES" value="16" enum="DebugDraw"> + </constant> + <constant name="DEBUG_DRAW_GI_BUFFER" value="17" enum="DebugDraw"> + </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="0" enum="DefaultCanvasItemTextureFilter"> The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized. </constant> diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 7af7678f63..0d2d6b38a7 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -51,6 +51,14 @@ public: int get_directional_light_shadow_size(RID p_light_intance) { return 0; } void set_directional_shadow_count(int p_count) {} + /* SDFGI UPDATE */ + + virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) {} + virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const { return 0; } + virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const { return AABB(); } + virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const { return 0; } + virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) {} + /* SKY API */ RID sky_create() { return RID(); } @@ -87,6 +95,11 @@ public: virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {} virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) {} + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {} + + virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {} + virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {} + void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {} void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {} @@ -114,6 +127,7 @@ public: RID light_instance_create(RID p_light) { return RID(); } void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {} + virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {} void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) {} void light_instance_mark_visible(RID p_light_instance) {} @@ -137,9 +151,13 @@ public: virtual bool gi_probe_needs_update(RID p_probe) const { return false; } virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) {} + virtual void gi_probe_set_quality(RS::GIProbeQuality) {} + virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {} void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {} virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {} + virtual void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) {} + virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) {} void set_scene_pass(uint64_t p_pass) {} virtual void set_time(double p_time, double p_step) {} @@ -148,7 +166,7 @@ public: virtual RID render_buffers_create() { return RID(); } virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) {} - virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) {} + virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) {} virtual bool screen_space_roughness_limiter_is_active() const { return false; } virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {} @@ -158,6 +176,7 @@ public: bool free(RID p_rid) { return true; } virtual void update() {} + virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {} RasterizerSceneDummy() {} ~RasterizerSceneDummy() {} @@ -576,7 +595,8 @@ public: void light_set_negative(RID p_light, bool p_enable) {} void light_set_cull_mask(RID p_light, uint32_t p_mask) {} void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {} - void light_set_use_gi(RID p_light, bool p_enabled) {} + void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {} + void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {} void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {} @@ -595,7 +615,8 @@ public: AABB light_get_aabb(RID p_light) const { return AABB(); } float light_get_param(RID p_light, RS::LightParam p_param) { return 0.0; } Color light_get_color(RID p_light) { return Color(); } - bool light_get_use_gi(RID p_light) { return false; } + virtual RS::LightBakeMode light_get_bake_mode(RID p_light) { return RS::LIGHT_BAKE_DISABLED; } + virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) { return 0; } uint64_t light_get_version(RID p_light) const { return 0; } /* PROBE API */ @@ -604,9 +625,9 @@ public: void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {} void reflection_probe_set_intensity(RID p_probe, float p_intensity) {} - void reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) {} - void reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) {} - void reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) {} + void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {} + void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {} + void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {} void reflection_probe_set_max_distance(RID p_probe, float p_distance) {} void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {} void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {} diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 2e36de5c79..a5e85424b7 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -247,6 +247,9 @@ void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const Stri for (int i = 0; i < fnode->arguments.size(); i++) { if (i > 0) header += ", "; + if (fnode->arguments[i].is_const) { + header += "const "; + } if (fnode->arguments[i].type == SL::TYPE_STRUCT) { header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name); } else { diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index 15ad187ab4..186804dbb1 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -245,7 +245,7 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, St continue; } - if_v6id = (uint32_t)c.index.to_int64(); + if_v6id = (uint32_t)c.index.to_int(); if (type == IP::TYPE_IPV6) { break; // IPv6 uses index. } diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp new file mode 100644 index 0000000000..47fe282758 --- /dev/null +++ b/editor/debugger/editor_performance_profiler.cpp @@ -0,0 +1,394 @@ +/*************************************************************************/ +/* editor_performance_profiler.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_performance_profiler.h" + +#include "editor/editor_scale.h" +#include "editor/editor_settings.h" +#include "main/performance.h" + +EditorPerformanceProfiler::Monitor::Monitor() {} + +EditorPerformanceProfiler::Monitor::Monitor(String p_name, String p_base, int p_frame_index, Performance::MonitorType p_type, TreeItem *p_item) { + type = p_type; + item = p_item; + frame_index = p_frame_index; + name = p_name; + base = p_base; +} + +void EditorPerformanceProfiler::Monitor::update_value(float p_value) { + ERR_FAIL_COND(!item); + String label = EditorPerformanceProfiler::_create_label(p_value, type); + String tooltip = label; + switch (type) { + case Performance::MONITOR_TYPE_MEMORY: { + tooltip = label; + } break; + case Performance::MONITOR_TYPE_TIME: { + tooltip = label; + } break; + default: { + tooltip += " " + item->get_text(0); + } break; + } + item->set_text(1, label); + item->set_tooltip(1, tooltip); + + if (p_value > max) { + max = p_value; + } +} + +void EditorPerformanceProfiler::Monitor::reset() { + history.clear(); + max = 0.0f; + if (item) { + item->set_text(1, ""); + item->set_tooltip(1, ""); + } +} + +String EditorPerformanceProfiler::_create_label(float p_value, Performance::MonitorType p_type) { + switch (p_type) { + case Performance::MONITOR_TYPE_MEMORY: { + return String::humanize_size(p_value); + } + case Performance::MONITOR_TYPE_TIME: { + return rtos(p_value * 1000).pad_decimals(2) + " ms"; + } + default: { + return rtos(p_value); + } + } +} + +void EditorPerformanceProfiler::_monitor_select() { + monitor_draw->update(); +} + +void EditorPerformanceProfiler::_monitor_draw() { + Vector<StringName> active; + for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { + if (i.value().item->is_checked(0)) { + active.push_back(i.key()); + } + } + + if (active.empty()) { + info_message->show(); + return; + } + + info_message->hide(); + + Ref<StyleBox> graph_style_box = get_theme_stylebox("normal", "TextEdit"); + Ref<Font> graph_font = get_theme_font("font", "TextEdit"); + + int columns = int(Math::ceil(Math::sqrt(float(active.size())))); + int rows = int(Math::ceil(float(active.size()) / float(columns))); + if (active.size() == 1) { + rows = 1; + } + Size2i cell_size = Size2i(monitor_draw->get_size()) / Size2i(columns, rows); + float spacing = float(POINT_SEPARATION) / float(columns); + float value_multiplier = EditorSettings::get_singleton()->is_dark_theme() ? 1.4f : 0.55f; + float hue_shift = 1.0f / float(monitors.size()); + + for (int i = 0; i < active.size(); i++) { + Monitor ¤t = monitors[active[i]]; + Rect2i rect(Point2i(i % columns, i / columns) * cell_size + Point2i(MARGIN, MARGIN), cell_size - Point2i(MARGIN, MARGIN) * 2); + monitor_draw->draw_style_box(graph_style_box, rect); + + rect.position += graph_style_box->get_offset(); + rect.size -= graph_style_box->get_minimum_size(); + Color draw_color = get_theme_color("accent_color", "Editor"); + draw_color.set_hsv(Math::fmod(hue_shift * float(current.frame_index), 0.9f), draw_color.get_s() * 0.9f, draw_color.get_v() * value_multiplier, 0.6f); + monitor_draw->draw_string(graph_font, rect.position + Point2(0, graph_font->get_ascent()), current.item->get_text(0), draw_color, rect.size.x); + + draw_color.a = 0.9f; + float value_position = rect.size.width - graph_font->get_string_size(current.item->get_text(1)).width; + if (value_position < 0) { + value_position = 0; + } + monitor_draw->draw_string(graph_font, rect.position + Point2(value_position, graph_font->get_ascent()), current.item->get_text(1), draw_color, rect.size.x); + + rect.position.y += graph_font->get_height(); + rect.size.height -= graph_font->get_height(); + + int line_count = rect.size.height / (graph_font->get_height() * 2); + if (line_count > 5) { + line_count = 5; + } + if (line_count > 0) { + Color horizontal_line_color; + horizontal_line_color.set_hsv(draw_color.get_h(), draw_color.get_s() * 0.5f, draw_color.get_v() * 0.5f, 0.3f); + monitor_draw->draw_line(rect.position, rect.position + Vector2(rect.size.width, 0), horizontal_line_color, Math::round(EDSCALE)); + monitor_draw->draw_string(graph_font, rect.position + Vector2(0, graph_font->get_ascent()), _create_label(current.max, current.type), horizontal_line_color, rect.size.width); + + for (int j = 0; j < line_count; j++) { + Vector2 y_offset = Vector2(0, rect.size.height * (1.0f - float(j) / float(line_count))); + monitor_draw->draw_line(rect.position + y_offset, rect.position + Vector2(rect.size.width, 0) + y_offset, horizontal_line_color, Math::round(EDSCALE)); + monitor_draw->draw_string(graph_font, rect.position - Vector2(0, graph_font->get_descent()) + y_offset, _create_label(current.max * float(j) / float(line_count), current.type), horizontal_line_color, rect.size.width); + } + } + + float from = rect.size.width; + float prev = -1.0f; + int count = 0; + List<float>::Element *e = current.history.front(); + + while (from >= 0 && e) { + float m = current.max; + float h2 = 0; + if (m != 0) { + h2 = (e->get() / m); + } + h2 = (1.0f - h2) * float(rect.size.y); + if (e != current.history.front()) { + monitor_draw->draw_line(rect.position + Point2(from, h2), rect.position + Point2(from + spacing, prev), draw_color, Math::round(EDSCALE)); + } + + if (marker_key == active[i] && count == marker_frame) { + Color line_color; + line_color.set_hsv(draw_color.get_h(), draw_color.get_s() * 0.8f, draw_color.get_v(), 0.5f); + monitor_draw->draw_line(rect.position + Point2(from, 0), rect.position + Point2(from, rect.size.y), line_color, Math::round(EDSCALE)); + + String label = _create_label(e->get(), current.type); + Size2 size = graph_font->get_string_size(label); + Vector2 text_top_left_position = Vector2(from, h2) - (size + Vector2(MARKER_MARGIN, MARKER_MARGIN)); + if (text_top_left_position.x < 0) { + text_top_left_position.x = from + MARKER_MARGIN; + } + if (text_top_left_position.y < 0) { + text_top_left_position.y = h2 + MARKER_MARGIN; + } + monitor_draw->draw_string(graph_font, rect.position + text_top_left_position + Point2(0, graph_font->get_ascent()), label, line_color, rect.size.x); + } + prev = h2; + e = e->next(); + from -= spacing; + count++; + } + } +} + +void EditorPerformanceProfiler::_build_monitor_tree() { + Set<StringName> monitor_checked; + for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { + if (i.value().item && i.value().item->is_checked(0)) { + monitor_checked.insert(i.key()); + } + } + + base_map.clear(); + monitor_tree->get_root()->clear_children(); + + for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { + TreeItem *base = _get_monitor_base(i.value().base); + TreeItem *item = _create_monitor_item(i.value().name, base); + item->set_checked(0, monitor_checked.has(i.key())); + i.value().item = item; + if (!i.value().history.empty()) { + i.value().update_value(i.value().history.front()->get()); + } + } +} + +TreeItem *EditorPerformanceProfiler::_get_monitor_base(const StringName &p_base_name) { + if (base_map.has(p_base_name)) { + return base_map[p_base_name]; + } + + TreeItem *base = monitor_tree->create_item(monitor_tree->get_root()); + base->set_text(0, p_base_name); + base->set_editable(0, false); + base->set_selectable(0, false); + base->set_expand_right(0, true); + base_map.insert(p_base_name, base); + return base; +} + +TreeItem *EditorPerformanceProfiler::_create_monitor_item(const StringName &p_monitor_name, TreeItem *p_base) { + TreeItem *item = monitor_tree->create_item(p_base); + item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + item->set_editable(0, true); + item->set_selectable(0, false); + item->set_selectable(1, false); + item->set_text(0, p_monitor_name); + return item; +} + +void EditorPerformanceProfiler::_marker_input(const Ref<InputEvent> &p_event) { + Ref<InputEventMouseButton> mb = p_event; + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + Vector<StringName> active; + for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { + if (i.value().item->is_checked(0)) { + active.push_back(i.key()); + } + } + if (active.size() > 0) { + int columns = int(Math::ceil(Math::sqrt(float(active.size())))); + int rows = int(Math::ceil(float(active.size()) / float(columns))); + if (active.size() == 1) { + rows = 1; + } + Size2i cell_size = Size2i(monitor_draw->get_size()) / Size2i(columns, rows); + Vector2i index = mb->get_position() / cell_size; + Rect2i rect(index * cell_size + Point2i(MARGIN, MARGIN), cell_size - Point2i(MARGIN, MARGIN) * 2); + if (rect.has_point(mb->get_position())) { + if (index.x + index.y * columns < active.size()) { + marker_key = active[index.x + index.y * columns]; + } else { + marker_key = ""; + } + Ref<StyleBox> graph_style_box = get_theme_stylebox("normal", "TextEdit"); + rect.position += graph_style_box->get_offset(); + rect.size -= graph_style_box->get_minimum_size(); + Vector2 point = mb->get_position() - rect.position; + if (point.x >= rect.size.x) { + marker_frame = 0; + } else { + int point_sep = 5; + float spacing = float(point_sep) / float(columns); + marker_frame = (rect.size.x - point.x) / spacing; + } + monitor_draw->update(); + return; + } + } + marker_key = ""; + monitor_draw->update(); + } +} + +void EditorPerformanceProfiler::reset() { + for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { + if (String(i.key()).begins_with("custom:")) { + monitors.erase(i); + } else { + i.value().reset(); + } + } + + _build_monitor_tree(); + marker_key = ""; + marker_frame = 0; + monitor_draw->update(); +} + +void EditorPerformanceProfiler::update_monitors(const Vector<StringName> &p_names) { + OrderedHashMap<StringName, int> names; + for (int i = 0; i < p_names.size(); i++) { + names.insert("custom:" + p_names[i], Performance::MONITOR_MAX + i); + } + + for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { + if (String(i.key()).begins_with("custom:")) { + if (!names.has(i.key())) { + monitors.erase(i); + } else { + i.value().frame_index = names[i.key()]; + names.erase(i.key()); + } + } + } + + for (OrderedHashMap<StringName, int>::Element i = names.front(); i; i = i.next()) { + String name = String(i.key()).replace_first("custom:", ""); + String base = "Custom"; + if (name.get_slice_count("/") == 2) { + base = name.get_slicec('/', 0); + name = name.get_slicec('/', 1); + } + monitors.insert(i.key(), Monitor(name, base, i.value(), Performance::MONITOR_TYPE_QUANTITY, nullptr)); + } + + _build_monitor_tree(); +} + +void EditorPerformanceProfiler::add_profile_frame(const Vector<float> &p_values) { + for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { + float data = 0.0f; + if (i.value().frame_index >= 0 && i.value().frame_index < p_values.size()) { + data = p_values[i.value().frame_index]; + } + i.value().history.push_front(data); + i.value().update_value(data); + } + marker_frame++; + monitor_draw->update(); +} + +List<float> *EditorPerformanceProfiler::get_monitor_data(const StringName &p_name) { + if (monitors.has(p_name)) { + return &monitors[p_name].history; + } + return nullptr; +} + +EditorPerformanceProfiler::EditorPerformanceProfiler() { + set_name(TTR("Monitors")); + set_split_offset(340 * EDSCALE); + + monitor_tree = memnew(Tree); + monitor_tree->set_columns(2); + monitor_tree->set_column_title(0, TTR("Monitor")); + monitor_tree->set_column_title(1, TTR("Value")); + monitor_tree->set_column_titles_visible(true); + monitor_tree->connect("item_edited", callable_mp(this, &EditorPerformanceProfiler::_monitor_select)); + monitor_tree->create_item(); + monitor_tree->set_hide_root(true); + add_child(monitor_tree); + + monitor_draw = memnew(Control); + monitor_draw->set_clip_contents(true); + monitor_draw->connect("draw", callable_mp(this, &EditorPerformanceProfiler::_monitor_draw)); + monitor_draw->connect("gui_input", callable_mp(this, &EditorPerformanceProfiler::_marker_input)); + add_child(monitor_draw); + + info_message = memnew(Label); + info_message->set_text(TTR("Pick one or more items from the list to display the graph.")); + info_message->set_valign(Label::VALIGN_CENTER); + info_message->set_align(Label::ALIGN_CENTER); + info_message->set_autowrap(true); + info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); + info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE); + monitor_draw->add_child(info_message); + + for (int i = 0; i < Performance::MONITOR_MAX; i++) { + String base = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i)).get_slicec('/', 0).capitalize(); + String name = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i)).get_slicec('/', 1).capitalize(); + monitors.insert(Performance::get_singleton()->get_monitor_name(Performance::Monitor(i)), Monitor(name, base, i, Performance::get_singleton()->get_monitor_type(Performance::Monitor(i)), nullptr)); + } + + _build_monitor_tree(); +} diff --git a/editor/debugger/editor_performance_profiler.h b/editor/debugger/editor_performance_profiler.h new file mode 100644 index 0000000000..144dd34103 --- /dev/null +++ b/editor/debugger/editor_performance_profiler.h @@ -0,0 +1,90 @@ +/*************************************************************************/ +/* editor_performance_profiler.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_PERFORMANCE_PROFILER_H +#define EDITOR_PERFORMANCE_PROFILER_H + +#include "core/map.h" +#include "core/ordered_hash_map.h" +#include "main/performance.h" +#include "scene/gui/control.h" +#include "scene/gui/label.h" +#include "scene/gui/split_container.h" +#include "scene/gui/tree.h" + +class EditorPerformanceProfiler : public HSplitContainer { + GDCLASS(EditorPerformanceProfiler, HSplitContainer); + +private: + class Monitor { + public: + String name; + String base; + List<float> history; + float max = 0.0f; + TreeItem *item = nullptr; + Performance::MonitorType type = Performance::MONITOR_TYPE_QUANTITY; + int frame_index = 0; + + Monitor(); + Monitor(String p_name, String p_base, int p_frame_index, Performance::MonitorType p_type, TreeItem *p_item); + void update_value(float p_value); + void reset(); + }; + + OrderedHashMap<StringName, Monitor> monitors; + + Map<StringName, TreeItem *> base_map; + Tree *monitor_tree; + Control *monitor_draw; + Label *info_message; + StringName marker_key; + int marker_frame; + const int MARGIN = 4; + const int POINT_SEPARATION = 5; + const int MARKER_MARGIN = 2; + + static String _create_label(float p_value, Performance::MonitorType p_type); + void _monitor_select(); + void _monitor_draw(); + void _build_monitor_tree(); + TreeItem *_get_monitor_base(const StringName &p_base_name); + TreeItem *_create_monitor_item(const StringName &p_monitor_name, TreeItem *p_base); + void _marker_input(const Ref<InputEvent> &p_event); + +public: + void reset(); + void update_monitors(const Vector<StringName> &p_names); + void add_profile_frame(const Vector<float> &p_values); + List<float> *get_monitor_data(const StringName &p_name); + EditorPerformanceProfiler(); +}; + +#endif // EDITOR_PERFORMANCE_PROFILER_H diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 6b010fbfb5..a828e29558 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -36,6 +36,7 @@ #include "core/project_settings.h" #include "core/ustring.h" #include "editor/debugger/editor_network_profiler.h" +#include "editor/debugger/editor_performance_profiler.h" #include "editor/debugger/editor_profiler.h" #include "editor/debugger/editor_visual_profiler.h" #include "editor/editor_log.h" @@ -172,14 +173,25 @@ void ScriptEditorDebugger::_file_selected(const String &p_file) { file->store_csv_line(line); // values - List<Vector<float>>::Element *E = perf_history.back(); - while (E) { - Vector<float> &perf_data = E->get(); - for (int i = 0; i < perf_data.size(); i++) { - line.write[i] = String::num_real(perf_data[i]); + Vector<List<float>::Element *> iterators; + iterators.resize(Performance::MONITOR_MAX); + bool continue_iteration = false; + for (int i = 0; i < Performance::MONITOR_MAX; i++) { + iterators.write[i] = performance_profiler->get_monitor_data(Performance::get_singleton()->get_monitor_name(Performance::Monitor(i)))->back(); + continue_iteration = continue_iteration || iterators[i]; + } + while (continue_iteration) { + continue_iteration = false; + for (int i = 0; i < Performance::MONITOR_MAX; i++) { + if (iterators[i]) { + line.write[i] = String::num_real(iterators[i]->get()); + iterators.write[i] = iterators[i]->prev(); + } else { + line.write[i] = ""; + } + continue_iteration = continue_iteration || iterators[i]; } file->store_csv_line(line); - E = E->prev(); } file->store_string("\n"); @@ -409,37 +421,12 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da EditorNode::get_log()->add_message(output_strings[i], msg_type); } } else if (p_msg == "performance:profile_frame") { - Vector<float> p; - p.resize(p_data.size()); + Vector<float> frame_data; + frame_data.resize(p_data.size()); for (int i = 0; i < p_data.size(); i++) { - p.write[i] = p_data[i]; - if (i < perf_items.size()) { - const float value = p[i]; - String label = rtos(value); - String tooltip = label; - switch (Performance::MonitorType((int)perf_items[i]->get_metadata(1))) { - case Performance::MONITOR_TYPE_MEMORY: { - label = String::humanize_size(value); - tooltip = label; - } break; - case Performance::MONITOR_TYPE_TIME: { - label = rtos(value * 1000).pad_decimals(2) + " ms"; - tooltip = label; - } break; - default: { - tooltip += " " + perf_items[i]->get_text(0); - } break; - } - - perf_items[i]->set_text(1, label); - perf_items[i]->set_tooltip(1, tooltip); - if (p[i] > perf_max[i]) { - perf_max.write[i] = p[i]; - } - } + frame_data.write[i] = p_data[i]; } - perf_history.push_front(p); - perf_draw->update(); + performance_profiler->add_profile_frame(frame_data); } else if (p_msg == "visual:profile_frame") { DebuggerMarshalls::VisualProfilerFrame frame; @@ -704,6 +691,15 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da emit_signal("stop_requested"); _stop_and_notify(); + } else if (p_msg == "performance:profile_names") { + Vector<StringName> monitors; + monitors.resize(p_data.size()); + for (int i = 0; i < p_data.size(); i++) { + ERR_FAIL_COND(p_data[i].get_type() != Variant::STRING_NAME); + monitors.set(i, p_data[i]); + } + performance_profiler->update_monitors(monitors); + } else { WARN_PRINT("unknown message " + p_msg); } @@ -724,141 +720,6 @@ void ScriptEditorDebugger::_set_reason_text(const String &p_reason, MessageType reason->set_tooltip(p_reason.word_wrap(80)); } -void ScriptEditorDebugger::_performance_select() { - perf_draw->update(); -} - -void ScriptEditorDebugger::_performance_draw() { - Vector<int> which; - for (int i = 0; i < perf_items.size(); i++) { - if (perf_items[i]->is_checked(0)) { - which.push_back(i); - } - } - - if (which.empty()) { - info_message->show(); - return; - } - - info_message->hide(); - - const Ref<StyleBox> graph_sb = get_theme_stylebox("normal", "TextEdit"); - const Ref<Font> graph_font = get_theme_font("font", "TextEdit"); - - const int cols = Math::ceil(Math::sqrt((float)which.size())); - int rows = Math::ceil((float)which.size() / cols); - if (which.size() == 1) { - rows = 1; - } - - const int margin = 3; - const int point_sep = 5; - const Size2i s = Size2i(perf_draw->get_size()) / Size2i(cols, rows); - - for (int i = 0; i < which.size(); i++) { - Point2i p(i % cols, i / cols); - Rect2i r(p * s, s); - r.position += Point2(margin, margin); - r.size -= Point2(margin, margin) * 2.0; - perf_draw->draw_style_box(graph_sb, r); - r.position += graph_sb->get_offset(); - r.size -= graph_sb->get_minimum_size(); - const int pi = which[i]; - - // Draw horizontal lines with labels. - - int nb_lines = 5; - // Draw less lines if the monitor isn't tall enough to display 5 labels. - if (r.size.height <= 160 * EDSCALE) { - nb_lines = 3; - } else if (r.size.height <= 240 * EDSCALE) { - nb_lines = 4; - } - - const float inv_nb_lines = 1.0 / nb_lines; - - for (int line = 0; line < nb_lines; line += 1) { - const int from_x = r.position.x; - const int to_x = r.position.x + r.size.width; - const int y = r.position.y + (r.size.height * inv_nb_lines + line * inv_nb_lines * r.size.height); - perf_draw->draw_line( - Point2(from_x, y), - Point2i(to_x, y), - Color(0.5, 0.5, 0.5, 0.25), - Math::round(EDSCALE)); - - String label; - switch (Performance::MonitorType((int)perf_items[pi]->get_metadata(1))) { - case Performance::MONITOR_TYPE_MEMORY: { - label = String::humanize_size(Math::ceil((1 - inv_nb_lines - inv_nb_lines * line) * perf_max[pi])); - } break; - case Performance::MONITOR_TYPE_TIME: { - label = rtos((1 - inv_nb_lines - inv_nb_lines * line) * perf_max[pi] * 1000).pad_decimals(2) + " ms"; - } break; - default: { - label = itos(Math::ceil((1 - inv_nb_lines - inv_nb_lines * line) * perf_max[pi])); - } break; - } - - perf_draw->draw_string( - graph_font, - Point2(from_x, y - graph_font->get_ascent() * 0.25), - label, - Color(0.5, 0.5, 0.5, 1.0)); - } - - const float h = (float)which[i] / (float)(perf_items.size()); - // Use a darker color on light backgrounds for better visibility. - const float value_multiplier = EditorSettings::get_singleton()->is_dark_theme() ? 1.4 : 0.55; - Color color = get_theme_color("accent_color", "Editor"); - color.set_hsv(Math::fmod(h + 0.4, 0.9), color.get_s() * 0.9, color.get_v() * value_multiplier); - - // Draw the monitor name in the top-left corner. - color.a = 0.6; - perf_draw->draw_string( - graph_font, - r.position + Point2(0, graph_font->get_ascent()), - perf_items[pi]->get_text(0), - color, - r.size.x); - - // Draw the monitor value in the top-left corner, just below the name. - color.a = 0.9; - perf_draw->draw_string( - graph_font, - r.position + Point2(0, graph_font->get_ascent() + graph_font->get_height()), - perf_items[pi]->get_text(1), - color, - r.size.y); - - const float spacing = point_sep / float(cols); - float from = r.size.width; - - const List<Vector<float>>::Element *E = perf_history.front(); - float prev = -1; - while (from >= 0 && E) { - float m = perf_max[pi]; - if (m == 0) { - m = 0.00001; - } - float h2 = E->get()[pi] / m; - h2 = (1.0 - h2) * r.size.y; - - if (E != perf_history.front()) { - perf_draw->draw_line( - r.position + Point2(from, h2), - r.position + Point2(from + spacing, prev), - color, - Math::round(EDSCALE)); - } - prev = h2; - E = E->next(); - from -= spacing; - } - } -} - void ScriptEditorDebugger::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -976,10 +837,7 @@ void ScriptEditorDebugger::start(Ref<RemoteDebuggerPeer> p_peer) { peer = p_peer; ERR_FAIL_COND(p_peer.is_null()); - perf_history.clear(); - for (int i = 0; i < Performance::MONITOR_MAX; i++) { - perf_max.write[i] = 0; - } + performance_profiler->reset(); set_process(true); breaked = false; @@ -1727,63 +1585,8 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { } { //monitors - - HSplitContainer *hsp = memnew(HSplitContainer); - - perf_monitors = memnew(Tree); - perf_monitors->set_columns(2); - perf_monitors->set_column_title(0, TTR("Monitor")); - perf_monitors->set_column_title(1, TTR("Value")); - perf_monitors->set_column_titles_visible(true); - perf_monitors->connect("item_edited", callable_mp(this, &ScriptEditorDebugger::_performance_select)); - hsp->add_child(perf_monitors); - - perf_draw = memnew(Control); - perf_draw->set_clip_contents(true); - perf_draw->connect("draw", callable_mp(this, &ScriptEditorDebugger::_performance_draw)); - hsp->add_child(perf_draw); - - hsp->set_name(TTR("Monitors")); - hsp->set_split_offset(340 * EDSCALE); - tabs->add_child(hsp); - perf_max.resize(Performance::MONITOR_MAX); - - Map<String, TreeItem *> bases; - TreeItem *root = perf_monitors->create_item(); - perf_monitors->set_hide_root(true); - for (int i = 0; i < Performance::MONITOR_MAX; i++) { - String n = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i)); - Performance::MonitorType mtype = Performance::get_singleton()->get_monitor_type(Performance::Monitor(i)); - String base = n.get_slice("/", 0); - String name = n.get_slice("/", 1); - if (!bases.has(base)) { - TreeItem *b = perf_monitors->create_item(root); - b->set_text(0, base.capitalize()); - b->set_editable(0, false); - b->set_selectable(0, false); - b->set_expand_right(0, true); - bases[base] = b; - } - - TreeItem *it = perf_monitors->create_item(bases[base]); - it->set_metadata(1, mtype); - it->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - it->set_editable(0, true); - it->set_selectable(0, false); - it->set_selectable(1, false); - it->set_text(0, name.capitalize()); - perf_items.push_back(it); - perf_max.write[i] = 0; - } - - info_message = memnew(Label); - info_message->set_text(TTR("Pick one or more items from the list to display the graph.")); - info_message->set_valign(Label::VALIGN_CENTER); - info_message->set_align(Label::ALIGN_CENTER); - info_message->set_autowrap(true); - info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); - info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE); - perf_draw->add_child(info_message); + performance_profiler = memnew(EditorPerformanceProfiler); + tabs->add_child(performance_profiler); } { //vmem inspect diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h index 2984051aa1..12fb82cc6f 100644 --- a/editor/debugger/script_editor_debugger.h +++ b/editor/debugger/script_editor_debugger.h @@ -52,6 +52,7 @@ class ItemList; class EditorProfiler; class EditorVisualProfiler; class EditorNetworkProfiler; +class EditorPerformanceProfiler; class SceneDebuggerTree; class ScriptEditorDebugger : public MarginContainer { @@ -113,16 +114,8 @@ private: // Each debugger should have it's tree in the future I guess. const Tree *editor_remote_tree = nullptr; - List<Vector<float>> perf_history; - Vector<float> perf_max; - Vector<TreeItem *> perf_items; - Map<int, String> profiler_signature; - Tree *perf_monitors; - Control *perf_draw; - Label *info_message; - Tree *vmem_tree; Button *vmem_refresh; Button *vmem_export; @@ -141,6 +134,7 @@ private: EditorProfiler *profiler; EditorVisualProfiler *visual_profiler; EditorNetworkProfiler *network_profiler; + EditorPerformanceProfiler *performance_profiler; EditorNode *editor; @@ -152,8 +146,6 @@ private: EditorDebuggerNode::CameraOverride camera_override; - void _performance_draw(); - void _performance_select(); void _stack_dump_frame_selected(); void _file_selected(const String &p_file); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index d88c61d7b2..9ca3d387d9 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -233,9 +233,9 @@ void EditorFileSystem::_scan_filesystem() { FileCache fc; fc.type = split[1]; - fc.modification_time = split[2].to_int64(); - fc.import_modification_time = split[3].to_int64(); - fc.import_valid = split[4].to_int64() != 0; + fc.modification_time = split[2].to_int(); + fc.import_modification_time = split[3].to_int(); + fc.import_valid = split[4].to_int() != 0; fc.import_group_file = split[5].strip_edges(); fc.script_class_name = split[6].get_slice("<>", 0); fc.script_class_extends = split[6].get_slice("<>", 1); diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index d2b9405552..4392538737 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -332,17 +332,10 @@ bool EditorHelpSearch::Runner::_phase_match_classes() { if (search_flags & SEARCH_METHODS) { for (int i = 0; i < class_doc.methods.size(); i++) { String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower(); - String aux_term = (search_flags & SEARCH_CASE_SENSITIVE) ? term : term.to_lower(); - - if (aux_term.begins_with(".")) { - aux_term = aux_term.right(1); - } - - if (aux_term.ends_with("(")) { - aux_term = aux_term.left(aux_term.length() - 1).strip_edges(); - } - - if (aux_term.is_subsequence_of(method_name)) { + if (method_name.find(term) > -1 || + (term.begins_with(".") && method_name.begins_with(term.right(1))) || + (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || + (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) { match.methods.push_back(const_cast<DocData::MethodDoc *>(&class_doc.methods[i])); } } @@ -448,9 +441,9 @@ bool EditorHelpSearch::Runner::_phase_select_match() { bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String &p_string) const { if (search_flags & SEARCH_CASE_SENSITIVE) { - return p_term.is_subsequence_of(p_string); + return p_string.find(p_term) > -1; } else { - return p_term.is_subsequence_ofi(p_string); + return p_string.findn(p_term) > -1; } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 30aa24695c..80a1da7827 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -360,7 +360,7 @@ void EditorNode::_notification(int p_what) { bool dof_jitter = GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter"); RS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter); RS::get_singleton()->environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size")); - RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_enable"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit")); + RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit")); bool glow_bicubic = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0; RS::get_singleton()->environment_glow_set_use_bicubic_upscale(glow_bicubic); RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality"))); @@ -435,14 +435,14 @@ void EditorNode::_notification(int p_what) { /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } break; - case NOTIFICATION_WM_FOCUS_IN: { + case NOTIFICATION_APPLICATION_FOCUS_IN: { // Restore the original FPS cap after focusing back on the editor OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec"))); EditorFileSystem::get_singleton()->scan_changes(); } break; - case NOTIFICATION_WM_FOCUS_OUT: { + case NOTIFICATION_APPLICATION_FOCUS_OUT: { // Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec"))); } break; @@ -3411,10 +3411,14 @@ void EditorNode::_update_recent_scenes() { void EditorNode::_quick_opened() { Vector<String> files = quick_open->get_selected_files(); + bool open_scene_dialog = quick_open->get_base_type() == "PackedScene"; for (int i = 0; i < files.size(); i++) { String res_path = files[i]; - if (quick_open->get_base_type() == "PackedScene") { + List<String> scene_extensions; + ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions); + + if (open_scene_dialog || scene_extensions.find(files[i].get_extension())) { open_request(res_path); } else { load_resource(res_path); @@ -6488,6 +6492,7 @@ EditorNode::EditorNode() { } resource_preview->add_preview_generator(Ref<EditorTexturePreviewPlugin>(memnew(EditorTexturePreviewPlugin))); + resource_preview->add_preview_generator(Ref<EditorImagePreviewPlugin>(memnew(EditorImagePreviewPlugin))); resource_preview->add_preview_generator(Ref<EditorPackedScenePreviewPlugin>(memnew(EditorPackedScenePreviewPlugin))); resource_preview->add_preview_generator(Ref<EditorMaterialPreviewPlugin>(memnew(EditorMaterialPreviewPlugin))); resource_preview->add_preview_generator(Ref<EditorScriptPreviewPlugin>(memnew(EditorScriptPreviewPlugin))); diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index b5f1133a9e..fe49198e8f 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -39,7 +39,7 @@ #include "scene/gui/margin_container.h" void EditorPluginSettings::_notification(int p_what) { - if (p_what == NOTIFICATION_WM_FOCUS_IN) { + if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN) { update_plugins(); } else if (p_what == Node::NOTIFICATION_READY) { plugin_config_dialog->connect_compat("plugin_ready", EditorNode::get_singleton(), "_on_plugin_ready"); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index eee610e9a8..23db6ebb4e 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -377,13 +377,13 @@ void EditorPropertyMember::_property_select() { selector->select_method_from_base_type(hint_text, current); } else if (hint == MEMBER_METHOD_OF_INSTANCE) { - Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64())); + Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int())); if (instance) { selector->select_method_from_instance(instance, current); } } else if (hint == MEMBER_METHOD_OF_SCRIPT) { - Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64())); + Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int())); if (Object::cast_to<Script>(obj)) { selector->select_method_from_script(Object::cast_to<Script>(obj), current); } @@ -408,13 +408,13 @@ void EditorPropertyMember::_property_select() { selector->select_property_from_base_type(hint_text, current); } else if (hint == MEMBER_PROPERTY_OF_INSTANCE) { - Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64())); + Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int())); if (instance) { selector->select_property_from_instance(instance, current); } } else if (hint == MEMBER_PROPERTY_OF_SCRIPT) { - Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64())); + Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int())); if (Object::cast_to<Script>(obj)) { selector->select_property_from_script(Object::cast_to<Script>(obj), current); } @@ -488,7 +488,7 @@ void EditorPropertyEnum::setup(const Vector<String> &p_options) { for (int i = 0; i < p_options.size(); i++) { Vector<String> text_split = p_options[i].split(":"); if (text_split.size() != 1) { - current_val = text_split[1].to_int64(); + current_val = text_split[1].to_int(); } options->add_item(text_split[0]); options->set_item_metadata(i, current_val); diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 7ac8fae156..d2250fed7a 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -110,7 +110,7 @@ void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Textur uint64_t modified_time = 0; if (p_str.begins_with("ID:")) { - hash = uint32_t(p_str.get_slicec(':', 2).to_int64()); + hash = uint32_t(p_str.get_slicec(':', 2).to_int()); path = "ID:" + p_str.get_slicec(':', 1); } else { modified_time = FileAccess::get_modified_time(path); @@ -257,9 +257,9 @@ void EditorResourcePreview::_thread() { _generate_preview(texture, small_texture, item, cache_base); } else { uint64_t modtime = FileAccess::get_modified_time(item.path); - int tsize = f->get_line().to_int64(); + int tsize = f->get_line().to_int(); bool has_small_texture = f->get_line().to_int(); - uint64_t last_modtime = f->get_line().to_int64(); + uint64_t last_modtime = f->get_line().to_int(); bool cache_valid = true; diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 67d92c4839..d76a3d2da7 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -182,8 +182,8 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) { } void EditorSpinSlider::_notification(int p_what) { - if (p_what == NOTIFICATION_WM_FOCUS_OUT || - p_what == NOTIFICATION_WM_FOCUS_IN || + if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_OUT || + p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN || p_what == NOTIFICATION_EXIT_TREE) { if (grabbing_spinner) { grabber->hide(); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index c700fdccad..e1f55bd8a8 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -2508,10 +2508,10 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_tree_thumbnail_done"), &FileSystemDock::_tree_thumbnail_done); ClassDB::bind_method(D_METHOD("_select_file"), &FileSystemDock::_select_file); - ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &FileSystemDock::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &FileSystemDock::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw"), &FileSystemDock::drop_data_fw); - ClassDB::bind_method(D_METHOD("navigate_to_path"), &FileSystemDock::navigate_to_path); + ClassDB::bind_method(D_METHOD("get_drag_data_fw", "position", "from"), &FileSystemDock::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("can_drop_data_fw", "position", "data", "from"), &FileSystemDock::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw", "position", "data", "from"), &FileSystemDock::drop_data_fw); + ClassDB::bind_method(D_METHOD("navigate_to_path", "path"), &FileSystemDock::navigate_to_path); ClassDB::bind_method(D_METHOD("_update_import_dock"), &FileSystemDock::_update_import_dock); diff --git a/editor/icons/InterpolatedCamera.svg b/editor/icons/InterpolatedCamera.svg deleted file mode 100644 index 4bc4ba1ee9..0000000000 --- a/editor/icons/InterpolatedCamera.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9.5.00004c-1.5691.0017903-2.8718 1.2125-2.9883 2.7773-.55103-.49952-1.268-.77655-2.0117-.77734-1.6569 0-3 1.3431-3 3 .00179 1.2698.80282 2.4009 2 2.8242v2.1758c0 .554.44599 1 1 1h6c.55401 0 .9853-.4462 1-1v-1l3 2v-6l-3 2v-1.7695c.63486-.56783.99842-1.3788 1-2.2305 0-1.6569-1.3431-3-3-3zm-6 12v4h1v-4zm3 0v4h1v-1h1c.55228 0 1-.44772 1-1v-1c0-.55228-.44824-1.024-1-1h-1zm5 0c-.55228 0-1 .44772-1 1v2c0 .55228.44772 1 1 1h1c.55228 0 1-.44772 1-1v-2c0-.55228-.44772-1-1-1zm-4 1h1v1h-1zm4 0h1v2h-1z" fill="#fc9c9c"/></svg>
\ No newline at end of file diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index e99ffe2b83..49e67f3605 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -369,7 +369,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) } else { const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius"); - if (!_is_line() && wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_threshold) { + if (!_is_line() && wip.size() > 1 && xform.xform(wip[0]).distance_to(xform.xform(cpoint)) < grab_threshold) { //wip closed _wip_close(); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 96079d5418..72d287c35c 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -538,7 +538,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) { ScriptEditorBase *current = Object::cast_to<ScriptEditorBase>(tab_container->get_child(selected)); if (current) { if (p_save) { - apply_scripts(); + _menu_option(FILE_SAVE); } Ref<Script> script = current->get_edited_resource(); @@ -1337,7 +1337,7 @@ void ScriptEditor::_notification(int p_what) { editor->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop)); } break; - case NOTIFICATION_WM_FOCUS_IN: { + case NOTIFICATION_WM_WINDOW_FOCUS_IN: { _test_script_times_on_disk(); _update_modified_scripts_for_external_editor(); } break; diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 0c3a44e4cd..7dd0b8a238 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -338,7 +338,7 @@ void ShaderEditor::_menu_option(int p_option) { } void ShaderEditor::_notification(int p_what) { - if (p_what == NOTIFICATION_WM_FOCUS_IN) { + if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN) { _check_for_external_edit(); } } diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp index 0ac29f68f6..f15a801530 100644 --- a/editor/plugins/shader_file_editor_plugin.cpp +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -200,7 +200,7 @@ void ShaderFileEditor::_update_options() { } void ShaderFileEditor::_notification(int p_what) { - if (p_what == NOTIFICATION_WM_FOCUS_IN) { + if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN) { if (is_visible_in_tree() && shader_file.is_valid()) { _update_options(); } diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 3a92818779..762f42abeb 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -780,7 +780,7 @@ void TextureRegionEditor::_notification(int p_what) { _update_autoslice(); } } break; - case NOTIFICATION_WM_FOCUS_IN: { + case NOTIFICATION_WM_WINDOW_FOCUS_IN: { // This happens when the user leaves the Editor and returns, // they could have changed the textures, so the cache is cleared. cache_map.clear(); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 49b9ca167b..f4838d336f 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -597,7 +597,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: } else if (hint == PROPERTY_HINT_METHOD_OF_INSTANCE) { MAKE_PROPSELECT - Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64())); + Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int())); if (instance) { property_select->select_method_from_instance(instance, v); } @@ -607,7 +607,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: } else if (hint == PROPERTY_HINT_METHOD_OF_SCRIPT) { MAKE_PROPSELECT - Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64())); + Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int())); if (Object::cast_to<Script>(obj)) { property_select->select_method_from_script(Object::cast_to<Script>(obj), v); } @@ -646,7 +646,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: } else if (hint == PROPERTY_HINT_PROPERTY_OF_INSTANCE) { MAKE_PROPSELECT - Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64())); + Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int())); if (instance) { property_select->select_property_from_instance(instance, v); } @@ -657,7 +657,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: } else if (hint == PROPERTY_HINT_PROPERTY_OF_SCRIPT) { MAKE_PROPSELECT - Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64())); + Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int())); if (Object::cast_to<Script>(obj)) { property_select->select_property_from_script(Object::cast_to<Script>(obj), v); } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index dd42ed9760..9831f1bd31 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -350,17 +350,22 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (!profile_allow_editing) { break; } - String preferred = ""; - Node *current_edited_scene_root = EditorNode::get_singleton()->get_edited_scene(); + // Prefer nodes that inherit from the current scene root. + Node *current_edited_scene_root = EditorNode::get_singleton()->get_edited_scene(); if (current_edited_scene_root) { - if (ClassDB::is_parent_class(current_edited_scene_root->get_class_name(), "Node2D")) { - preferred = "Node2D"; - } else if (ClassDB::is_parent_class(current_edited_scene_root->get_class_name(), "Node3D")) { - preferred = "Node3D"; + static const String preferred_types[] = { "Node2D", "Node3D", "Control" }; + + StringName root_class = current_edited_scene_root->get_class_name(); + + for (int i = 0; i < preferred_types->size(); i++) { + if (ClassDB::is_parent_class(root_class, preferred_types[i])) { + create_dialog->set_preferred_search_result_type(preferred_types[i]); + break; + } } } - create_dialog->set_preferred_search_result_type(preferred); + create_dialog->popup_create(true); } break; case TOOL_INSTANCE: { @@ -736,17 +741,28 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { _delete_confirm(); } else { - if (remove_list.size() >= 2) { - delete_dialog->set_text(vformat(TTR("Delete %d nodes?"), remove_list.size())); - } else if (remove_list.size() == 1 && remove_list[0] == editor_data->get_edited_scene_root()) { - delete_dialog->set_text(vformat(TTR("Delete the root node \"%s\"?"), remove_list[0]->get_name())); - } else if (remove_list.size() == 1 && remove_list[0]->get_filename() == "" && remove_list[0]->get_child_count() >= 1) { - // Display this message only for non-instanced scenes - delete_dialog->set_text(vformat(TTR("Delete node \"%s\" and its children?"), remove_list[0]->get_name())); + String msg; + if (remove_list.size() > 1) { + bool any_children = false; + for (int i = 0; !any_children && i < remove_list.size(); i++) { + any_children = remove_list[i]->get_child_count() > 0; + } + + msg = vformat(any_children ? TTR("Delete %d nodes and any children?") : TTR("Delete %d nodes?"), remove_list.size()); } else { - delete_dialog->set_text(vformat(TTR("Delete node \"%s\"?"), remove_list[0]->get_name())); + Node *node = remove_list[0]; + if (node == editor_data->get_edited_scene_root()) { + msg = vformat(TTR("Delete the root node \"%s\"?"), node->get_name()); + } else if (node->get_filename() == "" && node->get_child_count() > 0) { + // Display this message only for non-instanced scenes + msg = vformat(TTR("Delete node \"%s\" and its children?"), node->get_name()); + } else { + msg = vformat(TTR("Delete node \"%s\"?"), node->get_name()); + } } + delete_dialog->set_text(msg); + // Resize the dialog to its minimum size. // This prevents the dialog from being too wide after displaying // a deletion confirmation for a node with a long name. diff --git a/main/main.cpp b/main/main.cpp index 00760b39b0..76175780a3 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -856,7 +856,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } else if (I->get() == "--allow_focus_steal_pid") { // not exposed to user if (I->next()) { - allow_focus_steal_pid = I->next()->get().to_int64(); + allow_focus_steal_pid = I->next()->get().to_int(); N = I->next()->next(); } else { OS::get_singleton()->print("Missing editor PID argument, aborting.\n"); @@ -1620,7 +1620,7 @@ bool Main::start() { { DirAccessRef da = DirAccess::open(doc_tool); - ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a base Godot build directory."); + ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a valid directory path."); } #ifndef MODULE_MONO_ENABLED @@ -2115,7 +2115,6 @@ bool Main::start() { */ uint64_t Main::last_ticks = 0; -uint64_t Main::target_ticks = 0; uint32_t Main::frames = 0; uint32_t Main::frame = 0; bool Main::force_redraw_requested = false; @@ -2266,38 +2265,7 @@ bool Main::iteration() { return exit; } - const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay(); - if (frame_delay) { - // Add fixed frame delay to decrease CPU/GPU usage. This doesn't take - // the actual frame time into account. - // Due to the high fluctuation of the actual sleep duration, it's not recommended - // to use this as a FPS limiter. - OS::get_singleton()->delay_usec(frame_delay * 1000); - } - - // Add a dynamic frame delay to decrease CPU/GPU usage. This takes the - // previous frame time into account for a smoother result. - uint64_t dynamic_delay = 0; - if (OS::get_singleton()->is_in_low_processor_usage_mode() || !DisplayServer::get_singleton()->window_can_draw()) { - dynamic_delay = OS::get_singleton()->get_low_processor_usage_mode_sleep_usec(); - } - const int target_fps = Engine::get_singleton()->get_target_fps(); - if (target_fps > 0 && !Engine::get_singleton()->is_editor_hint()) { - // Override the low processor usage mode sleep delay if the target FPS is lower. - dynamic_delay = MAX(dynamic_delay, (uint64_t)(1000000 / target_fps)); - } - - if (dynamic_delay > 0) { - target_ticks += dynamic_delay; - uint64_t current_ticks = OS::get_singleton()->get_ticks_usec(); - - if (current_ticks < target_ticks) { - OS::get_singleton()->delay_usec(target_ticks - current_ticks); - } - - current_ticks = OS::get_singleton()->get_ticks_usec(); - target_ticks = MIN(MAX(target_ticks, current_ticks - dynamic_delay), current_ticks + dynamic_delay); - } + OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw()); #ifdef TOOLS_ENABLED if (auto_build_solutions) { diff --git a/main/main.h b/main/main.h index ab6917a65c..308128735c 100644 --- a/main/main.h +++ b/main/main.h @@ -38,7 +38,6 @@ class Main { static void print_help(const char *p_binary); static uint64_t last_ticks; - static uint64_t target_ticks; static uint32_t frames; static uint32_t frame; static bool force_redraw_requested; diff --git a/main/performance.cpp b/main/performance.cpp index 7e6b9fca64..7234511aeb 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -43,6 +43,12 @@ Performance *Performance::singleton = nullptr; void Performance::_bind_methods() { ClassDB::bind_method(D_METHOD("get_monitor", "monitor"), &Performance::get_monitor); + ClassDB::bind_method(D_METHOD("add_custom_monitor", "id", "callable", "arguments"), &Performance::add_custom_monitor, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("remove_custom_monitor", "id"), &Performance::remove_custom_monitor); + ClassDB::bind_method(D_METHOD("has_custom_monitor", "id"), &Performance::has_custom_monitor); + ClassDB::bind_method(D_METHOD("get_custom_monitor", "id"), &Performance::get_custom_monitor); + ClassDB::bind_method(D_METHOD("get_monitor_modification_time"), &Performance::get_monitor_modification_time); + ClassDB::bind_method(D_METHOD("get_custom_monitor_names"), &Performance::get_custom_monitor_names); BIND_ENUM_CONSTANT(TIME_FPS); BIND_ENUM_CONSTANT(TIME_PROCESS); @@ -231,8 +237,78 @@ void Performance::set_physics_process_time(float p_pt) { _physics_process_time = p_pt; } +void Performance::add_custom_monitor(const StringName &p_id, const Callable &p_callable, const Vector<Variant> &p_args) { + ERR_FAIL_COND_MSG(has_custom_monitor(p_id), "Custom monitor with id '" + String(p_id) + "' already exists."); + _monitor_map.insert(p_id, MonitorCall(p_callable, p_args)); + _monitor_modification_time = OS::get_singleton()->get_ticks_usec(); +} + +void Performance::remove_custom_monitor(const StringName &p_id) { + ERR_FAIL_COND_MSG(!has_custom_monitor(p_id), "Custom monitor with id '" + String(p_id) + "' doesn't exists."); + _monitor_map.erase(p_id); + _monitor_modification_time = OS::get_singleton()->get_ticks_usec(); +} + +bool Performance::has_custom_monitor(const StringName &p_id) { + return _monitor_map.has(p_id); +} + +Variant Performance::get_custom_monitor(const StringName &p_id) { + ERR_FAIL_COND_V_MSG(!has_custom_monitor(p_id), Variant(), "Custom monitor with id '" + String(p_id) + "' doesn't exists."); + bool error; + String error_message; + Variant return_value = _monitor_map[p_id].call(error, error_message); + ERR_FAIL_COND_V_MSG(error, return_value, "Error calling from custom monitor '" + String(p_id) + "' to callable: " + error_message); + return return_value; +} + +Array Performance::get_custom_monitor_names() { + if (!_monitor_map.size()) { + return Array(); + } + Array return_array; + return_array.resize(_monitor_map.size()); + int index = 0; + for (OrderedHashMap<StringName, MonitorCall>::Element i = _monitor_map.front(); i; i = i.next()) { + return_array.set(index, i.key()); + index++; + } + return return_array; +} + +uint64_t Performance::get_monitor_modification_time() { + return _monitor_modification_time; +} + Performance::Performance() { _process_time = 0; _physics_process_time = 0; + _monitor_modification_time = 0; singleton = this; } + +Performance::MonitorCall::MonitorCall(Callable p_callable, Vector<Variant> p_arguments) { + _callable = p_callable; + _arguments = p_arguments; +} + +Performance::MonitorCall::MonitorCall() { +} + +Variant Performance::MonitorCall::call(bool &r_error, String &r_error_message) { + Vector<const Variant *> arguments_mem; + arguments_mem.resize(_arguments.size()); + for (int i = 0; i < _arguments.size(); i++) { + arguments_mem.write[i] = &_arguments[i]; + } + const Variant **args = (const Variant **)arguments_mem.ptr(); + int argc = _arguments.size(); + Variant return_value; + Callable::CallError error; + _callable.call(args, argc, return_value, error); + r_error = (error.error != Callable::CallError::CALL_OK); + if (r_error) { + r_error_message = Variant::get_callable_error_text(_callable, args, argc, error); + } + return return_value; +} diff --git a/main/performance.h b/main/performance.h index ddbe45fa00..5f88a24c0f 100644 --- a/main/performance.h +++ b/main/performance.h @@ -32,6 +32,7 @@ #define PERFORMANCE_H #include "core/object.h" +#include "core/ordered_hash_map.h" #define PERF_WARN_OFFLINE_FUNCTION #define PERF_WARN_PROCESS_SYNC @@ -47,6 +48,19 @@ class Performance : public Object { float _process_time; float _physics_process_time; + class MonitorCall { + Callable _callable; + Vector<Variant> _arguments; + + public: + MonitorCall(Callable p_callable, Vector<Variant> p_arguments); + MonitorCall(); + Variant call(bool &r_error, String &r_error_message); + }; + + OrderedHashMap<StringName, MonitorCall> _monitor_map; + uint64_t _monitor_modification_time; + public: enum Monitor { @@ -95,6 +109,14 @@ public: void set_process_time(float p_pt); void set_physics_process_time(float p_pt); + void add_custom_monitor(const StringName &p_id, const Callable &p_callable, const Vector<Variant> &p_args); + void remove_custom_monitor(const StringName &p_id); + bool has_custom_monitor(const StringName &p_id); + Variant get_custom_monitor(const StringName &p_id); + Array get_custom_monitor_names(); + + uint64_t get_monitor_modification_time(); + static Performance *get_singleton() { return singleton; } Performance(); diff --git a/main/tests/test_string.cpp b/main/tests/test_string.cpp index 775c039282..5a14492be5 100644 --- a/main/tests/test_string.cpp +++ b/main/tests/test_string.cpp @@ -370,7 +370,7 @@ bool test_22() { static const int num[4] = { 1237461283, -22, 0, -1123412 }; for (int i = 0; i < 4; i++) { - OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n", nums[i], String(nums[i]).to_int()); + OS::get_singleton()->print("\tString: \"%s\" as Int is %lli\n", nums[i], (long long)(String(nums[i]).to_int())); if (String(nums[i]).to_int() != num[i]) { return false; diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index d0c9bf5d38..6c0a3a4ca3 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -523,7 +523,7 @@ void CSGBrushOperation::MeshMerge::_add_distance(List<real_t> &r_intersectionsA, // Check if distance exists. for (const List<real_t>::Element *E = intersections.front(); E; E = E->next()) { - if (Math::abs(**E - p_distance) < vertex_snap) { + if (Math::is_equal_approx(**E, p_distance)) { return; } } @@ -1068,15 +1068,6 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s break; } - // Don't create degenerate triangles. - Vector2 split_edge1[2] = { vertices[new_vertex_idx].point, edge_points[0] }; - Vector2 split_edge2[2] = { vertices[new_vertex_idx].point, edge_points[1] }; - Vector2 new_edge[2] = { vertices[new_vertex_idx].point, vertices[opposite_vertex_idx].point }; - if (are_segements_parallel(split_edge1, new_edge, vertex_snap2) && - are_segements_parallel(split_edge2, new_edge, vertex_snap2)) { - break; - } - // If opposite point is on the segemnt, add its index to segment indices too. Vector2 closest_point = Geometry2D::get_closest_point_to_segment(vertices[opposite_vertex_idx].point, p_segment_points); if ((closest_point - vertices[opposite_vertex_idx].point).length_squared() < vertex_snap2) { diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 724a4b56cb..f89f647aca 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -613,19 +613,19 @@ int64_t GDAPI godot_string_char_to_int64_with_len(const wchar_t *p_str, int p_le int64_t GDAPI godot_string_hex_to_int64(const godot_string *p_self) { const String *self = (const String *)p_self; - return self->hex_to_int64(false); + return self->hex_to_int(false); } int64_t GDAPI godot_string_hex_to_int64_with_prefix(const godot_string *p_self) { const String *self = (const String *)p_self; - return self->hex_to_int64(); + return self->hex_to_int(); } int64_t GDAPI godot_string_to_int64(const godot_string *p_self) { const String *self = (const String *)p_self; - return self->to_int64(); + return self->to_int(); } double GDAPI godot_string_unicode_char_to_double(const wchar_t *p_str, const wchar_t **r_end) { diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 06b9534fce..94aa2125c2 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -1853,7 +1853,7 @@ void NativeReloadNode::_notification(int p_what) { #ifdef TOOLS_ENABLED switch (p_what) { - case NOTIFICATION_WM_FOCUS_OUT: { + case NOTIFICATION_APPLICATION_FOCUS_OUT: { if (unloaded) { break; } @@ -1887,7 +1887,7 @@ void NativeReloadNode::_notification(int p_what) { } break; - case NOTIFICATION_WM_FOCUS_IN: { + case NOTIFICATION_APPLICATION_FOCUS_IN: { if (!unloaded) { break; } diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index 9d9c5b6473..fe7c10cad9 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -214,6 +214,11 @@ void VideoStreamPlaybackGDNative::cleanup() { if (pcm) { memfree(pcm); } + if (file) { + file->close(); + memdelete(file); + file = nullptr; + } pcm = nullptr; time = 0; num_channels = -1; diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index be159b6407..f04cb4b4c3 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -619,11 +619,11 @@ <argument index="0" name="path" type="String"> </argument> <description> - Loads a resource from the filesystem located at [code]path[/code]. - [b]Note:[/b] Resource paths can be obtained by right-clicking on a resource in the FileSystem dock and choosing [b]Copy Path[/b]. + Loads a resource from the filesystem located at [code]path[/code]. The resource is loaded on the method call (unless it's referenced already elsewhere, e.g. in another script or in the scene), which might cause slight delay, especially when loading scenes. To avoid unnecessary delays when loading something multiple times, either store the resource in a variable or use [method preload]. + [b]Note:[/b] Resource paths can be obtained by right-clicking on a resource in the FileSystem dock and choosing "Copy Path" or by dragging the file from the FileSystem dock into the script. [codeblock] - # Load a scene called main located in the root of the project directory. - var main = load("res://main.tscn") + # Load a scene called main located in the root of the project directory and cache it in a variable. + var main = load("res://main.tscn") # main will contain a PackedScene resource. [/codeblock] [b]Important:[/b] The path must be absolute, a local path will just return [code]null[/code]. </description> @@ -797,11 +797,11 @@ <argument index="0" name="path" type="String"> </argument> <description> - Returns a resource from the filesystem that is loaded during script parsing. - [b]Note:[/b] Resource paths can be obtained by right clicking on a resource in the Assets Panel and choosing "Copy Path". + Returns a [Resource] from the filesystem located at [code]path[/code]. The resource is loaded during script parsing, i.e. is loaded with the script and [method preload] effectively acts as a reference to that resource. Note that the method requires a constant path. If you want to load a resource from a dynamic/variable path, use [method load]. + [b]Note:[/b] Resource paths can be obtained by right clicking on a resource in the Assets Panel and choosing "Copy Path" or by dragging the file from the FileSystem dock into the script. [codeblock] - # Load a scene called main located in the root of the project directory. - var main = preload("res://main.tscn") + # Instance a scene. + var diamond = preload("res://diamond.tscn").instance() [/codeblock] </description> </method> diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 2db42601c6..82def3f877 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -952,16 +952,16 @@ void GDScriptTokenizerText::_advance() { INCPOS(i); if (hexa_found) { - int64_t val = str.hex_to_int64(); + int64_t val = str.hex_to_int(); _make_constant(val); } else if (bin_found) { - int64_t val = str.bin_to_int64(); + int64_t val = str.bin_to_int(); _make_constant(val); } else if (period_found || exponent_found) { double val = str.to_double(); _make_constant(val); } else { - int64_t val = str.to_int64(); + int64_t val = str.to_int(); _make_constant(val); } diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs index ae05710f4f..b30c857c64 100644 --- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs +++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs @@ -10,7 +10,7 @@ namespace GodotTools public override void _Notification(int what) { - if (what == Node.NotificationWmFocusIn) + if (what == Node.NotificationWmWindowFocusIn) { RestartTimer(); diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index ce889a4928..1475d24792 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -30,6 +30,8 @@ #include "image_loader_tga.h" +#include "core/error_macros.h" +#include "core/io/file_access_memory.h" #include "core/os/os.h" #include "core/print_string.h" @@ -311,5 +313,17 @@ void ImageLoaderTGA::get_recognized_extensions(List<String> *p_extensions) const p_extensions->push_back("tga"); } +static Ref<Image> _tga_mem_loader_func(const uint8_t *p_png, int p_size) { + FileAccessMemory memfile; + Error open_memfile_error = memfile.open_custom(p_png, p_size); + ERR_FAIL_COND_V_MSG(open_memfile_error, Ref<Image>(), "Could not create memfile for TGA image buffer."); + Ref<Image> img; + img.instance(); + Error load_error = ImageLoaderTGA().load_image(img, &memfile, false, 1.0f); + ERR_FAIL_COND_V_MSG(load_error, Ref<Image>(), "Failed to load TGA image."); + return img; +} + ImageLoaderTGA::ImageLoaderTGA() { + Image::_tga_mem_loader_func = _tga_mem_loader_func; } diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index a663a847c2..2f6f483edf 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -862,6 +862,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { String tname = string_table[name]; uint32_t attrcount = decode_uint32(&p_manifest[iofs + 20]); iofs += 28; + bool is_focus_aware_metadata = false; for (uint32_t i = 0; i < attrcount; i++) { uint32_t attr_nspace = decode_uint32(&p_manifest[iofs]); @@ -929,9 +930,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } } - if (tname == "meta-data" && attrname == "value" && value == "oculus_focus_aware_value") { + if (tname == "meta-data" && attrname == "value" && is_focus_aware_metadata) { // Update the focus awareness meta-data value - string_table.write[attr_value] = xr_mode_index == /* XRMode.OVR */ 1 && focus_awareness ? "true" : "false"; + encode_uint32(xr_mode_index == /* XRMode.OVR */ 1 && focus_awareness ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); } if (tname == "meta-data" && attrname == "value" && value == "plugins_value" && !plugins_names.empty()) { @@ -939,6 +940,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { string_table.write[attr_value] = plugins_names; } + is_focus_aware_metadata = tname == "meta-data" && attrname == "name" && value == "com.oculus.vr.focusaware"; iofs += 20; } diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index dbf1dc0f3c..48c09552c1 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -45,8 +45,8 @@ android:resizeableActivity="false" tools:ignore="UnusedAttribute" > - <!-- Focus awareness metadata populated at export time if the user enables it in the 'Xr Features' section. --> - <meta-data android:name="com.oculus.vr.focusaware" android:value="oculus_focus_aware_value" /> + <!-- Focus awareness metadata is updated at export time if the user enables it in the 'Xr Features' section. --> + <meta-data android:name="com.oculus.vr.focusaware" android:value="false" /> <intent-filter> <action android:name="android.intent.action.MAIN" /> diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index a032ae8d2c..4610b94363 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -457,7 +457,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNI return; if (os_android->get_main_loop()) { - os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APP_RESUMED); + os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_RESUMED); } } @@ -466,7 +466,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererPaused(JNIE return; if (os_android->get_main_loop()) { - os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APP_PAUSED); + os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_PAUSED); } } } diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index a0954600a2..cb4b0d745b 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -32,12 +32,12 @@ #ifdef X11_ENABLED -#include "detect_prime_x11.h" - -#include "core/os/dir_access.h" #include "core/print_string.h" -#include "errno.h" +#include "core/project_settings.h" +#include "detect_prime_x11.h" #include "key_mapping_x11.h" +#include "main/main.h" +#include "scene/resources/texture.h" #if defined(OPENGL_ENABLED) #include "drivers/gles2/rasterizer_gles2.h" @@ -47,20 +47,14 @@ #include "servers/rendering/rasterizer_rd/rasterizer_rd.h" #endif -#include "scene/resources/texture.h" - -#ifdef HAVE_MNTENT -#include <mntent.h> -#endif - #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "X11/Xutil.h" +#include <X11/Xatom.h> +#include <X11/Xutil.h> +#include <X11/extensions/Xinerama.h> -#include "X11/Xatom.h" -#include "X11/extensions/Xinerama.h" // ICCCM #define WM_NormalState 1L // window normal state #define WM_IconicState 3L // window minimized @@ -69,8 +63,6 @@ #define _NET_WM_STATE_ADD 1L // add/set property #define _NET_WM_STATE_TOGGLE 2L // toggle property -#include "main/main.h" - #include <dlfcn.h> #include <fcntl.h> #include <sys/stat.h> @@ -82,14 +74,9 @@ #undef KEY_TAB #endif -#include <X11/Xatom.h> - #undef CursorShape - #include <X11/XKBlib.h> -#include "core/project_settings.h" - // 2.2 is the first release with multitouch #define XINPUT_CLIENT_VERSION_MAJOR 2 #define XINPUT_CLIENT_VERSION_MINOR 2 @@ -417,10 +404,6 @@ void DisplayServerX11::mouse_warp_to_position(const Point2i &p_to) { if (mouse_mode == MOUSE_MODE_CAPTURED) { last_mouse_pos = p_to; } else { - /*XWindowAttributes xwa; - XGetWindowAttributes(x11_display, x11_window, &xwa); - printf("%d %d\n", xwa.x, xwa.y); needed? */ - XWarpPointer(x11_display, None, windows[MAIN_WINDOW_ID].x11_window, 0, 0, 0, 0, (int)p_to.x, (int)p_to.y); } @@ -1098,18 +1081,19 @@ Size2i DisplayServerX11::window_get_real_size(WindowID p_window) const { return Size2i(w, h); } -bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const { - _THREAD_SAFE_METHOD_ - +// Just a helper to reduce code duplication in `window_is_maximize_allowed` +// and `_set_wm_maximized`. +bool DisplayServerX11::_window_maximize_check(WindowID p_window, const char *p_atom_name) const { ERR_FAIL_COND_V(!windows.has(p_window), false); const WindowData &wd = windows[p_window]; - Atom property = XInternAtom(x11_display, "_NET_WM_ALLOWED_ACTIONS", False); + Atom property = XInternAtom(x11_display, p_atom_name, False); Atom type; int format; unsigned long len; unsigned long remaining; unsigned char *data = nullptr; + bool retval = false; int result = XGetWindowProperty( x11_display, @@ -1141,13 +1125,20 @@ bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const { } if (found_wm_act_max_horz || found_wm_act_max_vert) { - return true; + retval = true; + break; } } - XFree(atoms); + + XFree(data); } - return false; + return retval; +} + +bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + return _window_maximize_check(p_window, "_NET_WM_ALLOWED_ACTIONS"); } void DisplayServerX11::_set_wm_maximized(WindowID p_window, bool p_enabled) { @@ -1385,60 +1376,14 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c if (wd.fullscreen) { //if fullscreen, it's not in another mode return WINDOW_MODE_FULLSCREEN; } - { //test maximized - // Using EWMH -- Extended Window Manager Hints - Atom property = XInternAtom(x11_display, "_NET_WM_STATE", False); - Atom type; - int format; - unsigned long len; - unsigned long remaining; - unsigned char *data = nullptr; - bool retval = false; - - int result = XGetWindowProperty( - x11_display, - wd.x11_window, - property, - 0, - 1024, - False, - XA_ATOM, - &type, - &format, - &len, - &remaining, - &data); - - if (result == Success && data) { - Atom *atoms = (Atom *)data; - Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); - Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); - bool found_wm_max_horz = false; - bool found_wm_max_vert = false; - - for (uint64_t i = 0; i < len; i++) { - if (atoms[i] == wm_max_horz) { - found_wm_max_horz = true; - } - if (atoms[i] == wm_max_vert) { - found_wm_max_vert = true; - } - - if (found_wm_max_horz && found_wm_max_vert) { - retval = true; - break; - } - } - XFree(data); - } - - if (retval) { - return WINDOW_MODE_MAXIMIZED; - } + // Test maximized. + // Using EWMH -- Extended Window Manager Hints + if (_window_maximize_check(p_window, "_NET_WM_STATE")) { + return WINDOW_MODE_MAXIMIZED; } - { // test minimzed + { // Test minimized. // Using ICCCM -- Inter-Client Communication Conventions Manual Atom property = XInternAtom(x11_display, "WM_STATE", True); Atom type; @@ -1471,7 +1416,7 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c } } - // all other discarded, return windowed. + // All other discarded, return windowed. return WINDOW_MODE_WINDOWED; } @@ -2394,6 +2339,24 @@ void DisplayServerX11::_send_window_event(const WindowData &wd, WindowEvent p_ev void DisplayServerX11::process_events() { _THREAD_SAFE_METHOD_ + if (app_focused) { + //verify that one of the windows has focus, else send focus out notification + bool focus_found = false; + for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { + if (E->get().focused) { + focus_found = true; + } + } + + if (!focus_found) { + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); + } + + app_focused = false; + } + } + do_mouse_warp = false; // Is the current mouse mode one where it needs to be grabbed. @@ -2588,12 +2551,12 @@ void DisplayServerX11::process_events() { break; case NoExpose: - minimized = true; + windows[window_id].minimized = true; break; case VisibilityNotify: { XVisibilityEvent *visibility = (XVisibilityEvent *)&event; - minimized = (visibility->state == VisibilityFullyObscured); + windows[window_id].minimized = (visibility->state == VisibilityFullyObscured); } break; case LeaveNotify: { if (!mouse_mode_grab) { @@ -2607,10 +2570,8 @@ void DisplayServerX11::process_events() { } } break; case FocusIn: - minimized = false; - window_has_focus = true; + windows[window_id].focused = true; _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN); - window_focused = true; if (mouse_mode_grab) { // Show and update the cursor if confined and the window regained focus. @@ -2637,13 +2598,19 @@ void DisplayServerX11::process_events() { if (windows[window_id].xic) { XSetICFocus(windows[window_id].xic); } + + if (!app_focused) { + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); + } + app_focused = true; + } break; case FocusOut: - window_has_focus = false; + windows[window_id].focused = false; Input::get_singleton()->release_pressed_events(); _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT); - window_focused = false; if (mouse_mode_grab) { for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { @@ -2782,7 +2749,7 @@ void DisplayServerX11::process_events() { Point2i new_center = pos; pos = last_mouse_pos + xi.relative_motion; center = new_center; - do_mouse_warp = window_has_focus; // warp the cursor if we're focused in + do_mouse_warp = windows[window_id].focused; // warp the cursor if we're focused in } if (!last_mouse_pos_valid) { @@ -2842,7 +2809,7 @@ void DisplayServerX11::process_events() { // Don't propagate the motion event unless we have focus // this is so that the relative motion doesn't get messed up // after we regain focus. - if (window_has_focus || !mouse_mode_grab) { + if (windows[window_id].focused || !mouse_mode_grab) { Input::get_singleton()->accumulate_input_event(mm); } @@ -3819,8 +3786,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode requested = None; - window_has_focus = true; // Set focus to true at init - /*if (p_desired.layered) { set_window_per_pixel_transparency_enabled(true); }*/ diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index f01b9a2323..3d0b2c7e8a 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -36,7 +36,6 @@ #include "servers/display_server.h" #include "core/input/input.h" - #include "drivers/alsa/audio_driver_alsa.h" #include "drivers/alsamidi/midi_driver_alsamidi.h" #include "drivers/pulseaudio/audio_driver_pulseaudio.h" @@ -140,6 +139,8 @@ class DisplayServerX11 : public DisplayServer { bool borderless = false; bool resize_disabled = false; Vector2i last_position_before_fs; + bool focused = false; + bool minimized = false; }; Map<WindowID, WindowData> windows; @@ -165,6 +166,7 @@ class DisplayServerX11 : public DisplayServer { uint64_t last_click_ms; int last_click_button_index; uint32_t last_button_state; + bool app_focused = false; struct { int opcode; @@ -196,8 +198,8 @@ class DisplayServerX11 : public DisplayServer { void _handle_key_event(WindowID p_window, XKeyEvent *p_event, bool p_echo = false); - bool minimized; - bool window_has_focus; + //bool minimized; + //bool window_has_focus; bool do_mouse_warp; const char *cursor_theme; @@ -211,7 +213,7 @@ class DisplayServerX11 : public DisplayServer { bool layered_window; String rendering_driver; - bool window_focused; + //bool window_focused; //void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); void set_wm_above(bool p_enabled); @@ -231,6 +233,7 @@ class DisplayServerX11 : public DisplayServer { static Property _read_property(Display *p_display, Window p_window, Atom p_property); void _update_real_mouse_position(const WindowData &wd); + bool _window_maximize_check(WindowID p_window, const char *p_atom_name) const; void _set_wm_fullscreen(WindowID p_window, bool p_enabled); void _set_wm_maximized(WindowID p_window, bool p_enabled); diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 09a5eca914..8c6f3b1167 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -31,8 +31,11 @@ #include "os_linuxbsd.h" #include "core/os/dir_access.h" -#include "core/print_string.h" -#include "errno.h" +#include "main/main.h" + +#ifdef X11_ENABLED +#include "display_server_x11.h" +#endif #ifdef HAVE_MNTENT #include <mntent.h> @@ -48,12 +51,6 @@ #include <sys/types.h> #include <unistd.h> -#include "main/main.h" - -#ifdef X11_ENABLED -#include "display_server_x11.h" -#endif - void OS_LinuxBSD::initialize() { crash_handler.initialize(); diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index fddb1d0ca6..ac419a821c 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -220,7 +220,7 @@ public: virtual Vector<int> get_window_list() const; - virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i & = Rect2i()); + virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()); virtual void delete_sub_window(WindowID p_id); virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID); diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 920fd24c4a..93f6e3540a 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -197,6 +197,18 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { } } +- (void)applicationDidResignActive:(NSNotification *)notification { + if (OS_OSX::get_singleton()->get_main_loop()) { + OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); + } +} + +- (void)applicationDidBecomeActive:(NSNotification *)notification { + if (OS_OSX::get_singleton()->get_main_loop()) { + OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); + } +} + - (void)globalMenuCallback:(id)sender { if (![sender representedObject]) return; diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 9af7c02351..916816325d 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -825,14 +825,15 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String zipfi.tmz_date.tm_hour = time.hour; zipfi.tmz_date.tm_mday = date.day; zipfi.tmz_date.tm_min = time.min; - zipfi.tmz_date.tm_mon = date.month; + zipfi.tmz_date.tm_mon = date.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, http://www.cplusplus.com/reference/ctime/tm/ zipfi.tmz_date.tm_sec = time.sec; zipfi.tmz_date.tm_year = date.year; zipfi.dosDate = 0; // 0100000: regular file type // 0000755: permissions rwxr-xr-x // 0000644: permissions rw-r--r-- - zipfi.external_fa = (is_executable ? 0100755 : 0100644) << 16L; + uint32_t _mode = (is_executable ? 0100755 : 0100644); + zipfi.external_fa = (_mode << 16L) | !(_mode & 0200); zipfi.internal_fa = 0; zipOpenNewFileInZip4(p_zip, diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index f47afcc4e5..61dc156fbc 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1790,6 +1790,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA // Restore mouse mode _set_mouse_mode_impl(mouse_mode); + if (!app_focused) { + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); + } + app_focused = true; + } break; } case WM_KILLFOCUS: { @@ -1805,6 +1811,19 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } touch_state.clear(); + bool self_steal = false; + HWND new_hwnd = (HWND)wParam; + if (IsWindow(new_hwnd)) { + self_steal = true; + } + + if (!self_steal) { + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); + } + app_focused = false; + } + break; } case WM_ACTIVATE: // Watch For Window Activate Message diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 995ced0809..8433bb449b 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -317,6 +317,7 @@ private: int pressrc; HINSTANCE hInstance; // Holds The Instance Of The Application String rendering_driver; + bool app_focused = false; struct WindowData { HWND hWnd; diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 5020940c5c..9fd24b5294 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -325,8 +325,7 @@ void RayCast2D::_bind_methods() { } RayCast2D::RayCast2D() { - enabled = false; - + enabled = true; collided = false; against_shape = 0; collision_mask = 1; diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 689afa5608..ecbaca7bd1 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -35,6 +35,7 @@ #include "core/math/camera_matrix.h" #include "scene/resources/material.h" #include "scene/resources/surface_tool.h" + void Camera3D::_update_audio_listener_state() { } diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index 138b1b8a7a..5c9431e08a 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -34,6 +34,7 @@ #include "scene/3d/node_3d.h" #include "scene/3d/velocity_tracker_3d.h" #include "scene/main/window.h" +#include "scene/resources/camera_effects.h" #include "scene/resources/environment.h" class Camera3D : public Node3D { diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 09fc81b216..71df1b5ded 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef LIGHT_H -#define LIGHT_H +#ifndef LIGHT_3D_H +#define LIGHT_3D_H #include "scene/3d/visual_instance_3d.h" #include "scene/resources/texture.h" @@ -145,7 +145,7 @@ public: enum ShadowMode { SHADOW_ORTHOGONAL, SHADOW_PARALLEL_2_SPLITS, - SHADOW_PARALLEL_4_SPLITS + SHADOW_PARALLEL_4_SPLITS, }; enum ShadowDepthRange { @@ -217,4 +217,4 @@ public: Light3D(RenderingServer::LIGHT_SPOT) {} }; -#endif +#endif // LIGHT_3D_H diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index 68f4b3132c..2a922e3cda 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -383,8 +383,7 @@ void RayCast3D::_clear_debug_shape() { } RayCast3D::RayCast3D() { - enabled = false; - + enabled = true; collided = false; against_shape = 0; collision_mask = 1; diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index 24071f31f3..5e73e460ed 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "world_environment.h" + #include "scene/main/window.h" void WorldEnvironment::_notification(int p_what) { diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h index ddb2af7bd3..4a0dbd35a3 100644 --- a/scene/3d/world_environment.h +++ b/scene/3d/world_environment.h @@ -32,6 +32,8 @@ #define SCENARIO_FX_H #include "scene/3d/node_3d.h" +#include "scene/resources/camera_effects.h" +#include "scene/resources/environment.h" class WorldEnvironment : public Node { GDCLASS(WorldEnvironment, Node); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index c6897fc684..bacc65c7bf 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -51,7 +51,9 @@ void AcceptDialog::_input_from_window(const Ref<InputEvent> &p_event) { } void AcceptDialog::_parent_focused() { - _cancel_pressed(); + if (!is_exclusive()) { + _cancel_pressed(); + } } void AcceptDialog::_notification(int p_what) { @@ -295,6 +297,7 @@ AcceptDialog::AcceptDialog() { set_wrap_controls(true); set_visible(false); set_transient(true); + set_exclusive(true); bg = memnew(Panel); add_child(bg); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index ba55927980..251f31ce4e 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -688,12 +688,12 @@ void LineEdit::_notification(int p_what) { update_placeholder_width(); update(); } break; - case NOTIFICATION_WM_FOCUS_IN: { + case NOTIFICATION_WM_WINDOW_FOCUS_IN: { window_has_focus = true; draw_caret = true; update(); } break; - case NOTIFICATION_WM_FOCUS_OUT: { + case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { window_has_focus = false; draw_caret = false; update(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index c7fc8dbe43..3860ce61e9 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -603,12 +603,12 @@ void TextEdit::_notification(int p_what) { _update_wrap_at(); syntax_highlighting_cache.clear(); } break; - case NOTIFICATION_WM_FOCUS_IN: { + case NOTIFICATION_WM_WINDOW_FOCUS_IN: { window_has_focus = true; draw_caret = true; update(); } break; - case NOTIFICATION_WM_FOCUS_OUT: { + case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { window_has_focus = false; draw_caret = false; update(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 7b9db7c081..34161a9e80 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3410,7 +3410,7 @@ void Tree::scroll_to_item(TreeItem *p_item) { const Rect2 r = get_item_rect(p_item); - if (r.position.y < v_scroll->get_value()) { + if (r.position.y <= v_scroll->get_value()) { v_scroll->set_value(r.position.y); } else if (r.position.y + r.size.y + 2 * cache.vseparation > v_scroll->get_value() + get_size().y) { v_scroll->set_value(r.position.y + r.size.y + 2 * cache.vseparation - get_size().y); diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index 881df06d8f..e118cb0d8d 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -201,10 +201,9 @@ bool VideoPlayer::has_expand() const { void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) { stop(); + AudioServer::get_singleton()->lock(); mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size()); - AudioServer::get_singleton()->unlock(); - stream = p_stream; if (stream.is_valid()) { stream->set_audio_track(audio_track); @@ -212,6 +211,7 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) { } else { playback = Ref<VideoStreamPlayback>(); } + AudioServer::get_singleton()->unlock(); if (!playback.is_null()) { playback->set_loop(loops); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 1bf828a03b..88f9730f78 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2857,8 +2857,8 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER); BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT); - BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN); - BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT); + BIND_CONSTANT(NOTIFICATION_WM_WINDOW_FOCUS_IN); + BIND_CONSTANT(NOTIFICATION_WM_WINDOW_FOCUS_OUT); BIND_CONSTANT(NOTIFICATION_WM_CLOSE_REQUEST); BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST); BIND_CONSTANT(NOTIFICATION_WM_SIZE_CHANGED); @@ -2867,8 +2867,10 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_WM_ABOUT); BIND_CONSTANT(NOTIFICATION_CRASH); BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE); - BIND_CONSTANT(NOTIFICATION_APP_RESUMED); - BIND_CONSTANT(NOTIFICATION_APP_PAUSED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_RESUMED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_PAUSED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_IN); + BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT); BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT); BIND_ENUM_CONSTANT(PAUSE_MODE_STOP); diff --git a/scene/main/node.h b/scene/main/node.h index 7595aabd9a..c3972e2d8e 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -243,8 +243,8 @@ public: NOTIFICATION_WM_MOUSE_ENTER = 1002, NOTIFICATION_WM_MOUSE_EXIT = 1003, - NOTIFICATION_WM_FOCUS_IN = 1004, - NOTIFICATION_WM_FOCUS_OUT = 1005, + NOTIFICATION_WM_WINDOW_FOCUS_IN = 1004, + NOTIFICATION_WM_WINDOW_FOCUS_OUT = 1005, NOTIFICATION_WM_CLOSE_REQUEST = 1006, NOTIFICATION_WM_GO_BACK_REQUEST = 1007, NOTIFICATION_WM_SIZE_CHANGED = 1008, @@ -255,8 +255,10 @@ public: NOTIFICATION_WM_ABOUT = MainLoop::NOTIFICATION_WM_ABOUT, NOTIFICATION_CRASH = MainLoop::NOTIFICATION_CRASH, NOTIFICATION_OS_IME_UPDATE = MainLoop::NOTIFICATION_OS_IME_UPDATE, - NOTIFICATION_APP_RESUMED = MainLoop::NOTIFICATION_APP_RESUMED, - NOTIFICATION_APP_PAUSED = MainLoop::NOTIFICATION_APP_PAUSED + NOTIFICATION_APPLICATION_RESUMED = MainLoop::NOTIFICATION_APPLICATION_RESUMED, + NOTIFICATION_APPLICATION_PAUSED = MainLoop::NOTIFICATION_APPLICATION_PAUSED, + NOTIFICATION_APPLICATION_FOCUS_IN = MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN, + NOTIFICATION_APPLICATION_FOCUS_OUT = MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT }; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 3c3c7533a3..a418883506 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -587,9 +587,11 @@ void SceneTree::_notification(int p_notification) { case NOTIFICATION_OS_IME_UPDATE: case NOTIFICATION_WM_ABOUT: case NOTIFICATION_CRASH: - case NOTIFICATION_APP_RESUMED: - case NOTIFICATION_APP_PAUSED: { - get_root()->propagate_notification(p_notification); + case NOTIFICATION_APPLICATION_RESUMED: + case NOTIFICATION_APPLICATION_PAUSED: + case NOTIFICATION_APPLICATION_FOCUS_IN: + case NOTIFICATION_APPLICATION_FOCUS_OUT: { + get_root()->propagate_notification(p_notification); //pass these to nodes, since they are mirrored } break; default: diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 606f39370b..0d5d222f5e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -815,7 +815,7 @@ void Viewport::_notification(int p_what) { } break; case NOTIFICATION_WM_MOUSE_EXIT: - case NOTIFICATION_WM_FOCUS_OUT: { + case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { _drop_physics_mouseover(); if (gui.mouse_focus && !gui.forced_mouse_focus) { @@ -2913,6 +2913,10 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) { return; } + if (!_can_consume_input_events()) { + return; + } + if (!is_input_handled()) { get_tree()->_call_input_pause(input_group, "_input", ev, this); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input } @@ -2926,7 +2930,7 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) { void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) { ERR_FAIL_COND(!is_inside_tree()); - if (disable_input) { + if (disable_input || !_can_consume_input_events()) { return; } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 11fe4f00d2..d45b321f73 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -441,6 +441,8 @@ private: bool _sub_windows_forward_input(const Ref<InputEvent> &p_event); SubWindowResize _sub_window_get_resize_margin(Window *p_subwindow, const Point2 &p_point); + virtual bool _can_consume_input_events() const { return true; } + protected: void _set_size(const Size2i &p_size, const Size2i &p_size_2d_override, const Rect2i &p_to_screen_rect, const Transform2D &p_stretch_transform, bool p_allocated); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index a9be8a1eff..8604bb78ac 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -316,13 +316,13 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) { } break; case DisplayServer::WINDOW_EVENT_FOCUS_IN: { focused = true; - _propagate_window_notification(this, NOTIFICATION_WM_FOCUS_IN); + _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_IN); emit_signal("focus_entered"); } break; case DisplayServer::WINDOW_EVENT_FOCUS_OUT: { focused = false; - _propagate_window_notification(this, NOTIFICATION_WM_FOCUS_OUT); + _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_OUT); emit_signal("focus_exited"); } break; case DisplayServer::WINDOW_EVENT_CLOSE_REQUEST: { @@ -398,6 +398,18 @@ void Window::set_visible(bool p_visible) { emit_signal(SceneStringNames::get_singleton()->visibility_changed); RS::get_singleton()->viewport_set_active(get_viewport_rid(), visible); + + //update transient exclusive + if (transient_parent) { + if (exclusive && visible) { + ERR_FAIL_COND_MSG(transient_parent->exclusive_child && transient_parent->exclusive_child != this, "Transient parent has another exclusive child."); + transient_parent->exclusive_child = this; + } else { + if (transient_parent->exclusive_child == this) { + transient_parent->exclusive_child = nullptr; + } + } + } } void Window::_clear_transient() { @@ -862,6 +874,10 @@ void Window::child_controls_changed() { call_deferred("_update_child_controls"); } +bool Window::_can_consume_input_events() const { + return exclusive_child == nullptr; +} + void Window::_window_input(const Ref<InputEvent> &p_ev) { if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev))) { return; //avoid joy input on editor @@ -878,10 +894,13 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) { if (exclusive_child != nullptr) { exclusive_child->grab_focus(); - return; //has an exclusive child, can't get events until child is closed + if (!is_embedding_subwindows()) { //not embedding, no need for event + return; + } } emit_signal(SceneStringNames::get_singleton()->window_input, p_ev); + input(p_ev); if (!is_input_handled()) { unhandled_input(p_ev); diff --git a/scene/main/window.h b/scene/main/window.h index adaa5ca3be..89c94753da 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -130,6 +130,7 @@ private: void _window_drop_files(const Vector<String> &p_files); void _rect_changed_callback(const Rect2i &p_callback); void _event_callback(DisplayServer::WindowEvent p_event); + virtual bool _can_consume_input_events() const; protected: Viewport *_get_embedder() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 54112ef2bd..86ea0406e1 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -131,6 +131,7 @@ #include "scene/resources/audio_stream_sample.h" #include "scene/resources/bit_map.h" #include "scene/resources/box_shape_3d.h" +#include "scene/resources/camera_effects.h" #include "scene/resources/capsule_shape_2d.h" #include "scene/resources/capsule_shape_3d.h" #include "scene/resources/circle_shape_2d.h" diff --git a/scene/resources/camera_effects.cpp b/scene/resources/camera_effects.cpp new file mode 100644 index 0000000000..6b6ed51ed0 --- /dev/null +++ b/scene/resources/camera_effects.cpp @@ -0,0 +1,197 @@ +/*************************************************************************/ +/* camera_effects.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "camera_effects.h" + +#include "servers/rendering_server.h" + +RID CameraEffects::get_rid() const { + return camera_effects; +} + +// DOF blur + +void CameraEffects::set_dof_blur_far_enabled(bool p_enabled) { + dof_blur_far_enabled = p_enabled; + _update_dof_blur(); + _change_notify(); +} + +bool CameraEffects::is_dof_blur_far_enabled() const { + return dof_blur_far_enabled; +} + +void CameraEffects::set_dof_blur_far_distance(float p_distance) { + dof_blur_far_distance = p_distance; + _update_dof_blur(); +} + +float CameraEffects::get_dof_blur_far_distance() const { + return dof_blur_far_distance; +} + +void CameraEffects::set_dof_blur_far_transition(float p_distance) { + dof_blur_far_transition = p_distance; + _update_dof_blur(); +} + +float CameraEffects::get_dof_blur_far_transition() const { + return dof_blur_far_transition; +} + +void CameraEffects::set_dof_blur_near_enabled(bool p_enabled) { + dof_blur_near_enabled = p_enabled; + _update_dof_blur(); + _change_notify(); +} + +bool CameraEffects::is_dof_blur_near_enabled() const { + return dof_blur_near_enabled; +} + +void CameraEffects::set_dof_blur_near_distance(float p_distance) { + dof_blur_near_distance = p_distance; + _update_dof_blur(); +} + +float CameraEffects::get_dof_blur_near_distance() const { + return dof_blur_near_distance; +} + +void CameraEffects::set_dof_blur_near_transition(float p_distance) { + dof_blur_near_transition = p_distance; + _update_dof_blur(); +} + +float CameraEffects::get_dof_blur_near_transition() const { + return dof_blur_near_transition; +} + +void CameraEffects::set_dof_blur_amount(float p_amount) { + dof_blur_amount = p_amount; + _update_dof_blur(); +} + +float CameraEffects::get_dof_blur_amount() const { + return dof_blur_amount; +} + +void CameraEffects::_update_dof_blur() { + RS::get_singleton()->camera_effects_set_dof_blur( + camera_effects, + dof_blur_far_enabled, + dof_blur_far_distance, + dof_blur_far_transition, + dof_blur_near_enabled, + dof_blur_near_distance, + dof_blur_near_transition, + dof_blur_amount); +} + +// Custom exposure + +void CameraEffects::set_override_exposure_enabled(bool p_enabled) { + override_exposure_enabled = p_enabled; + _update_override_exposure(); +} + +bool CameraEffects::is_override_exposure_enabled() const { + return override_exposure_enabled; +} + +void CameraEffects::set_override_exposure(float p_exposure) { + override_exposure = p_exposure; + _update_override_exposure(); +} + +float CameraEffects::get_override_exposure() const { + return override_exposure; +} + +void CameraEffects::_update_override_exposure() { + RS::get_singleton()->camera_effects_set_custom_exposure( + camera_effects, + override_exposure_enabled, + override_exposure); +} + +// Private methods, constructor and destructor + +void CameraEffects::_bind_methods() { + // DOF blur + + ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &CameraEffects::set_dof_blur_far_enabled); + ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &CameraEffects::is_dof_blur_far_enabled); + ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "distance"), &CameraEffects::set_dof_blur_far_distance); + ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &CameraEffects::get_dof_blur_far_distance); + ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "distance"), &CameraEffects::set_dof_blur_far_transition); + ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &CameraEffects::get_dof_blur_far_transition); + + ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &CameraEffects::set_dof_blur_near_enabled); + ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &CameraEffects::is_dof_blur_near_enabled); + ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "distance"), &CameraEffects::set_dof_blur_near_distance); + ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &CameraEffects::get_dof_blur_near_distance); + ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "distance"), &CameraEffects::set_dof_blur_near_transition); + ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &CameraEffects::get_dof_blur_near_transition); + + ClassDB::bind_method(D_METHOD("set_dof_blur_amount", "amount"), &CameraEffects::set_dof_blur_amount); + ClassDB::bind_method(D_METHOD("get_dof_blur_amount"), &CameraEffects::get_dof_blur_amount); + + ADD_GROUP("DOF Blur", "dof_blur_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_amount", "get_dof_blur_amount"); + + // Override exposure + + ClassDB::bind_method(D_METHOD("set_override_exposure_enabled", "enabled"), &CameraEffects::set_override_exposure_enabled); + ClassDB::bind_method(D_METHOD("is_override_exposure_enabled"), &CameraEffects::is_override_exposure_enabled); + ClassDB::bind_method(D_METHOD("set_override_exposure", "exposure"), &CameraEffects::set_override_exposure); + ClassDB::bind_method(D_METHOD("get_override_exposure"), &CameraEffects::get_override_exposure); + + ADD_GROUP("Override Exposure", "override_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_exposure_enabled"), "set_override_exposure_enabled", "is_override_exposure_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "override_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_override_exposure", "get_override_exposure"); +} + +CameraEffects::CameraEffects() { + camera_effects = RS::get_singleton()->camera_effects_create(); + + _update_dof_blur(); + _update_override_exposure(); +} + +CameraEffects::~CameraEffects() { + RS::get_singleton()->free(camera_effects); +} diff --git a/scene/resources/camera_effects.h b/scene/resources/camera_effects.h new file mode 100644 index 0000000000..6b216e3296 --- /dev/null +++ b/scene/resources/camera_effects.h @@ -0,0 +1,94 @@ +/*************************************************************************/ +/* camera_effects.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef CAMERA_EFFECTS_H +#define CAMERA_EFFECTS_H + +#include "core/resource.h" +#include "core/rid.h" + +class CameraEffects : public Resource { + GDCLASS(CameraEffects, Resource); + +private: + RID camera_effects; + + // DOF blur + bool dof_blur_far_enabled = false; + float dof_blur_far_distance = 10; + float dof_blur_far_transition = 5; + + bool dof_blur_near_enabled = false; + float dof_blur_near_distance = 2; + float dof_blur_near_transition = 1; + + float dof_blur_amount = 0.1; + void _update_dof_blur(); + + // Override exposure + bool override_exposure_enabled = false; + float override_exposure = 1.0; + void _update_override_exposure(); + +protected: + static void _bind_methods(); + +public: + virtual RID get_rid() const; + + // DOF blur + void set_dof_blur_far_enabled(bool p_enabled); + bool is_dof_blur_far_enabled() const; + void set_dof_blur_far_distance(float p_distance); + float get_dof_blur_far_distance() const; + void set_dof_blur_far_transition(float p_distance); + float get_dof_blur_far_transition() const; + + void set_dof_blur_near_enabled(bool p_enabled); + bool is_dof_blur_near_enabled() const; + void set_dof_blur_near_distance(float p_distance); + float get_dof_blur_near_distance() const; + void set_dof_blur_near_transition(float p_distance); + float get_dof_blur_near_transition() const; + + void set_dof_blur_amount(float p_amount); + float get_dof_blur_amount() const; + + // Override exposure + void set_override_exposure_enabled(bool p_enabled); + bool is_override_exposure_enabled() const; + void set_override_exposure(float p_exposure); + float get_override_exposure() const; + + CameraEffects(); + ~CameraEffects(); +}; + +#endif // CAMERA_EFFECTS_H diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 854a9ee9da..94629a77b9 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "environment.h" + #include "core/project_settings.h" #include "servers/rendering_server.h" #include "texture.h" @@ -37,136 +38,159 @@ RID Environment::get_rid() const { return environment; } +// Background + void Environment::set_background(BGMode p_bg) { bg_mode = p_bg; RS::get_singleton()->environment_set_background(environment, RS::EnvironmentBG(p_bg)); _change_notify(); } +Environment::BGMode Environment::get_background() const { + return bg_mode; +} + void Environment::set_sky(const Ref<Sky> &p_sky) { bg_sky = p_sky; - RID sb_rid; if (bg_sky.is_valid()) { sb_rid = bg_sky->get_rid(); } - RS::get_singleton()->environment_set_sky(environment, sb_rid); } +Ref<Sky> Environment::get_sky() const { + return bg_sky; +} + void Environment::set_sky_custom_fov(float p_scale) { bg_sky_custom_fov = p_scale; RS::get_singleton()->environment_set_sky_custom_fov(environment, p_scale); } +float Environment::get_sky_custom_fov() const { + return bg_sky_custom_fov; +} + +void Environment::set_sky_rotation(const Vector3 &p_rotation) { + bg_sky_rotation = p_rotation; + RS::get_singleton()->environment_set_sky_orientation(environment, Basis(p_rotation)); +} + +Vector3 Environment::get_sky_rotation() const { + return bg_sky_rotation; +} + void Environment::set_bg_color(const Color &p_color) { bg_color = p_color; RS::get_singleton()->environment_set_bg_color(environment, p_color); } +Color Environment::get_bg_color() const { + return bg_color; +} + void Environment::set_bg_energy(float p_energy) { bg_energy = p_energy; RS::get_singleton()->environment_set_bg_energy(environment, p_energy); } +float Environment::get_bg_energy() const { + return bg_energy; +} + void Environment::set_canvas_max_layer(int p_max_layer) { bg_canvas_max_layer = p_max_layer; RS::get_singleton()->environment_set_canvas_max_layer(environment, p_max_layer); } -void Environment::set_ambient_light_color(const Color &p_color) { - ambient_color = p_color; - RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color); -} - -void Environment::set_ambient_light_energy(float p_energy) { - ambient_energy = p_energy; - RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color); -} - -void Environment::set_ambient_light_sky_contribution(float p_energy) { - ambient_sky_contribution = p_energy; - RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color); +int Environment::get_canvas_max_layer() const { + return bg_canvas_max_layer; } -void Environment::set_camera_feed_id(int p_camera_feed_id) { - camera_feed_id = p_camera_feed_id; +void Environment::set_camera_feed_id(int p_id) { + bg_camera_feed_id = p_id; // FIXME: Disabled during Vulkan refactoring, should be ported. #if 0 RS::get_singleton()->environment_set_camera_feed_id(environment, camera_feed_id); #endif -}; - -void Environment::set_ambient_source(AmbientSource p_source) { - ambient_source = p_source; - RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color); } -Environment::AmbientSource Environment::get_ambient_source() const { - return ambient_source; +int Environment::get_camera_feed_id() const { + return bg_camera_feed_id; } -void Environment::set_reflection_source(ReflectionSource p_source) { - reflection_source = p_source; - RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color); -} +// Ambient light -Environment::ReflectionSource Environment::get_reflection_source() const { - return reflection_source; +void Environment::set_ambient_light_color(const Color &p_color) { + ambient_color = p_color; + _update_ambient_light(); } -Environment::BGMode Environment::get_background() const { - return bg_mode; +Color Environment::get_ambient_light_color() const { + return ambient_color; } -Ref<Sky> Environment::get_sky() const { - return bg_sky; +void Environment::set_ambient_source(AmbientSource p_source) { + ambient_source = p_source; + _update_ambient_light(); } -float Environment::get_sky_custom_fov() const { - return bg_sky_custom_fov; +Environment::AmbientSource Environment::get_ambient_source() const { + return ambient_source; } -void Environment::set_sky_rotation(const Vector3 &p_rotation) { - sky_rotation = p_rotation; - RS::get_singleton()->environment_set_sky_orientation(environment, Basis(p_rotation)); +void Environment::set_ambient_light_energy(float p_energy) { + ambient_energy = p_energy; + _update_ambient_light(); } -Vector3 Environment::get_sky_rotation() const { - return sky_rotation; +float Environment::get_ambient_light_energy() const { + return ambient_energy; } -Color Environment::get_bg_color() const { - return bg_color; +void Environment::set_ambient_light_sky_contribution(float p_ratio) { + ambient_sky_contribution = p_ratio; + _update_ambient_light(); } -float Environment::get_bg_energy() const { - return bg_energy; +float Environment::get_ambient_light_sky_contribution() const { + return ambient_sky_contribution; } -int Environment::get_canvas_max_layer() const { - return bg_canvas_max_layer; +void Environment::set_reflection_source(ReflectionSource p_source) { + reflection_source = p_source; + _update_ambient_light(); } -Color Environment::get_ambient_light_color() const { - return ambient_color; +Environment::ReflectionSource Environment::get_reflection_source() const { + return reflection_source; } -float Environment::get_ambient_light_energy() const { - return ambient_energy; +void Environment::set_ao_color(const Color &p_color) { + ao_color = p_color; + _update_ambient_light(); } -float Environment::get_ambient_light_sky_contribution() const { - return ambient_sky_contribution; +Color Environment::get_ao_color() const { + return ao_color; } -int Environment::get_camera_feed_id() const { - return camera_feed_id; +void Environment::_update_ambient_light() { + RS::get_singleton()->environment_set_ambient_light( + environment, + ambient_color, + RS::EnvironmentAmbientSource(ambient_source), + ambient_energy, + ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), + ao_color); } +// Tonemap + void Environment::set_tonemapper(ToneMapper p_tone_mapper) { tone_mapper = p_tone_mapper; - RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey); + _update_tonemap(); } Environment::ToneMapper Environment::get_tonemapper() const { @@ -175,7 +199,7 @@ Environment::ToneMapper Environment::get_tonemapper() const { void Environment::set_tonemap_exposure(float p_exposure) { tonemap_exposure = p_exposure; - RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey); + _update_tonemap(); } float Environment::get_tonemap_exposure() const { @@ -184,44 +208,44 @@ float Environment::get_tonemap_exposure() const { void Environment::set_tonemap_white(float p_white) { tonemap_white = p_white; - RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey); + _update_tonemap(); } float Environment::get_tonemap_white() const { return tonemap_white; } -void Environment::set_tonemap_auto_exposure(bool p_enabled) { - tonemap_auto_exposure = p_enabled; - RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey); +void Environment::set_tonemap_auto_exposure_enabled(bool p_enabled) { + tonemap_auto_exposure_enabled = p_enabled; + _update_tonemap(); _change_notify(); } -bool Environment::get_tonemap_auto_exposure() const { - return tonemap_auto_exposure; -} - -void Environment::set_tonemap_auto_exposure_max(float p_auto_exposure_max) { - tonemap_auto_exposure_max = p_auto_exposure_max; - RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey); -} - -float Environment::get_tonemap_auto_exposure_max() const { - return tonemap_auto_exposure_max; +bool Environment::is_tonemap_auto_exposure_enabled() const { + return tonemap_auto_exposure_enabled; } void Environment::set_tonemap_auto_exposure_min(float p_auto_exposure_min) { tonemap_auto_exposure_min = p_auto_exposure_min; - RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey); + _update_tonemap(); } float Environment::get_tonemap_auto_exposure_min() const { return tonemap_auto_exposure_min; } +void Environment::set_tonemap_auto_exposure_max(float p_auto_exposure_max) { + tonemap_auto_exposure_max = p_auto_exposure_max; + _update_tonemap(); +} + +float Environment::get_tonemap_auto_exposure_max() const { + return tonemap_auto_exposure_max; +} + void Environment::set_tonemap_auto_exposure_speed(float p_auto_exposure_speed) { tonemap_auto_exposure_speed = p_auto_exposure_speed; - RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey); + _update_tonemap(); } float Environment::get_tonemap_auto_exposure_speed() const { @@ -230,143 +254,31 @@ float Environment::get_tonemap_auto_exposure_speed() const { void Environment::set_tonemap_auto_exposure_grey(float p_auto_exposure_grey) { tonemap_auto_exposure_grey = p_auto_exposure_grey; - RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey); + _update_tonemap(); } float Environment::get_tonemap_auto_exposure_grey() const { return tonemap_auto_exposure_grey; } -void Environment::set_adjustment_enable(bool p_enable) { - adjustment_enabled = p_enable; - RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID()); - _change_notify(); -} - -bool Environment::is_adjustment_enabled() const { - return adjustment_enabled; -} - -void Environment::set_adjustment_brightness(float p_brightness) { - adjustment_brightness = p_brightness; - RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID()); -} - -float Environment::get_adjustment_brightness() const { - return adjustment_brightness; -} - -void Environment::set_adjustment_contrast(float p_contrast) { - adjustment_contrast = p_contrast; - RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID()); -} - -float Environment::get_adjustment_contrast() const { - return adjustment_contrast; -} - -void Environment::set_adjustment_saturation(float p_saturation) { - adjustment_saturation = p_saturation; - RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID()); -} - -float Environment::get_adjustment_saturation() const { - return adjustment_saturation; -} - -void Environment::set_adjustment_color_correction(const Ref<Texture2D> &p_ramp) { - adjustment_color_correction = p_ramp; - RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID()); -} - -Ref<Texture2D> Environment::get_adjustment_color_correction() const { - return adjustment_color_correction; +void Environment::_update_tonemap() { + RS::get_singleton()->environment_set_tonemap( + environment, + RS::EnvironmentToneMapper(tone_mapper), + tonemap_exposure, + tonemap_white, + tonemap_auto_exposure_enabled, + tonemap_auto_exposure_min, + tonemap_auto_exposure_max, + tonemap_auto_exposure_speed, + tonemap_auto_exposure_grey); } -void Environment::_validate_property(PropertyInfo &property) const { - if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light/sky_contribution") { - if (bg_mode != BG_SKY && ambient_source != AMBIENT_SOURCE_SKY && reflection_source != REFLECTION_SOURCE_SKY) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; - } - } - - if (property.name == "glow_intensity" && glow_blend_mode == GLOW_BLEND_MODE_MIX) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; - } - - if (property.name == "glow_mix" && glow_blend_mode != GLOW_BLEND_MODE_MIX) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; - } +// SSR - if (property.name == "background_color") { - if (bg_mode != BG_COLOR && ambient_source != AMBIENT_SOURCE_COLOR) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; - } - } - - if (property.name == "background_canvas_max_layer") { - if (bg_mode != BG_CANVAS) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; - } - } - - if (property.name == "background_camera_feed_id") { - if (bg_mode != BG_CAMERA_FEED) { - property.usage = PROPERTY_USAGE_NOEDITOR; - } - } - - static const char *hide_prefixes[] = { - "fog_", - "auto_exposure_", - "ss_reflections_", - "ssao_", - "glow_", - "adjustment_", - nullptr - - }; - - static const char *high_end_prefixes[] = { - "auto_exposure_", - "tonemap_", - "ss_reflections_", - "ssao_", - nullptr - - }; - - const char **prefixes = hide_prefixes; - while (*prefixes) { - String prefix = String(*prefixes); - - String enabled = prefix + "enabled"; - if (property.name.begins_with(prefix) && property.name != enabled && !bool(get(enabled))) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; - return; - } - - prefixes++; - } - - if (RenderingServer::get_singleton()->is_low_end()) { - prefixes = high_end_prefixes; - while (*prefixes) { - String prefix = String(*prefixes); - - if (property.name.begins_with(prefix)) { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; - return; - } - - prefixes++; - } - } -} - -void Environment::set_ssr_enabled(bool p_enable) { - ssr_enabled = p_enable; - RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance); +void Environment::set_ssr_enabled(bool p_enabled) { + ssr_enabled = p_enabled; + _update_ssr(); _change_notify(); } @@ -376,7 +288,7 @@ bool Environment::is_ssr_enabled() const { void Environment::set_ssr_max_steps(int p_steps) { ssr_max_steps = p_steps; - RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance); + _update_ssr(); } int Environment::get_ssr_max_steps() const { @@ -385,7 +297,7 @@ int Environment::get_ssr_max_steps() const { void Environment::set_ssr_fade_in(float p_fade_in) { ssr_fade_in = p_fade_in; - RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance); + _update_ssr(); } float Environment::get_ssr_fade_in() const { @@ -394,7 +306,7 @@ float Environment::get_ssr_fade_in() const { void Environment::set_ssr_fade_out(float p_fade_out) { ssr_fade_out = p_fade_out; - RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance); + _update_ssr(); } float Environment::get_ssr_fade_out() const { @@ -403,16 +315,28 @@ float Environment::get_ssr_fade_out() const { void Environment::set_ssr_depth_tolerance(float p_depth_tolerance) { ssr_depth_tolerance = p_depth_tolerance; - RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance); + _update_ssr(); } float Environment::get_ssr_depth_tolerance() const { return ssr_depth_tolerance; } -void Environment::set_ssao_enabled(bool p_enable) { - ssao_enabled = p_enable; - RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); +void Environment::_update_ssr() { + RS::get_singleton()->environment_set_ssr( + environment, + ssr_enabled, + ssr_max_steps, + ssr_fade_in, + ssr_fade_out, + ssr_depth_tolerance); +} + +// SSAO + +void Environment::set_ssao_enabled(bool p_enabled) { + ssao_enabled = p_enabled; + _update_ssao(); _change_notify(); } @@ -422,7 +346,7 @@ bool Environment::is_ssao_enabled() const { void Environment::set_ssao_radius(float p_radius) { ssao_radius = p_radius; - RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + _update_ssao(); } float Environment::get_ssao_radius() const { @@ -431,7 +355,7 @@ float Environment::get_ssao_radius() const { void Environment::set_ssao_intensity(float p_intensity) { ssao_intensity = p_intensity; - RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + _update_ssao(); } float Environment::get_ssao_intensity() const { @@ -440,7 +364,7 @@ float Environment::get_ssao_intensity() const { void Environment::set_ssao_bias(float p_bias) { ssao_bias = p_bias; - RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + _update_ssao(); } float Environment::get_ssao_bias() const { @@ -449,7 +373,7 @@ float Environment::get_ssao_bias() const { void Environment::set_ssao_direct_light_affect(float p_direct_light_affect) { ssao_direct_light_affect = p_direct_light_affect; - RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + _update_ssao(); } float Environment::get_ssao_direct_light_affect() const { @@ -458,25 +382,16 @@ float Environment::get_ssao_direct_light_affect() const { void Environment::set_ssao_ao_channel_affect(float p_ao_channel_affect) { ssao_ao_channel_affect = p_ao_channel_affect; - RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + _update_ssao(); } float Environment::get_ssao_ao_channel_affect() const { return ssao_ao_channel_affect; } -void Environment::set_ao_color(const Color &p_color) { - ao_color = p_color; - RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color); -} - -Color Environment::get_ao_color() const { - return ao_color; -} - void Environment::set_ssao_blur(SSAOBlur p_blur) { ssao_blur = p_blur; - RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + _update_ssao(); } Environment::SSAOBlur Environment::get_ssao_blur() const { @@ -485,16 +400,175 @@ Environment::SSAOBlur Environment::get_ssao_blur() const { void Environment::set_ssao_edge_sharpness(float p_edge_sharpness) { ssao_edge_sharpness = p_edge_sharpness; - RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + _update_ssao(); } float Environment::get_ssao_edge_sharpness() const { return ssao_edge_sharpness; } +void Environment::_update_ssao() { + RS::get_singleton()->environment_set_ssao( + environment, + ssao_enabled, + ssao_radius, + ssao_intensity, + ssao_bias, + ssao_direct_light_affect, + ssao_ao_channel_affect, + RS::EnvironmentSSAOBlur(ssao_blur), + ssao_edge_sharpness); +} + +// SDFGI + +void Environment::set_sdfgi_enabled(bool p_enabled) { + sdfgi_enabled = p_enabled; + _update_sdfgi(); +} + +bool Environment::is_sdfgi_enabled() const { + return sdfgi_enabled; +} + +void Environment::set_sdfgi_cascades(SDFGICascades p_cascades) { + sdfgi_cascades = p_cascades; + _update_sdfgi(); +} + +Environment::SDFGICascades Environment::get_sdfgi_cascades() const { + return sdfgi_cascades; +} + +void Environment::set_sdfgi_min_cell_size(float p_size) { + sdfgi_min_cell_size = p_size; + _change_notify("sdfgi_max_distance"); + _change_notify("sdfgi_cascade0_distance"); + _update_sdfgi(); +} + +float Environment::get_sdfgi_min_cell_size() const { + return sdfgi_min_cell_size; +} + +void Environment::set_sdfgi_max_distance(float p_distance) { + p_distance /= 64.0; + int cc[3] = { 4, 6, 8 }; + int cascades = cc[sdfgi_cascades]; + for (int i = 0; i < cascades; i++) { + p_distance *= 0.5; //halve for each cascade + } + sdfgi_min_cell_size = p_distance; + _change_notify("sdfgi_min_cell_size"); + _change_notify("sdfgi_cascade0_distance"); + _update_sdfgi(); +} + +float Environment::get_sdfgi_max_distance() const { + float md = sdfgi_min_cell_size; + md *= 64.0; + int cc[3] = { 4, 6, 8 }; + int cascades = cc[sdfgi_cascades]; + for (int i = 0; i < cascades; i++) { + md *= 2.0; + } + return md; +} + +void Environment::set_sdfgi_cascade0_distance(float p_distance) { + sdfgi_min_cell_size = p_distance / 64.0; + _change_notify("sdfgi_min_cell_size"); + _change_notify("sdfgi_max_distance"); + _update_sdfgi(); +} + +float Environment::get_sdfgi_cascade0_distance() const { + return sdfgi_min_cell_size * 64.0; +} + +void Environment::set_sdfgi_y_scale(SDFGIYScale p_y_scale) { + sdfgi_y_scale = p_y_scale; + _update_sdfgi(); +} + +Environment::SDFGIYScale Environment::get_sdfgi_y_scale() const { + return sdfgi_y_scale; +} + +void Environment::set_sdfgi_use_occlusion(bool p_enabled) { + sdfgi_use_occlusion = p_enabled; + _update_sdfgi(); +} + +bool Environment::is_sdfgi_using_occlusion() const { + return sdfgi_use_occlusion; +} + +void Environment::set_sdfgi_use_multi_bounce(bool p_enabled) { + sdfgi_use_multibounce = p_enabled; + _update_sdfgi(); +} + +bool Environment::is_sdfgi_using_multi_bounce() const { + return sdfgi_use_multibounce; +} + +void Environment::set_sdfgi_read_sky_light(bool p_enabled) { + sdfgi_read_sky_light = p_enabled; + _update_sdfgi(); +} + +bool Environment::is_sdfgi_reading_sky_light() const { + return sdfgi_read_sky_light; +} + +void Environment::set_sdfgi_energy(float p_energy) { + sdfgi_energy = p_energy; + _update_sdfgi(); +} + +float Environment::get_sdfgi_energy() const { + return sdfgi_energy; +} + +void Environment::set_sdfgi_normal_bias(float p_bias) { + sdfgi_normal_bias = p_bias; + _update_sdfgi(); +} + +float Environment::get_sdfgi_normal_bias() const { + return sdfgi_normal_bias; +} + +void Environment::set_sdfgi_probe_bias(float p_bias) { + sdfgi_probe_bias = p_bias; + _update_sdfgi(); +} + +float Environment::get_sdfgi_probe_bias() const { + return sdfgi_probe_bias; +} + +void Environment::_update_sdfgi() { + RS::get_singleton()->environment_set_sdfgi( + environment, + sdfgi_enabled, + RS::EnvironmentSDFGICascades(sdfgi_cascades), + sdfgi_min_cell_size, + RS::EnvironmentSDFGIYScale(sdfgi_y_scale), + sdfgi_use_occlusion, + sdfgi_use_multibounce, + sdfgi_read_sky_light, + sdfgi_energy, + sdfgi_normal_bias, + sdfgi_probe_bias); +} + +// Glow + void Environment::set_glow_enabled(bool p_enabled) { glow_enabled = p_enabled; - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); + _update_glow(); _change_notify(); } @@ -502,7 +576,7 @@ bool Environment::is_glow_enabled() const { return glow_enabled; } -void Environment::set_glow_level(int p_level, bool p_enabled) { +void Environment::set_glow_level_enabled(int p_level, bool p_enabled) { ERR_FAIL_INDEX(p_level, RS::MAX_GLOW_LEVELS); if (p_enabled) { @@ -511,7 +585,7 @@ void Environment::set_glow_level(int p_level, bool p_enabled) { glow_levels &= ~(1 << p_level); } - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); + _update_glow(); } bool Environment::is_glow_level_enabled(int p_level) const { @@ -522,8 +596,7 @@ bool Environment::is_glow_level_enabled(int p_level) const { void Environment::set_glow_intensity(float p_intensity) { glow_intensity = p_intensity; - - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); + _update_glow(); } float Environment::get_glow_intensity() const { @@ -532,7 +605,7 @@ float Environment::get_glow_intensity() const { void Environment::set_glow_strength(float p_strength) { glow_strength = p_strength; - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); + _update_glow(); } float Environment::get_glow_strength() const { @@ -541,7 +614,7 @@ float Environment::get_glow_strength() const { void Environment::set_glow_mix(float p_mix) { glow_mix = p_mix; - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); + _update_glow(); } float Environment::get_glow_mix() const { @@ -550,8 +623,7 @@ float Environment::get_glow_mix() const { void Environment::set_glow_bloom(float p_threshold) { glow_bloom = p_threshold; - - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); + _update_glow(); } float Environment::get_glow_bloom() const { @@ -560,8 +632,7 @@ float Environment::get_glow_bloom() const { void Environment::set_glow_blend_mode(GlowBlendMode p_mode) { glow_blend_mode = p_mode; - - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); + _update_glow(); _change_notify(); } @@ -571,37 +642,51 @@ Environment::GlowBlendMode Environment::get_glow_blend_mode() const { void Environment::set_glow_hdr_bleed_threshold(float p_threshold) { glow_hdr_bleed_threshold = p_threshold; - - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); + _update_glow(); } float Environment::get_glow_hdr_bleed_threshold() const { return glow_hdr_bleed_threshold; } +void Environment::set_glow_hdr_bleed_scale(float p_scale) { + glow_hdr_bleed_scale = p_scale; + _update_glow(); +} + +float Environment::get_glow_hdr_bleed_scale() const { + return glow_hdr_bleed_scale; +} + void Environment::set_glow_hdr_luminance_cap(float p_amount) { glow_hdr_luminance_cap = p_amount; - - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); + _update_glow(); } float Environment::get_glow_hdr_luminance_cap() const { return glow_hdr_luminance_cap; } -void Environment::set_glow_hdr_bleed_scale(float p_scale) { - glow_hdr_bleed_scale = p_scale; - - RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap); +void Environment::_update_glow() { + RS::get_singleton()->environment_set_glow( + environment, + glow_enabled, + glow_levels, + glow_intensity, + glow_strength, + glow_mix, + glow_bloom, + RS::EnvironmentGlowBlendMode(glow_blend_mode), + glow_hdr_bleed_threshold, + glow_hdr_bleed_scale, + glow_hdr_luminance_cap); } -float Environment::get_glow_hdr_bleed_scale() const { - return glow_hdr_bleed_scale; -} +// Fog void Environment::set_fog_enabled(bool p_enabled) { fog_enabled = p_enabled; - RS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount); + _update_fog(); _change_notify(); } @@ -611,7 +696,7 @@ bool Environment::is_fog_enabled() const { void Environment::set_fog_color(const Color &p_color) { fog_color = p_color; - RS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount); + _update_fog(); } Color Environment::get_fog_color() const { @@ -620,7 +705,7 @@ Color Environment::get_fog_color() const { void Environment::set_fog_sun_color(const Color &p_color) { fog_sun_color = p_color; - RS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount); + _update_fog(); } Color Environment::get_fog_sun_color() const { @@ -629,16 +714,25 @@ Color Environment::get_fog_sun_color() const { void Environment::set_fog_sun_amount(float p_amount) { fog_sun_amount = p_amount; - RS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount); + _update_fog(); } float Environment::get_fog_sun_amount() const { return fog_sun_amount; } +void Environment::_update_fog() { + RS::get_singleton()->environment_set_fog( + environment, + fog_enabled, + fog_color, + fog_sun_color, + fog_sun_amount); +} + void Environment::set_fog_depth_enabled(bool p_enabled) { fog_depth_enabled = p_enabled; - RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + _update_fog_depth(); } bool Environment::is_fog_depth_enabled() const { @@ -647,7 +741,7 @@ bool Environment::is_fog_depth_enabled() const { void Environment::set_fog_depth_begin(float p_distance) { fog_depth_begin = p_distance; - RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + _update_fog_depth(); } float Environment::get_fog_depth_begin() const { @@ -656,7 +750,7 @@ float Environment::get_fog_depth_begin() const { void Environment::set_fog_depth_end(float p_distance) { fog_depth_end = p_distance; - RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + _update_fog_depth(); } float Environment::get_fog_depth_end() const { @@ -665,7 +759,7 @@ float Environment::get_fog_depth_end() const { void Environment::set_fog_depth_curve(float p_curve) { fog_depth_curve = p_curve; - RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + _update_fog_depth(); } float Environment::get_fog_depth_curve() const { @@ -674,7 +768,7 @@ float Environment::get_fog_depth_curve() const { void Environment::set_fog_transmit_enabled(bool p_enabled) { fog_transmit_enabled = p_enabled; - RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + _update_fog_depth(); } bool Environment::is_fog_transmit_enabled() const { @@ -683,16 +777,27 @@ bool Environment::is_fog_transmit_enabled() const { void Environment::set_fog_transmit_curve(float p_curve) { fog_transmit_curve = p_curve; - RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); + _update_fog_depth(); } float Environment::get_fog_transmit_curve() const { return fog_transmit_curve; } +void Environment::_update_fog_depth() { + RS::get_singleton()->environment_set_fog_depth( + environment, + fog_depth_enabled, + fog_depth_begin, + fog_depth_end, + fog_depth_curve, + fog_transmit_enabled, + fog_transmit_curve); +} + void Environment::set_fog_height_enabled(bool p_enabled) { fog_height_enabled = p_enabled; - RS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve); + _update_fog_height(); } bool Environment::is_fog_height_enabled() const { @@ -701,7 +806,7 @@ bool Environment::is_fog_height_enabled() const { void Environment::set_fog_height_min(float p_distance) { fog_height_min = p_distance; - RS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve); + _update_fog_height(); } float Environment::get_fog_height_min() const { @@ -710,7 +815,7 @@ float Environment::get_fog_height_min() const { void Environment::set_fog_height_max(float p_distance) { fog_height_max = p_distance; - RS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve); + _update_fog_height(); } float Environment::get_fog_height_max() const { @@ -719,316 +824,279 @@ float Environment::get_fog_height_max() const { void Environment::set_fog_height_curve(float p_distance) { fog_height_curve = p_distance; - RS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve); + _update_fog_height(); } float Environment::get_fog_height_curve() const { return fog_height_curve; } -#ifndef DISABLE_DEPRECATED -// Kept for compatibility from 3.x to 4.0. -bool Environment::_set(const StringName &p_name, const Variant &p_value) { - if (p_name == "background_sky") { - set_sky(p_value); - return true; - } else if (p_name == "background_sky_custom_fov") { - set_sky_custom_fov(p_value); - return true; - } else if (p_name == "background_sky_orientation") { - Vector3 euler = p_value.operator Basis().get_euler(); - set_sky_rotation(euler); - return true; - } else { - return false; - } +void Environment::_update_fog_height() { + RS::get_singleton()->environment_set_fog_height( + environment, + fog_height_enabled, + fog_height_min, + fog_height_max, + fog_height_curve); } -#endif -void Environment::set_sdfgi_enabled(bool p_enabled) { - sdfgi_enabled = p_enabled; - _update_sdfgi(); -} +// Adjustment -bool Environment::is_sdfgi_enabled() const { - return sdfgi_enabled; +void Environment::set_adjustment_enabled(bool p_enabled) { + adjustment_enabled = p_enabled; + _update_adjustment(); + _change_notify(); } -void Environment::set_sdfgi_cascades(SDFGICascades p_cascades) { - sdfgi_cascades = p_cascades; - _update_sdfgi(); -} -Environment::SDFGICascades Environment::get_sdfgi_cascades() const { - return sdfgi_cascades; +bool Environment::is_adjustment_enabled() const { + return adjustment_enabled; } -void Environment::set_sdfgi_min_cell_size(float p_size) { - sdfgi_min_cell_size = p_size; - _change_notify("sdfgi_max_distance"); - _change_notify("sdfgi_cascade0_distance"); - _update_sdfgi(); -} -float Environment::get_sdfgi_min_cell_size() const { - return sdfgi_min_cell_size; +void Environment::set_adjustment_brightness(float p_brightness) { + adjustment_brightness = p_brightness; + _update_adjustment(); } -void Environment::set_sdfgi_max_distance(float p_size) { - p_size /= 64.0; - int cc[3] = { 4, 6, 8 }; - int cascades = cc[sdfgi_cascades]; - for (int i = 0; i < cascades; i++) { - p_size *= 0.5; //halve for each cascade - } - sdfgi_min_cell_size = p_size; - _change_notify("sdfgi_min_cell_size"); - _change_notify("sdfgi_cascade0_distance"); - _update_sdfgi(); -} -float Environment::get_sdfgi_max_distance() const { - float md = sdfgi_min_cell_size; - md *= 64.0; - int cc[3] = { 4, 6, 8 }; - int cascades = cc[sdfgi_cascades]; - for (int i = 0; i < cascades; i++) { - md *= 2.0; - } - return md; +float Environment::get_adjustment_brightness() const { + return adjustment_brightness; } -void Environment::set_sdfgi_cascade0_distance(float p_size) { - sdfgi_min_cell_size = p_size / 64.0; - _change_notify("sdfgi_min_cell_size"); - _change_notify("sdfgi_max_distance"); - _update_sdfgi(); -} -float Environment::get_sdfgi_cascade0_distance() const { - return sdfgi_min_cell_size * 64.0; +void Environment::set_adjustment_contrast(float p_contrast) { + adjustment_contrast = p_contrast; + _update_adjustment(); } -void Environment::set_sdfgi_use_occlusion(bool p_enable) { - sdfgi_use_occlusion = p_enable; - _update_sdfgi(); +float Environment::get_adjustment_contrast() const { + return adjustment_contrast; } -bool Environment::is_sdfgi_using_occlusion() const { - return sdfgi_use_occlusion; +void Environment::set_adjustment_saturation(float p_saturation) { + adjustment_saturation = p_saturation; + _update_adjustment(); } -void Environment::set_sdfgi_use_multi_bounce(bool p_enable) { - sdfgi_use_multibounce = p_enable; - _update_sdfgi(); -} -bool Environment::is_sdfgi_using_multi_bounce() const { - return sdfgi_use_multibounce; +float Environment::get_adjustment_saturation() const { + return adjustment_saturation; } -void Environment::set_sdfgi_use_enhance_ssr(bool p_enable) { - sdfgi_enhance_ssr = p_enable; - _update_sdfgi(); -} -bool Environment::is_sdfgi_using_enhance_ssr() const { - return sdfgi_enhance_ssr; +void Environment::set_adjustment_color_correction(const Ref<Texture2D> &p_ramp) { + adjustment_color_correction = p_ramp; + _update_adjustment(); } -void Environment::set_sdfgi_read_sky_light(bool p_enable) { - sdfgi_read_sky_light = p_enable; - _update_sdfgi(); +Ref<Texture2D> Environment::get_adjustment_color_correction() const { + return adjustment_color_correction; } -bool Environment::is_sdfgi_reading_sky_light() const { - return sdfgi_read_sky_light; +void Environment::_update_adjustment() { + RS::get_singleton()->environment_set_adjustment( + environment, + adjustment_enabled, + adjustment_brightness, + adjustment_contrast, + adjustment_saturation, + adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID()); } -void Environment::set_sdfgi_energy(float p_energy) { - sdfgi_energy = p_energy; - _update_sdfgi(); -} -float Environment::get_sdfgi_energy() const { - return sdfgi_energy; -} +// Private methods, constructor and destructor -void Environment::set_sdfgi_normal_bias(float p_bias) { - sdfgi_normal_bias = p_bias; - _update_sdfgi(); -} -float Environment::get_sdfgi_normal_bias() const { - return sdfgi_normal_bias; -} +void Environment::_validate_property(PropertyInfo &property) const { + if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light/sky_contribution") { + if (bg_mode != BG_SKY && ambient_source != AMBIENT_SOURCE_SKY && reflection_source != REFLECTION_SOURCE_SKY) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } + } -void Environment::set_sdfgi_probe_bias(float p_bias) { - sdfgi_probe_bias = p_bias; - _update_sdfgi(); -} -float Environment::get_sdfgi_probe_bias() const { - return sdfgi_probe_bias; -} + if (property.name == "glow_intensity" && glow_blend_mode == GLOW_BLEND_MODE_MIX) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } -void Environment::set_sdfgi_y_scale(SDFGIYScale p_y_scale) { - sdfgi_y_scale = p_y_scale; - _update_sdfgi(); -} -Environment::SDFGIYScale Environment::get_sdfgi_y_scale() const { - return sdfgi_y_scale; + if (property.name == "glow_mix" && glow_blend_mode != GLOW_BLEND_MODE_MIX) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } + + if (property.name == "background_color") { + if (bg_mode != BG_COLOR && ambient_source != AMBIENT_SOURCE_COLOR) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } + } + + if (property.name == "background_canvas_max_layer") { + if (bg_mode != BG_CANVAS) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } + } + + if (property.name == "background_camera_feed_id") { + if (bg_mode != BG_CAMERA_FEED) { + property.usage = PROPERTY_USAGE_NOEDITOR; + } + } + + static const char *hide_prefixes[] = { + "fog_", + "auto_exposure_", + "ss_reflections_", + "ssao_", + "glow_", + "adjustment_", + nullptr + + }; + + static const char *high_end_prefixes[] = { + "auto_exposure_", + "tonemap_", + "ss_reflections_", + "ssao_", + nullptr + + }; + + const char **prefixes = hide_prefixes; + while (*prefixes) { + String prefix = String(*prefixes); + + String enabled = prefix + "enabled"; + if (property.name.begins_with(prefix) && property.name != enabled && !bool(get(enabled))) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + return; + } + + prefixes++; + } + + if (RenderingServer::get_singleton()->is_low_end()) { + prefixes = high_end_prefixes; + while (*prefixes) { + String prefix = String(*prefixes); + + if (property.name.begins_with(prefix)) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + return; + } + + prefixes++; + } + } } -void Environment::_update_sdfgi() { - RS::get_singleton()->environment_set_sdfgi(environment, sdfgi_enabled, RS::EnvironmentSDFGICascades(sdfgi_cascades), sdfgi_min_cell_size, RS::EnvironmentSDFGIYScale(sdfgi_y_scale), sdfgi_use_occlusion, sdfgi_use_multibounce, sdfgi_read_sky_light, sdfgi_enhance_ssr, sdfgi_energy, sdfgi_normal_bias, sdfgi_probe_bias); + +#ifndef DISABLE_DEPRECATED +// Kept for compatibility from 3.x to 4.0. +bool Environment::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "background_sky") { + set_sky(p_value); + return true; + } else if (p_name == "background_sky_custom_fov") { + set_sky_custom_fov(p_value); + return true; + } else if (p_name == "background_sky_orientation") { + Vector3 euler = p_value.operator Basis().get_euler(); + set_sky_rotation(euler); + return true; + } else { + return false; + } } +#endif void Environment::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background); - ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky); - ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov); - ClassDB::bind_method(D_METHOD("set_sky_rotation", "euler_radians"), &Environment::set_sky_rotation); - ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color); - ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy); - ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer); - ClassDB::bind_method(D_METHOD("set_ambient_light_color", "color"), &Environment::set_ambient_light_color); - ClassDB::bind_method(D_METHOD("set_ambient_light_energy", "energy"), &Environment::set_ambient_light_energy); - ClassDB::bind_method(D_METHOD("set_ambient_light_sky_contribution", "energy"), &Environment::set_ambient_light_sky_contribution); - ClassDB::bind_method(D_METHOD("set_camera_feed_id", "camera_feed_id"), &Environment::set_camera_feed_id); - ClassDB::bind_method(D_METHOD("set_ambient_source", "source"), &Environment::set_ambient_source); - ClassDB::bind_method(D_METHOD("set_reflection_source", "source"), &Environment::set_reflection_source); + // Background + ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background); ClassDB::bind_method(D_METHOD("get_background"), &Environment::get_background); + ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky); ClassDB::bind_method(D_METHOD("get_sky"), &Environment::get_sky); + ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov); ClassDB::bind_method(D_METHOD("get_sky_custom_fov"), &Environment::get_sky_custom_fov); + ClassDB::bind_method(D_METHOD("set_sky_rotation", "euler_radians"), &Environment::set_sky_rotation); ClassDB::bind_method(D_METHOD("get_sky_rotation"), &Environment::get_sky_rotation); + ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color); ClassDB::bind_method(D_METHOD("get_bg_color"), &Environment::get_bg_color); + ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy); ClassDB::bind_method(D_METHOD("get_bg_energy"), &Environment::get_bg_energy); + ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer); ClassDB::bind_method(D_METHOD("get_canvas_max_layer"), &Environment::get_canvas_max_layer); - ClassDB::bind_method(D_METHOD("get_ambient_light_color"), &Environment::get_ambient_light_color); - ClassDB::bind_method(D_METHOD("get_ambient_light_energy"), &Environment::get_ambient_light_energy); - ClassDB::bind_method(D_METHOD("get_ambient_light_sky_contribution"), &Environment::get_ambient_light_sky_contribution); + ClassDB::bind_method(D_METHOD("set_camera_feed_id", "id"), &Environment::set_camera_feed_id); ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &Environment::get_camera_feed_id); - ClassDB::bind_method(D_METHOD("get_ambient_source"), &Environment::get_ambient_source); - ClassDB::bind_method(D_METHOD("get_reflection_source"), &Environment::get_reflection_source); - ClassDB::bind_method(D_METHOD("set_ao_color", "color"), &Environment::set_ao_color); - ClassDB::bind_method(D_METHOD("get_ao_color"), &Environment::get_ao_color); ADD_GROUP("Background", "background_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Canvas,Keep,Camera Feed"), "set_background", "get_background"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "background_canvas_max_layer", PROPERTY_HINT_RANGE, "-1000,1000,1"), "set_canvas_max_layer", "get_canvas_max_layer"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "background_camera_feed_id", PROPERTY_HINT_RANGE, "1,10,1"), "set_camera_feed_id", "get_camera_feed_id"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "background_canvas_max_layer", PROPERTY_HINT_RANGE, "-1000,1000,1"), "set_canvas_max_layer", "get_canvas_max_layer"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "background_camera_feed_id", PROPERTY_HINT_RANGE, "1,10,1"), "set_camera_feed_id", "get_camera_feed_id"); + ADD_GROUP("Sky", "sky_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation"), "set_sky_rotation", "get_sky_rotation"); + + // Ambient light + + ClassDB::bind_method(D_METHOD("set_ambient_light_color", "color"), &Environment::set_ambient_light_color); + ClassDB::bind_method(D_METHOD("get_ambient_light_color"), &Environment::get_ambient_light_color); + ClassDB::bind_method(D_METHOD("set_ambient_source", "source"), &Environment::set_ambient_source); + ClassDB::bind_method(D_METHOD("get_ambient_source"), &Environment::get_ambient_source); + ClassDB::bind_method(D_METHOD("set_ambient_light_energy", "energy"), &Environment::set_ambient_light_energy); + ClassDB::bind_method(D_METHOD("get_ambient_light_energy"), &Environment::get_ambient_light_energy); + ClassDB::bind_method(D_METHOD("set_ambient_light_sky_contribution", "ratio"), &Environment::set_ambient_light_sky_contribution); + ClassDB::bind_method(D_METHOD("get_ambient_light_sky_contribution"), &Environment::get_ambient_light_sky_contribution); + ClassDB::bind_method(D_METHOD("set_reflection_source", "source"), &Environment::set_reflection_source); + ClassDB::bind_method(D_METHOD("get_reflection_source"), &Environment::get_reflection_source); + ClassDB::bind_method(D_METHOD("set_ao_color", "color"), &Environment::set_ao_color); + ClassDB::bind_method(D_METHOD("get_ao_color"), &Environment::get_ao_color); + ADD_GROUP("Ambient Light", "ambient_light_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Color,Sky"), "set_ambient_source", "get_ambient_source"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_color"), "set_ambient_light_color", "get_ambient_light_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_occlusion_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ao_color", "get_ao_color"); + ADD_GROUP("Reflected Light", "reflected_light_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "reflected_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Sky"), "set_reflection_source", "get_reflection_source"); - ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled); - ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled); - - ClassDB::bind_method(D_METHOD("set_fog_color", "color"), &Environment::set_fog_color); - ClassDB::bind_method(D_METHOD("get_fog_color"), &Environment::get_fog_color); - - ClassDB::bind_method(D_METHOD("set_fog_sun_color", "color"), &Environment::set_fog_sun_color); - ClassDB::bind_method(D_METHOD("get_fog_sun_color"), &Environment::get_fog_sun_color); - - ClassDB::bind_method(D_METHOD("set_fog_sun_amount", "amount"), &Environment::set_fog_sun_amount); - ClassDB::bind_method(D_METHOD("get_fog_sun_amount"), &Environment::get_fog_sun_amount); - - ClassDB::bind_method(D_METHOD("set_fog_depth_enabled", "enabled"), &Environment::set_fog_depth_enabled); - ClassDB::bind_method(D_METHOD("is_fog_depth_enabled"), &Environment::is_fog_depth_enabled); - - ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "distance"), &Environment::set_fog_depth_begin); - ClassDB::bind_method(D_METHOD("get_fog_depth_begin"), &Environment::get_fog_depth_begin); - - ClassDB::bind_method(D_METHOD("set_fog_depth_end", "distance"), &Environment::set_fog_depth_end); - ClassDB::bind_method(D_METHOD("get_fog_depth_end"), &Environment::get_fog_depth_end); - - ClassDB::bind_method(D_METHOD("set_fog_depth_curve", "curve"), &Environment::set_fog_depth_curve); - ClassDB::bind_method(D_METHOD("get_fog_depth_curve"), &Environment::get_fog_depth_curve); - - ClassDB::bind_method(D_METHOD("set_fog_transmit_enabled", "enabled"), &Environment::set_fog_transmit_enabled); - ClassDB::bind_method(D_METHOD("is_fog_transmit_enabled"), &Environment::is_fog_transmit_enabled); - - ClassDB::bind_method(D_METHOD("set_fog_transmit_curve", "curve"), &Environment::set_fog_transmit_curve); - ClassDB::bind_method(D_METHOD("get_fog_transmit_curve"), &Environment::get_fog_transmit_curve); - - ClassDB::bind_method(D_METHOD("set_fog_height_enabled", "enabled"), &Environment::set_fog_height_enabled); - ClassDB::bind_method(D_METHOD("is_fog_height_enabled"), &Environment::is_fog_height_enabled); - - ClassDB::bind_method(D_METHOD("set_fog_height_min", "height"), &Environment::set_fog_height_min); - ClassDB::bind_method(D_METHOD("get_fog_height_min"), &Environment::get_fog_height_min); - - ClassDB::bind_method(D_METHOD("set_fog_height_max", "height"), &Environment::set_fog_height_max); - ClassDB::bind_method(D_METHOD("get_fog_height_max"), &Environment::get_fog_height_max); - - ClassDB::bind_method(D_METHOD("set_fog_height_curve", "curve"), &Environment::set_fog_height_curve); - ClassDB::bind_method(D_METHOD("get_fog_height_curve"), &Environment::get_fog_height_curve); - - ADD_GROUP("Fog", "fog_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_color"), "set_fog_color", "get_fog_color"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_sun_color"), "set_fog_sun_color", "get_fog_sun_color"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_end", PROPERTY_HINT_RANGE, "0,4000,0.1,or_greater"), "set_fog_depth_end", "get_fog_depth_end"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_height_enabled"), "set_fog_height_enabled", "is_fog_height_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_min", "get_fog_height_min"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_max", "get_fog_height_max"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve"); + // Tonemap ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper); ClassDB::bind_method(D_METHOD("get_tonemapper"), &Environment::get_tonemapper); - ClassDB::bind_method(D_METHOD("set_tonemap_exposure", "exposure"), &Environment::set_tonemap_exposure); ClassDB::bind_method(D_METHOD("get_tonemap_exposure"), &Environment::get_tonemap_exposure); - ClassDB::bind_method(D_METHOD("set_tonemap_white", "white"), &Environment::set_tonemap_white); ClassDB::bind_method(D_METHOD("get_tonemap_white"), &Environment::get_tonemap_white); - - ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure", "auto_exposure"), &Environment::set_tonemap_auto_exposure); - ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure"), &Environment::get_tonemap_auto_exposure); - + ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_enabled", "enabled"), &Environment::set_tonemap_auto_exposure_enabled); + ClassDB::bind_method(D_METHOD("is_tonemap_auto_exposure_enabled"), &Environment::is_tonemap_auto_exposure_enabled); ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_max", "exposure_max"), &Environment::set_tonemap_auto_exposure_max); ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_max"), &Environment::get_tonemap_auto_exposure_max); - ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_min", "exposure_min"), &Environment::set_tonemap_auto_exposure_min); ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_min"), &Environment::get_tonemap_auto_exposure_min); - ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_speed", "exposure_speed"), &Environment::set_tonemap_auto_exposure_speed); ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_speed"), &Environment::get_tonemap_auto_exposure_speed); - ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_grey", "exposure_grey"), &Environment::set_tonemap_auto_exposure_grey); ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_grey"), &Environment::get_tonemap_auto_exposure_grey); ADD_GROUP("Tonemap", "tonemap_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,Aces"), "set_tonemapper", "get_tonemapper"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,ACES"), "set_tonemapper", "get_tonemapper"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white"); ADD_GROUP("Auto Exposure", "auto_exposure_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_exposure_enabled"), "set_tonemap_auto_exposure", "get_tonemap_auto_exposure"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_exposure_enabled"), "set_tonemap_auto_exposure_enabled", "is_tonemap_auto_exposure_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_grey", "get_tonemap_auto_exposure_grey"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_min_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_min", "get_tonemap_auto_exposure_min"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_max_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_max", "get_tonemap_auto_exposure_max"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_speed", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_speed", "get_tonemap_auto_exposure_speed"); + // SSR + ClassDB::bind_method(D_METHOD("set_ssr_enabled", "enabled"), &Environment::set_ssr_enabled); ClassDB::bind_method(D_METHOD("is_ssr_enabled"), &Environment::is_ssr_enabled); - ClassDB::bind_method(D_METHOD("set_ssr_max_steps", "max_steps"), &Environment::set_ssr_max_steps); ClassDB::bind_method(D_METHOD("get_ssr_max_steps"), &Environment::get_ssr_max_steps); - ClassDB::bind_method(D_METHOD("set_ssr_fade_in", "fade_in"), &Environment::set_ssr_fade_in); ClassDB::bind_method(D_METHOD("get_ssr_fade_in"), &Environment::get_ssr_fade_in); - ClassDB::bind_method(D_METHOD("set_ssr_fade_out", "fade_out"), &Environment::set_ssr_fade_out); ClassDB::bind_method(D_METHOD("get_ssr_fade_out"), &Environment::get_ssr_fade_out); - ClassDB::bind_method(D_METHOD("set_ssr_depth_tolerance", "depth_tolerance"), &Environment::set_ssr_depth_tolerance); ClassDB::bind_method(D_METHOD("get_ssr_depth_tolerance"), &Environment::get_ssr_depth_tolerance); @@ -1039,27 +1107,22 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.01,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance"); + // SSAO + ClassDB::bind_method(D_METHOD("set_ssao_enabled", "enabled"), &Environment::set_ssao_enabled); ClassDB::bind_method(D_METHOD("is_ssao_enabled"), &Environment::is_ssao_enabled); - ClassDB::bind_method(D_METHOD("set_ssao_radius", "radius"), &Environment::set_ssao_radius); ClassDB::bind_method(D_METHOD("get_ssao_radius"), &Environment::get_ssao_radius); - ClassDB::bind_method(D_METHOD("set_ssao_intensity", "intensity"), &Environment::set_ssao_intensity); ClassDB::bind_method(D_METHOD("get_ssao_intensity"), &Environment::get_ssao_intensity); - ClassDB::bind_method(D_METHOD("set_ssao_bias", "bias"), &Environment::set_ssao_bias); ClassDB::bind_method(D_METHOD("get_ssao_bias"), &Environment::get_ssao_bias); - ClassDB::bind_method(D_METHOD("set_ssao_direct_light_affect", "amount"), &Environment::set_ssao_direct_light_affect); ClassDB::bind_method(D_METHOD("get_ssao_direct_light_affect"), &Environment::get_ssao_direct_light_affect); - ClassDB::bind_method(D_METHOD("set_ssao_ao_channel_affect", "amount"), &Environment::set_ssao_ao_channel_affect); ClassDB::bind_method(D_METHOD("get_ssao_ao_channel_affect"), &Environment::get_ssao_ao_channel_affect); - ClassDB::bind_method(D_METHOD("set_ssao_blur", "mode"), &Environment::set_ssao_blur); ClassDB::bind_method(D_METHOD("get_ssao_blur"), &Environment::get_ssao_blur); - ClassDB::bind_method(D_METHOD("set_ssao_edge_sharpness", "edge_sharpness"), &Environment::set_ssao_edge_sharpness); ClassDB::bind_method(D_METHOD("get_ssao_edge_sharpness"), &Environment::get_ssao_edge_sharpness); @@ -1073,42 +1136,33 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_blur", PROPERTY_HINT_ENUM, "Disabled,1x1,2x2,3x3"), "set_ssao_blur", "get_ssao_blur"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_edge_sharpness", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_ssao_edge_sharpness", "get_ssao_edge_sharpness"); + // SDFGI + ClassDB::bind_method(D_METHOD("set_sdfgi_enabled", "enabled"), &Environment::set_sdfgi_enabled); ClassDB::bind_method(D_METHOD("is_sdfgi_enabled"), &Environment::is_sdfgi_enabled); - ClassDB::bind_method(D_METHOD("set_sdfgi_cascades", "amount"), &Environment::set_sdfgi_cascades); ClassDB::bind_method(D_METHOD("get_sdfgi_cascades"), &Environment::get_sdfgi_cascades); - - ClassDB::bind_method(D_METHOD("set_sdfgi_min_cell_size", "strength"), &Environment::set_sdfgi_min_cell_size); + ClassDB::bind_method(D_METHOD("set_sdfgi_min_cell_size", "size"), &Environment::set_sdfgi_min_cell_size); ClassDB::bind_method(D_METHOD("get_sdfgi_min_cell_size"), &Environment::get_sdfgi_min_cell_size); - - ClassDB::bind_method(D_METHOD("set_sdfgi_max_distance", "strength"), &Environment::set_sdfgi_max_distance); + ClassDB::bind_method(D_METHOD("set_sdfgi_max_distance", "distance"), &Environment::set_sdfgi_max_distance); ClassDB::bind_method(D_METHOD("get_sdfgi_max_distance"), &Environment::get_sdfgi_max_distance); - - ClassDB::bind_method(D_METHOD("set_sdfgi_cascade0_distance", "strength"), &Environment::set_sdfgi_cascade0_distance); + ClassDB::bind_method(D_METHOD("set_sdfgi_cascade0_distance", "distance"), &Environment::set_sdfgi_cascade0_distance); ClassDB::bind_method(D_METHOD("get_sdfgi_cascade0_distance"), &Environment::get_sdfgi_cascade0_distance); - + ClassDB::bind_method(D_METHOD("set_sdfgi_y_scale", "scale"), &Environment::set_sdfgi_y_scale); + ClassDB::bind_method(D_METHOD("get_sdfgi_y_scale"), &Environment::get_sdfgi_y_scale); ClassDB::bind_method(D_METHOD("set_sdfgi_use_occlusion", "enable"), &Environment::set_sdfgi_use_occlusion); ClassDB::bind_method(D_METHOD("is_sdfgi_using_occlusion"), &Environment::is_sdfgi_using_occlusion); - ClassDB::bind_method(D_METHOD("set_sdfgi_use_multi_bounce", "enable"), &Environment::set_sdfgi_use_multi_bounce); ClassDB::bind_method(D_METHOD("is_sdfgi_using_multi_bounce"), &Environment::is_sdfgi_using_multi_bounce); - ClassDB::bind_method(D_METHOD("set_sdfgi_read_sky_light", "enable"), &Environment::set_sdfgi_read_sky_light); ClassDB::bind_method(D_METHOD("is_sdfgi_reading_sky_light"), &Environment::is_sdfgi_reading_sky_light); - ClassDB::bind_method(D_METHOD("set_sdfgi_energy", "amount"), &Environment::set_sdfgi_energy); ClassDB::bind_method(D_METHOD("get_sdfgi_energy"), &Environment::get_sdfgi_energy); - ClassDB::bind_method(D_METHOD("set_sdfgi_normal_bias", "bias"), &Environment::set_sdfgi_normal_bias); ClassDB::bind_method(D_METHOD("get_sdfgi_normal_bias"), &Environment::get_sdfgi_normal_bias); - ClassDB::bind_method(D_METHOD("set_sdfgi_probe_bias", "bias"), &Environment::set_sdfgi_probe_bias); ClassDB::bind_method(D_METHOD("get_sdfgi_probe_bias"), &Environment::get_sdfgi_probe_bias); - ClassDB::bind_method(D_METHOD("set_sdfgi_y_scale", "scale"), &Environment::set_sdfgi_y_scale); - ClassDB::bind_method(D_METHOD("get_sdfgi_y_scale"), &Environment::get_sdfgi_y_scale); - ADD_GROUP("SDFGI", "sdfgi_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_enabled"), "set_sdfgi_enabled", "is_sdfgi_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_multi_bounce"), "set_sdfgi_use_multi_bounce", "is_sdfgi_using_multi_bounce"); @@ -1123,77 +1177,120 @@ void Environment::_bind_methods() { 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"); + // Glow + ClassDB::bind_method(D_METHOD("set_glow_enabled", "enabled"), &Environment::set_glow_enabled); ClassDB::bind_method(D_METHOD("is_glow_enabled"), &Environment::is_glow_enabled); - - ClassDB::bind_method(D_METHOD("set_glow_level", "idx", "enabled"), &Environment::set_glow_level); + ClassDB::bind_method(D_METHOD("set_glow_level_enabled", "idx", "enabled"), &Environment::set_glow_level_enabled); ClassDB::bind_method(D_METHOD("is_glow_level_enabled", "idx"), &Environment::is_glow_level_enabled); - ClassDB::bind_method(D_METHOD("set_glow_intensity", "intensity"), &Environment::set_glow_intensity); ClassDB::bind_method(D_METHOD("get_glow_intensity"), &Environment::get_glow_intensity); - ClassDB::bind_method(D_METHOD("set_glow_strength", "strength"), &Environment::set_glow_strength); ClassDB::bind_method(D_METHOD("get_glow_strength"), &Environment::get_glow_strength); - ClassDB::bind_method(D_METHOD("set_glow_mix", "mix"), &Environment::set_glow_mix); ClassDB::bind_method(D_METHOD("get_glow_mix"), &Environment::get_glow_mix); - ClassDB::bind_method(D_METHOD("set_glow_bloom", "amount"), &Environment::set_glow_bloom); ClassDB::bind_method(D_METHOD("get_glow_bloom"), &Environment::get_glow_bloom); - ClassDB::bind_method(D_METHOD("set_glow_blend_mode", "mode"), &Environment::set_glow_blend_mode); ClassDB::bind_method(D_METHOD("get_glow_blend_mode"), &Environment::get_glow_blend_mode); - ClassDB::bind_method(D_METHOD("set_glow_hdr_bleed_threshold", "threshold"), &Environment::set_glow_hdr_bleed_threshold); ClassDB::bind_method(D_METHOD("get_glow_hdr_bleed_threshold"), &Environment::get_glow_hdr_bleed_threshold); - - ClassDB::bind_method(D_METHOD("set_glow_hdr_luminance_cap", "amount"), &Environment::set_glow_hdr_luminance_cap); - ClassDB::bind_method(D_METHOD("get_glow_hdr_luminance_cap"), &Environment::get_glow_hdr_luminance_cap); - ClassDB::bind_method(D_METHOD("set_glow_hdr_bleed_scale", "scale"), &Environment::set_glow_hdr_bleed_scale); ClassDB::bind_method(D_METHOD("get_glow_hdr_bleed_scale"), &Environment::get_glow_hdr_bleed_scale); + ClassDB::bind_method(D_METHOD("set_glow_hdr_luminance_cap", "amount"), &Environment::set_glow_hdr_luminance_cap); + ClassDB::bind_method(D_METHOD("get_glow_hdr_luminance_cap"), &Environment::get_glow_hdr_luminance_cap); ADD_GROUP("Glow", "glow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_enabled"), "set_glow_enabled", "is_glow_enabled"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/1"), "set_glow_level", "is_glow_level_enabled", 0); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/2"), "set_glow_level", "is_glow_level_enabled", 1); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/3"), "set_glow_level", "is_glow_level_enabled", 2); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/4"), "set_glow_level", "is_glow_level_enabled", 3); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/5"), "set_glow_level", "is_glow_level_enabled", 4); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/6"), "set_glow_level", "is_glow_level_enabled", 5); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/7"), "set_glow_level", "is_glow_level_enabled", 6); - + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/1"), "set_glow_level_enabled", "is_glow_level_enabled", 0); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/2"), "set_glow_level_enabled", "is_glow_level_enabled", 1); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/3"), "set_glow_level_enabled", "is_glow_level_enabled", 2); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/4"), "set_glow_level_enabled", "is_glow_level_enabled", 3); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/5"), "set_glow_level_enabled", "is_glow_level_enabled", 4); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/6"), "set_glow_level_enabled", "is_glow_level_enabled", 5); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/7"), "set_glow_level_enabled", "is_glow_level_enabled", 6); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_intensity", PROPERTY_HINT_RANGE, "0.0,8.0,0.01"), "set_glow_intensity", "get_glow_intensity"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_mix", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_glow_mix", "get_glow_mix"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_strength", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"), "set_glow_strength", "get_glow_strength"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_mix", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_glow_mix", "get_glow_mix"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_bloom", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_glow_bloom", "get_glow_bloom"); ADD_PROPERTY(PropertyInfo(Variant::INT, "glow_blend_mode", PROPERTY_HINT_ENUM, "Additive,Screen,Softlight,Replace,Mix"), "set_glow_blend_mode", "get_glow_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_threshold", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_threshold", "get_glow_hdr_bleed_threshold"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_luminance_cap", PROPERTY_HINT_RANGE, "0.0,256.0,0.01"), "set_glow_hdr_luminance_cap", "get_glow_hdr_luminance_cap"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_luminance_cap", PROPERTY_HINT_RANGE, "0.0,256.0,0.01"), "set_glow_hdr_luminance_cap", "get_glow_hdr_luminance_cap"); - ClassDB::bind_method(D_METHOD("set_adjustment_enable", "enabled"), &Environment::set_adjustment_enable); - ClassDB::bind_method(D_METHOD("is_adjustment_enabled"), &Environment::is_adjustment_enabled); + // Fog + ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled); + ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled); + ClassDB::bind_method(D_METHOD("set_fog_color", "color"), &Environment::set_fog_color); + ClassDB::bind_method(D_METHOD("get_fog_color"), &Environment::get_fog_color); + ClassDB::bind_method(D_METHOD("set_fog_sun_color", "color"), &Environment::set_fog_sun_color); + ClassDB::bind_method(D_METHOD("get_fog_sun_color"), &Environment::get_fog_sun_color); + ClassDB::bind_method(D_METHOD("set_fog_sun_amount", "amount"), &Environment::set_fog_sun_amount); + ClassDB::bind_method(D_METHOD("get_fog_sun_amount"), &Environment::get_fog_sun_amount); + + ClassDB::bind_method(D_METHOD("set_fog_depth_enabled", "enabled"), &Environment::set_fog_depth_enabled); + ClassDB::bind_method(D_METHOD("is_fog_depth_enabled"), &Environment::is_fog_depth_enabled); + ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "distance"), &Environment::set_fog_depth_begin); + ClassDB::bind_method(D_METHOD("get_fog_depth_begin"), &Environment::get_fog_depth_begin); + ClassDB::bind_method(D_METHOD("set_fog_depth_end", "distance"), &Environment::set_fog_depth_end); + ClassDB::bind_method(D_METHOD("get_fog_depth_end"), &Environment::get_fog_depth_end); + ClassDB::bind_method(D_METHOD("set_fog_depth_curve", "curve"), &Environment::set_fog_depth_curve); + ClassDB::bind_method(D_METHOD("get_fog_depth_curve"), &Environment::get_fog_depth_curve); + ClassDB::bind_method(D_METHOD("set_fog_transmit_enabled", "enabled"), &Environment::set_fog_transmit_enabled); + ClassDB::bind_method(D_METHOD("is_fog_transmit_enabled"), &Environment::is_fog_transmit_enabled); + ClassDB::bind_method(D_METHOD("set_fog_transmit_curve", "curve"), &Environment::set_fog_transmit_curve); + ClassDB::bind_method(D_METHOD("get_fog_transmit_curve"), &Environment::get_fog_transmit_curve); + + ClassDB::bind_method(D_METHOD("set_fog_height_enabled", "enabled"), &Environment::set_fog_height_enabled); + ClassDB::bind_method(D_METHOD("is_fog_height_enabled"), &Environment::is_fog_height_enabled); + ClassDB::bind_method(D_METHOD("set_fog_height_min", "height"), &Environment::set_fog_height_min); + ClassDB::bind_method(D_METHOD("get_fog_height_min"), &Environment::get_fog_height_min); + ClassDB::bind_method(D_METHOD("set_fog_height_max", "height"), &Environment::set_fog_height_max); + ClassDB::bind_method(D_METHOD("get_fog_height_max"), &Environment::get_fog_height_max); + ClassDB::bind_method(D_METHOD("set_fog_height_curve", "curve"), &Environment::set_fog_height_curve); + ClassDB::bind_method(D_METHOD("get_fog_height_curve"), &Environment::get_fog_height_curve); + + ADD_GROUP("Fog", "fog_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_color"), "set_fog_color", "get_fog_color"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_sun_color"), "set_fog_sun_color", "get_fog_sun_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount"); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_end", PROPERTY_HINT_RANGE, "0,4000,0.1,or_greater"), "set_fog_depth_end", "get_fog_depth_end"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve"); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_height_enabled"), "set_fog_height_enabled", "is_fog_height_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_min", "get_fog_height_min"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_max", "get_fog_height_max"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve"); + + // Adjustment + + ClassDB::bind_method(D_METHOD("set_adjustment_enabled", "enabled"), &Environment::set_adjustment_enabled); + ClassDB::bind_method(D_METHOD("is_adjustment_enabled"), &Environment::is_adjustment_enabled); ClassDB::bind_method(D_METHOD("set_adjustment_brightness", "brightness"), &Environment::set_adjustment_brightness); ClassDB::bind_method(D_METHOD("get_adjustment_brightness"), &Environment::get_adjustment_brightness); - ClassDB::bind_method(D_METHOD("set_adjustment_contrast", "contrast"), &Environment::set_adjustment_contrast); ClassDB::bind_method(D_METHOD("get_adjustment_contrast"), &Environment::get_adjustment_contrast); - ClassDB::bind_method(D_METHOD("set_adjustment_saturation", "saturation"), &Environment::set_adjustment_saturation); ClassDB::bind_method(D_METHOD("get_adjustment_saturation"), &Environment::get_adjustment_saturation); - ClassDB::bind_method(D_METHOD("set_adjustment_color_correction", "color_correction"), &Environment::set_adjustment_color_correction); ClassDB::bind_method(D_METHOD("get_adjustment_color_correction"), &Environment::get_adjustment_color_correction); ADD_GROUP("Adjustments", "adjustment_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "adjustment_enabled"), "set_adjustment_enable", "is_adjustment_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "adjustment_enabled"), "set_adjustment_enabled", "is_adjustment_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_brightness", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_brightness", "get_adjustment_brightness"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_contrast", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_contrast", "get_adjustment_contrast"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_adjustment_color_correction", "get_adjustment_color_correction"); + // Constants + BIND_ENUM_CONSTANT(BG_CLEAR_COLOR); BIND_ENUM_CONSTANT(BG_COLOR); BIND_ENUM_CONSTANT(BG_SKY); @@ -1211,267 +1308,49 @@ void Environment::_bind_methods() { BIND_ENUM_CONSTANT(REFLECTION_SOURCE_DISABLED); BIND_ENUM_CONSTANT(REFLECTION_SOURCE_SKY); + BIND_ENUM_CONSTANT(TONE_MAPPER_LINEAR); + BIND_ENUM_CONSTANT(TONE_MAPPER_REINHARDT); + BIND_ENUM_CONSTANT(TONE_MAPPER_FILMIC); + BIND_ENUM_CONSTANT(TONE_MAPPER_ACES); + BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_ADDITIVE); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SCREEN); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SOFTLIGHT); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_MIX); - BIND_ENUM_CONSTANT(TONE_MAPPER_LINEAR); - BIND_ENUM_CONSTANT(TONE_MAPPER_REINHARDT); - BIND_ENUM_CONSTANT(TONE_MAPPER_FILMIC); - BIND_ENUM_CONSTANT(TONE_MAPPER_ACES); - BIND_ENUM_CONSTANT(SSAO_BLUR_DISABLED); BIND_ENUM_CONSTANT(SSAO_BLUR_1x1); BIND_ENUM_CONSTANT(SSAO_BLUR_2x2); BIND_ENUM_CONSTANT(SSAO_BLUR_3x3); + + BIND_ENUM_CONSTANT(SDFGI_CASCADES_4); + BIND_ENUM_CONSTANT(SDFGI_CASCADES_6); + BIND_ENUM_CONSTANT(SDFGI_CASCADES_8); + + BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_DISABLED); + BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_75_PERCENT); + BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_50_PERCENT); } Environment::Environment() { environment = RS::get_singleton()->environment_create(); - bg_mode = BG_CLEAR_COLOR; - bg_sky_custom_fov = 0; - bg_energy = 1.0; - bg_canvas_max_layer = 0; - ambient_energy = 1.0; - //ambient_sky_contribution = 1.0; - ambient_source = AMBIENT_SOURCE_BG; - reflection_source = REFLECTION_SOURCE_BG; - set_ambient_light_sky_contribution(1.0); - set_camera_feed_id(1); - - tone_mapper = TONE_MAPPER_LINEAR; - tonemap_exposure = 1.0; - tonemap_white = 1.0; - tonemap_auto_exposure = false; - tonemap_auto_exposure_max = 8; - tonemap_auto_exposure_min = 0.05; - tonemap_auto_exposure_speed = 0.5; - tonemap_auto_exposure_grey = 0.4; - - set_tonemapper(tone_mapper); //update - - adjustment_enabled = false; - adjustment_contrast = 1.0; - adjustment_saturation = 1.0; - adjustment_brightness = 1.0; - - set_adjustment_enable(adjustment_enabled); //update - - ssr_enabled = false; - ssr_max_steps = 64; - ssr_fade_in = 0.15; - ssr_fade_out = 2.0; - ssr_depth_tolerance = 0.2; - - ssao_enabled = false; - ssao_radius = 1; - ssao_intensity = 1; - ssao_bias = 0.01; - ssao_direct_light_affect = 0.0; - ssao_ao_channel_affect = 0.0; - ssao_blur = SSAO_BLUR_3x3; - set_ssao_edge_sharpness(4); - - glow_enabled = false; - glow_levels = (1 << 2) | (1 << 4); - glow_intensity = 0.8; - glow_strength = 1.0; - glow_mix = 0.05; - glow_bloom = 0.0; - glow_blend_mode = GLOW_BLEND_MODE_SOFTLIGHT; - glow_hdr_bleed_threshold = 1.0; - glow_hdr_luminance_cap = 12.0; - glow_hdr_bleed_scale = 2.0; - - fog_enabled = false; - fog_color = Color(0.5, 0.5, 0.5); - fog_sun_color = Color(0.8, 0.8, 0.0); - fog_sun_amount = 0; - - fog_depth_enabled = true; - - fog_depth_begin = 10; - fog_depth_end = 100; - fog_depth_curve = 1; - - fog_transmit_enabled = false; - fog_transmit_curve = 1; - - fog_height_enabled = false; - fog_height_min = 10; - fog_height_max = 0; - fog_height_curve = 1; - - set_fog_color(Color(0.5, 0.6, 0.7)); - set_fog_sun_color(Color(1.0, 0.9, 0.7)); - - sdfgi_enabled = false; - sdfgi_cascades = SDFGI_CASCADES_6; - sdfgi_min_cell_size = 0.2; - sdfgi_use_occlusion = false; - sdfgi_use_multibounce = false; - sdfgi_read_sky_light = false; - sdfgi_enhance_ssr = false; - sdfgi_energy = 1.0; - sdfgi_normal_bias = 1.1; - sdfgi_probe_bias = 1.1; - sdfgi_y_scale = SDFGI_Y_SCALE_DISABLED; + set_camera_feed_id(bg_camera_feed_id); + _update_ambient_light(); + _update_tonemap(); + _update_ssr(); + _update_ssao(); _update_sdfgi(); -} - -Environment::~Environment() { - RS::get_singleton()->free(environment); -} - -////////////////////// + _update_glow(); + _update_fog(); + _update_fog_depth(); + _update_fog_height(); + _update_adjustment(); -void CameraEffects::set_dof_blur_far_enabled(bool p_enable) { - dof_blur_far_enabled = p_enable; - RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); -} - -bool CameraEffects::is_dof_blur_far_enabled() const { - return dof_blur_far_enabled; -} - -void CameraEffects::set_dof_blur_far_distance(float p_distance) { - dof_blur_far_distance = p_distance; - RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); -} - -float CameraEffects::get_dof_blur_far_distance() const { - return dof_blur_far_distance; -} - -void CameraEffects::set_dof_blur_far_transition(float p_distance) { - dof_blur_far_transition = p_distance; - RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); -} - -float CameraEffects::get_dof_blur_far_transition() const { - return dof_blur_far_transition; -} - -void CameraEffects::set_dof_blur_near_enabled(bool p_enable) { - dof_blur_near_enabled = p_enable; - RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); _change_notify(); } -bool CameraEffects::is_dof_blur_near_enabled() const { - return dof_blur_near_enabled; -} - -void CameraEffects::set_dof_blur_near_distance(float p_distance) { - dof_blur_near_distance = p_distance; - RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); -} - -float CameraEffects::get_dof_blur_near_distance() const { - return dof_blur_near_distance; -} - -void CameraEffects::set_dof_blur_near_transition(float p_distance) { - dof_blur_near_transition = p_distance; - RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); -} - -float CameraEffects::get_dof_blur_near_transition() const { - return dof_blur_near_transition; -} - -void CameraEffects::set_dof_blur_amount(float p_amount) { - dof_blur_amount = p_amount; - RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); -} - -float CameraEffects::get_dof_blur_amount() const { - return dof_blur_amount; -} - -void CameraEffects::set_override_exposure_enabled(bool p_enabled) { - override_exposure_enabled = p_enabled; - RS::get_singleton()->camera_effects_set_custom_exposure(camera_effects, override_exposure_enabled, override_exposure); -} - -bool CameraEffects::is_override_exposure_enabled() const { - return override_exposure_enabled; -} - -void CameraEffects::set_override_exposure(float p_exposure) { - override_exposure = p_exposure; - RS::get_singleton()->camera_effects_set_custom_exposure(camera_effects, override_exposure_enabled, override_exposure); -} - -float CameraEffects::get_override_exposure() const { - return override_exposure; -} - -RID CameraEffects::get_rid() const { - return camera_effects; -} - -void CameraEffects::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &CameraEffects::set_dof_blur_far_enabled); - ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &CameraEffects::is_dof_blur_far_enabled); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "intensity"), &CameraEffects::set_dof_blur_far_distance); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &CameraEffects::get_dof_blur_far_distance); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "intensity"), &CameraEffects::set_dof_blur_far_transition); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &CameraEffects::get_dof_blur_far_transition); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &CameraEffects::set_dof_blur_near_enabled); - ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &CameraEffects::is_dof_blur_near_enabled); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "intensity"), &CameraEffects::set_dof_blur_near_distance); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &CameraEffects::get_dof_blur_near_distance); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "intensity"), &CameraEffects::set_dof_blur_near_transition); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &CameraEffects::get_dof_blur_near_transition); - - ClassDB::bind_method(D_METHOD("set_dof_blur_amount", "intensity"), &CameraEffects::set_dof_blur_amount); - ClassDB::bind_method(D_METHOD("get_dof_blur_amount"), &CameraEffects::get_dof_blur_amount); - - ClassDB::bind_method(D_METHOD("set_override_exposure_enabled", "enable"), &CameraEffects::set_override_exposure_enabled); - ClassDB::bind_method(D_METHOD("is_override_exposure_enabled"), &CameraEffects::is_override_exposure_enabled); - - ClassDB::bind_method(D_METHOD("set_override_exposure", "exposure"), &CameraEffects::set_override_exposure); - ClassDB::bind_method(D_METHOD("get_override_exposure"), &CameraEffects::get_override_exposure); - - ADD_GROUP("DOF Blur", "dof_blur_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_amount", "get_dof_blur_amount"); - ADD_GROUP("Override Exposure", "override_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_exposure_enable"), "set_override_exposure_enabled", "is_override_exposure_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "override_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_override_exposure", "get_override_exposure"); -} - -CameraEffects::CameraEffects() { - camera_effects = RS::get_singleton()->camera_effects_create(); - - dof_blur_far_enabled = false; - dof_blur_far_distance = 10; - dof_blur_far_transition = 5; - - dof_blur_near_enabled = false; - dof_blur_near_distance = 2; - dof_blur_near_transition = 1; - - set_dof_blur_amount(0.1); - - override_exposure_enabled = false; - set_override_exposure(1.0); -} - -CameraEffects::~CameraEffects() { - RS::get_singleton()->free(camera_effects); +Environment::~Environment() { + RS::get_singleton()->free(environment); } diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 83a5fe939c..5dbeeb2fc8 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -41,7 +41,6 @@ class Environment : public Resource { public: enum BGMode { - BG_CLEAR_COLOR, BG_COLOR, BG_SKY, @@ -68,22 +67,14 @@ public: TONE_MAPPER_LINEAR, TONE_MAPPER_REINHARDT, TONE_MAPPER_FILMIC, - TONE_MAPPER_ACES - }; - - enum GlowBlendMode { - GLOW_BLEND_MODE_ADDITIVE, - GLOW_BLEND_MODE_SCREEN, - GLOW_BLEND_MODE_SOFTLIGHT, - GLOW_BLEND_MODE_REPLACE, - GLOW_BLEND_MODE_MIX, + TONE_MAPPER_ACES, }; enum SSAOBlur { SSAO_BLUR_DISABLED, SSAO_BLUR_1x1, SSAO_BLUR_2x2, - SSAO_BLUR_3x3 + SSAO_BLUR_3x3, }; enum SDFGICascades { @@ -98,97 +89,121 @@ public: SDFGI_Y_SCALE_50_PERCENT, }; + enum GlowBlendMode { + GLOW_BLEND_MODE_ADDITIVE, + GLOW_BLEND_MODE_SCREEN, + GLOW_BLEND_MODE_SOFTLIGHT, + GLOW_BLEND_MODE_REPLACE, + GLOW_BLEND_MODE_MIX, + }; + private: RID environment; + // Background BGMode bg_mode = BG_CLEAR_COLOR; Ref<Sky> bg_sky; - float bg_sky_custom_fov; - Vector3 sky_rotation; + float bg_sky_custom_fov = 0; + Vector3 bg_sky_rotation; Color bg_color; - float bg_energy; - int bg_canvas_max_layer; + float bg_energy = 1.0; + int bg_canvas_max_layer = 0; + int bg_camera_feed_id = 1; + + // Ambient light Color ambient_color; - float ambient_energy; + AmbientSource ambient_source = AMBIENT_SOURCE_BG; + float ambient_energy = 1.0; + float ambient_sky_contribution = 1.0; + ReflectionSource reflection_source = REFLECTION_SOURCE_BG; Color ao_color; - float ambient_sky_contribution; - int camera_feed_id; - AmbientSource ambient_source; - ReflectionSource reflection_source; + void _update_ambient_light(); + // Tonemap ToneMapper tone_mapper = TONE_MAPPER_LINEAR; - float tonemap_exposure; - float tonemap_white; - bool tonemap_auto_exposure; - float tonemap_auto_exposure_max; - float tonemap_auto_exposure_min; - float tonemap_auto_exposure_speed; - float tonemap_auto_exposure_grey; - - bool adjustment_enabled; - float adjustment_contrast; - float adjustment_saturation; - float adjustment_brightness; - Ref<Texture2D> adjustment_color_correction; - - bool ssr_enabled; - int ssr_max_steps; - float ssr_fade_in; - float ssr_fade_out; - float ssr_depth_tolerance; - - bool ssao_enabled; - float ssao_radius; - float ssao_intensity; - float ssao_bias; - float ssao_direct_light_affect; - float ssao_ao_channel_affect; + float tonemap_exposure = 1.0; + float tonemap_white = 1.0; + bool tonemap_auto_exposure_enabled = false; + float tonemap_auto_exposure_min = 0.05; + float tonemap_auto_exposure_max = 8; + float tonemap_auto_exposure_speed = 0.5; + float tonemap_auto_exposure_grey = 0.4; + void _update_tonemap(); + + // SSR + bool ssr_enabled = false; + int ssr_max_steps = 64; + float ssr_fade_in = 0.15; + float ssr_fade_out = 2.0; + float ssr_depth_tolerance = 0.2; + void _update_ssr(); + + // SSAO + bool ssao_enabled = false; + float ssao_radius = 1.0; + float ssao_intensity = 1.0; + float ssao_bias = 0.01; + float ssao_direct_light_affect = 0.0; + float ssao_ao_channel_affect = 0.0; SSAOBlur ssao_blur = SSAO_BLUR_3x3; - float ssao_edge_sharpness; - - bool glow_enabled; - int glow_levels; - float glow_intensity; - float glow_strength; - float glow_mix; - float glow_bloom; - GlowBlendMode glow_blend_mode = GLOW_BLEND_MODE_ADDITIVE; - float glow_hdr_bleed_threshold; - float glow_hdr_bleed_scale; - float glow_hdr_luminance_cap; - - bool fog_enabled; - Color fog_color; - Color fog_sun_color; - float fog_sun_amount; - - bool fog_depth_enabled; - float fog_depth_begin; - float fog_depth_end; - float fog_depth_curve; - - bool fog_transmit_enabled; - float fog_transmit_curve; - - bool fog_height_enabled; - float fog_height_min; - float fog_height_max; - float fog_height_curve; - - bool sdfgi_enabled; - SDFGICascades sdfgi_cascades; - float sdfgi_min_cell_size; - bool sdfgi_use_occlusion; - bool sdfgi_use_multibounce; - bool sdfgi_read_sky_light; - bool sdfgi_enhance_ssr; - float sdfgi_energy; - float sdfgi_normal_bias; - float sdfgi_probe_bias; - SDFGIYScale sdfgi_y_scale; - + float ssao_edge_sharpness = 4.0; + void _update_ssao(); + + // SDFGI + bool sdfgi_enabled = false; + SDFGICascades sdfgi_cascades = SDFGI_CASCADES_6; + float sdfgi_min_cell_size = 0.2; + SDFGIYScale sdfgi_y_scale = SDFGI_Y_SCALE_DISABLED; + bool sdfgi_use_occlusion = false; + bool sdfgi_use_multibounce = false; + bool sdfgi_read_sky_light = false; + float sdfgi_energy = 1.0; + float sdfgi_normal_bias = 1.1; + float sdfgi_probe_bias = 1.1; void _update_sdfgi(); + // Glow + bool glow_enabled = false; + int glow_levels = (1 << 2) | (1 << 4); + float glow_intensity = 0.8; + float glow_strength = 1.0; + float glow_mix = 0.05; + float glow_bloom = 0.0; + GlowBlendMode glow_blend_mode = GLOW_BLEND_MODE_SOFTLIGHT; + float glow_hdr_bleed_threshold = 1.0; + float glow_hdr_bleed_scale = 2.0; + float glow_hdr_luminance_cap = 12.0; + void _update_glow(); + + // Fog + bool fog_enabled = false; + Color fog_color = Color(0.5, 0.6, 0.7); + Color fog_sun_color = Color(1.0, 0.9, 0.7); + float fog_sun_amount = 0.0; + void _update_fog(); + + bool fog_depth_enabled = true; + float fog_depth_begin = 10.0; + float fog_depth_end = 100.0; + float fog_depth_curve = 1.0; + bool fog_transmit_enabled = false; + float fog_transmit_curve = 1.0; + void _update_fog_depth(); + + bool fog_height_enabled = false; + float fog_height_min = 10.0; + float fog_height_max = 0.0; + float fog_height_curve = 1.0; + void _update_fog_height(); + + // Adjustment + bool adjustment_enabled = false; + float adjustment_brightness = 1.0; + float adjustment_contrast = 1.0; + float adjustment_saturation = 1.0; + Ref<Texture2D> adjustment_color_correction; + void _update_adjustment(); + protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const; @@ -198,228 +213,179 @@ protected: #endif public: - void set_background(BGMode p_bg); + virtual RID get_rid() const; + // Background + void set_background(BGMode p_bg); + BGMode get_background() const; void set_sky(const Ref<Sky> &p_sky); + Ref<Sky> get_sky() const; void set_sky_custom_fov(float p_scale); + float get_sky_custom_fov() const; void set_sky_rotation(const Vector3 &p_rotation); + Vector3 get_sky_rotation() const; void set_bg_color(const Color &p_color); + Color get_bg_color() const; void set_bg_energy(float p_energy); + float get_bg_energy() const; void set_canvas_max_layer(int p_max_layer); + int get_canvas_max_layer() const; + void set_camera_feed_id(int p_id); + int get_camera_feed_id() const; + + // Ambient light void set_ambient_light_color(const Color &p_color); - void set_ambient_light_energy(float p_energy); - void set_ambient_light_sky_contribution(float p_energy); - void set_camera_feed_id(int p_camera_feed_id); + Color get_ambient_light_color() const; void set_ambient_source(AmbientSource p_source); AmbientSource get_ambient_source() const; - void set_reflection_source(ReflectionSource p_source); - ReflectionSource get_reflection_source() const; - - BGMode get_background() const; - Ref<Sky> get_sky() const; - float get_sky_custom_fov() const; - Vector3 get_sky_rotation() const; - Color get_bg_color() const; - float get_bg_energy() const; - int get_canvas_max_layer() const; - Color get_ambient_light_color() const; + void set_ambient_light_energy(float p_energy); float get_ambient_light_energy() const; + void set_ambient_light_sky_contribution(float p_ratio); float get_ambient_light_sky_contribution() const; - int get_camera_feed_id() const; + void set_reflection_source(ReflectionSource p_source); + ReflectionSource get_reflection_source() const; + void set_ao_color(const Color &p_color); + Color get_ao_color() const; + // Tonemap void set_tonemapper(ToneMapper p_tone_mapper); ToneMapper get_tonemapper() const; - void set_tonemap_exposure(float p_exposure); float get_tonemap_exposure() const; - void set_tonemap_white(float p_white); float get_tonemap_white() const; - - void set_tonemap_auto_exposure(bool p_enabled); - bool get_tonemap_auto_exposure() const; - - void set_tonemap_auto_exposure_max(float p_auto_exposure_max); - float get_tonemap_auto_exposure_max() const; - + void set_tonemap_auto_exposure_enabled(bool p_enabled); + bool is_tonemap_auto_exposure_enabled() const; void set_tonemap_auto_exposure_min(float p_auto_exposure_min); float get_tonemap_auto_exposure_min() const; - + void set_tonemap_auto_exposure_max(float p_auto_exposure_max); + float get_tonemap_auto_exposure_max() const; void set_tonemap_auto_exposure_speed(float p_auto_exposure_speed); float get_tonemap_auto_exposure_speed() const; - void set_tonemap_auto_exposure_grey(float p_auto_exposure_grey); float get_tonemap_auto_exposure_grey() const; - void set_adjustment_enable(bool p_enable); - bool is_adjustment_enabled() const; - - void set_adjustment_brightness(float p_brightness); - float get_adjustment_brightness() const; - - void set_adjustment_contrast(float p_contrast); - float get_adjustment_contrast() const; - - void set_adjustment_saturation(float p_saturation); - float get_adjustment_saturation() const; - - void set_adjustment_color_correction(const Ref<Texture2D> &p_ramp); - Ref<Texture2D> get_adjustment_color_correction() const; - - void set_ssr_enabled(bool p_enable); + // SSR + void set_ssr_enabled(bool p_enabled); bool is_ssr_enabled() const; - void set_ssr_max_steps(int p_steps); int get_ssr_max_steps() const; - void set_ssr_fade_in(float p_fade_in); float get_ssr_fade_in() const; - void set_ssr_fade_out(float p_fade_out); float get_ssr_fade_out() const; - void set_ssr_depth_tolerance(float p_depth_tolerance); float get_ssr_depth_tolerance() const; - void set_ssao_enabled(bool p_enable); + // SSAO + void set_ssao_enabled(bool p_enabled); bool is_ssao_enabled() const; - void set_ssao_radius(float p_radius); float get_ssao_radius() const; - void set_ssao_intensity(float p_intensity); float get_ssao_intensity() const; - void set_ssao_bias(float p_bias); float get_ssao_bias() const; - void set_ssao_direct_light_affect(float p_direct_light_affect); float get_ssao_direct_light_affect() const; - void set_ssao_ao_channel_affect(float p_ao_channel_affect); float get_ssao_ao_channel_affect() const; - - void set_ao_color(const Color &p_color); - Color get_ao_color() const; - void set_ssao_blur(SSAOBlur p_blur); SSAOBlur get_ssao_blur() const; - void set_ssao_edge_sharpness(float p_edge_sharpness); float get_ssao_edge_sharpness() const; + // SDFGI + void set_sdfgi_enabled(bool p_enabled); + bool is_sdfgi_enabled() const; + void set_sdfgi_cascades(SDFGICascades p_cascades); + SDFGICascades get_sdfgi_cascades() const; + void set_sdfgi_min_cell_size(float p_size); + float get_sdfgi_min_cell_size() const; + void set_sdfgi_max_distance(float p_distance); + float get_sdfgi_max_distance() const; + void set_sdfgi_cascade0_distance(float p_distance); + float get_sdfgi_cascade0_distance() const; + void set_sdfgi_y_scale(SDFGIYScale p_y_scale); + SDFGIYScale get_sdfgi_y_scale() const; + void set_sdfgi_use_occlusion(bool p_enabled); + bool is_sdfgi_using_occlusion() const; + void set_sdfgi_use_multi_bounce(bool p_enabled); + bool is_sdfgi_using_multi_bounce() const; + void set_sdfgi_read_sky_light(bool p_enabled); + bool is_sdfgi_reading_sky_light() const; + void set_sdfgi_energy(float p_energy); + float get_sdfgi_energy() const; + void set_sdfgi_normal_bias(float p_bias); + float get_sdfgi_normal_bias() const; + void set_sdfgi_probe_bias(float p_bias); + float get_sdfgi_probe_bias() const; + + // Glow void set_glow_enabled(bool p_enabled); bool is_glow_enabled() const; - - void set_glow_level(int p_level, bool p_enabled); + void set_glow_level_enabled(int p_level, bool p_enabled); bool is_glow_level_enabled(int p_level) const; - void set_glow_intensity(float p_intensity); float get_glow_intensity() const; - void set_glow_strength(float p_strength); float get_glow_strength() const; - void set_glow_mix(float p_mix); float get_glow_mix() const; - void set_glow_bloom(float p_threshold); float get_glow_bloom() const; - void set_glow_blend_mode(GlowBlendMode p_mode); GlowBlendMode get_glow_blend_mode() const; - void set_glow_hdr_bleed_threshold(float p_threshold); float get_glow_hdr_bleed_threshold() const; - - void set_glow_hdr_luminance_cap(float p_amount); - float get_glow_hdr_luminance_cap() const; - void set_glow_hdr_bleed_scale(float p_scale); float get_glow_hdr_bleed_scale() const; + void set_glow_hdr_luminance_cap(float p_amount); + float get_glow_hdr_luminance_cap() const; + // Fog void set_fog_enabled(bool p_enabled); bool is_fog_enabled() const; - void set_fog_color(const Color &p_color); Color get_fog_color() const; - void set_fog_sun_color(const Color &p_color); Color get_fog_sun_color() const; - void set_fog_sun_amount(float p_amount); float get_fog_sun_amount() const; void set_fog_depth_enabled(bool p_enabled); bool is_fog_depth_enabled() const; - void set_fog_depth_begin(float p_distance); float get_fog_depth_begin() const; - void set_fog_depth_end(float p_distance); float get_fog_depth_end() const; - void set_fog_depth_curve(float p_curve); float get_fog_depth_curve() const; - void set_fog_transmit_enabled(bool p_enabled); bool is_fog_transmit_enabled() const; - void set_fog_transmit_curve(float p_curve); float get_fog_transmit_curve() const; void set_fog_height_enabled(bool p_enabled); bool is_fog_height_enabled() const; - void set_fog_height_min(float p_distance); float get_fog_height_min() const; - void set_fog_height_max(float p_distance); float get_fog_height_max() const; - void set_fog_height_curve(float p_distance); float get_fog_height_curve() const; - void set_sdfgi_enabled(bool p_enabled); - bool is_sdfgi_enabled() const; - - void set_sdfgi_cascades(SDFGICascades p_cascades); - SDFGICascades get_sdfgi_cascades() const; - - void set_sdfgi_min_cell_size(float p_size); - float get_sdfgi_min_cell_size() const; - - void set_sdfgi_cascade0_distance(float p_size); - float get_sdfgi_cascade0_distance() const; - - void set_sdfgi_max_distance(float p_size); - float get_sdfgi_max_distance() const; - - void set_sdfgi_use_occlusion(bool p_enable); - bool is_sdfgi_using_occlusion() const; - - void set_sdfgi_use_multi_bounce(bool p_enable); - bool is_sdfgi_using_multi_bounce() const; - - void set_sdfgi_use_enhance_ssr(bool p_enable); - bool is_sdfgi_using_enhance_ssr() const; - - void set_sdfgi_read_sky_light(bool p_enable); - bool is_sdfgi_reading_sky_light() const; - - void set_sdfgi_energy(float p_energy); - float get_sdfgi_energy() const; - - void set_sdfgi_normal_bias(float p_bias); - float get_sdfgi_normal_bias() const; - - void set_sdfgi_probe_bias(float p_bias); - float get_sdfgi_probe_bias() const; - - void set_sdfgi_y_scale(SDFGIYScale p_y_scale); - SDFGIYScale get_sdfgi_y_scale() const; - - virtual RID get_rid() const; + // Adjustment + void set_adjustment_enabled(bool p_enabled); + bool is_adjustment_enabled() const; + void set_adjustment_brightness(float p_brightness); + float get_adjustment_brightness() const; + void set_adjustment_contrast(float p_contrast); + float get_adjustment_contrast() const; + void set_adjustment_saturation(float p_saturation); + float get_adjustment_saturation() const; + void set_adjustment_color_correction(const Ref<Texture2D> &p_ramp); + Ref<Texture2D> get_adjustment_color_correction() const; Environment(); ~Environment(); @@ -429,65 +395,9 @@ VARIANT_ENUM_CAST(Environment::BGMode) VARIANT_ENUM_CAST(Environment::AmbientSource) VARIANT_ENUM_CAST(Environment::ReflectionSource) VARIANT_ENUM_CAST(Environment::ToneMapper) -VARIANT_ENUM_CAST(Environment::GlowBlendMode) VARIANT_ENUM_CAST(Environment::SSAOBlur) VARIANT_ENUM_CAST(Environment::SDFGICascades) VARIANT_ENUM_CAST(Environment::SDFGIYScale) - -class CameraEffects : public Resource { - GDCLASS(CameraEffects, Resource); - -private: - RID camera_effects; - - bool dof_blur_far_enabled; - float dof_blur_far_distance; - float dof_blur_far_transition; - - bool dof_blur_near_enabled; - float dof_blur_near_distance; - float dof_blur_near_transition; - - float dof_blur_amount; - - bool override_exposure_enabled; - float override_exposure; - -protected: - static void _bind_methods(); - -public: - void set_dof_blur_far_enabled(bool p_enable); - bool is_dof_blur_far_enabled() const; - - void set_dof_blur_far_distance(float p_distance); - float get_dof_blur_far_distance() const; - - void set_dof_blur_far_transition(float p_distance); - float get_dof_blur_far_transition() const; - - void set_dof_blur_near_enabled(bool p_enable); - bool is_dof_blur_near_enabled() const; - - void set_dof_blur_near_distance(float p_distance); - float get_dof_blur_near_distance() const; - - void set_dof_blur_near_transition(float p_distance); - float get_dof_blur_near_transition() const; - - void set_dof_blur_amount(float p_amount); - float get_dof_blur_amount() const; - - void set_override_exposure_enabled(bool p_enabled); - bool is_override_exposure_enabled() const; - - void set_override_exposure(float p_exposure); - float get_override_exposure() const; - - virtual RID get_rid() const; - - CameraEffects(); - ~CameraEffects(); -}; +VARIANT_ENUM_CAST(Environment::GlowBlendMode) #endif // ENVIRONMENT_H diff --git a/scene/resources/world_3d.h b/scene/resources/world_3d.h index 81a27a7349..02a821637f 100644 --- a/scene/resources/world_3d.h +++ b/scene/resources/world_3d.h @@ -32,6 +32,7 @@ #define WORLD_3D_H #include "core/resource.h" +#include "scene/resources/camera_effects.h" #include "scene/resources/environment.h" #include "servers/physics_server_3d.h" #include "servers/rendering_server.h" diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 0ea11a2670..83e0a797a9 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -181,7 +181,7 @@ bool DisplayServer::screen_is_kept_on() const { return false; } -DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &) { +DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) { ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server."); } @@ -402,7 +402,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_window_list"), &DisplayServer::get_window_list); ClassDB::bind_method(D_METHOD("get_window_at_screen_position", "position"), &DisplayServer::get_window_at_screen_position); - ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i())); + ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "flags", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i())); ClassDB::bind_method(D_METHOD("delete_sub_window", "window_id"), &DisplayServer::delete_sub_window); ClassDB::bind_method(D_METHOD("window_set_title", "title", "window_id"), &DisplayServer::window_set_title, DEFVAL(MAIN_WINDOW_ID)); diff --git a/servers/display_server.h b/servers/display_server.h index 166274f8ed..a4fcd29a4a 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -211,7 +211,7 @@ public: WINDOW_FLAG_NO_FOCUS_BIT = (1 << WINDOW_FLAG_NO_FOCUS) }; - virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i & = Rect2i()); + virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()); virtual void delete_sub_window(WindowID p_id); virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0; diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp index ae549ed2e4..ec74507e03 100644 --- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp +++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "broad_phase_2d_hash_grid.h" +#include "collision_object_2d_sw.h" #include "core/project_settings.h" #define LARGE_ELEMENT_FI 1.01239812 @@ -70,20 +71,22 @@ void BroadPhase2DHashGrid::_unpair_attempt(Element *p_elem, Element *p_with) { void BroadPhase2DHashGrid::_check_motion(Element *p_elem) { for (Map<Element *, PairData *>::Element *E = p_elem->paired.front(); E; E = E->next()) { - bool pairing = p_elem->aabb.intersects(E->key()->aabb); - - if (pairing != E->get()->colliding) { - if (pairing) { - if (pair_callback) { - E->get()->ud = pair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, pair_userdata); - } - } else { - if (unpair_callback) { - unpair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, E->get()->ud, unpair_userdata); - } + bool physical_collision = p_elem->aabb.intersects(E->key()->aabb); + bool logical_collision = p_elem->owner->test_collision_mask(E->key()->owner); + + if (physical_collision) { + if (!E->get()->colliding || (logical_collision && !E->get()->ud && pair_callback)) { + E->get()->ud = pair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, pair_userdata); + } else if (E->get()->colliding && !logical_collision && E->get()->ud && unpair_callback) { + unpair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, E->get()->ud, unpair_userdata); + E->get()->ud = nullptr; } - - E->get()->colliding = pairing; + E->get()->colliding = true; + } else { // No physcial_collision + if (E->get()->colliding && unpair_callback) { + unpair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, E->get()->ud, unpair_userdata); + } + E->get()->colliding = false; } } } @@ -317,23 +320,17 @@ void BroadPhase2DHashGrid::move(ID p_id, const Rect2 &p_aabb) { Element &e = E->get(); - if (p_aabb == e.aabb) { - return; - } - - if (p_aabb != Rect2()) { - _enter_grid(&e, p_aabb, e._static); - } - - if (e.aabb != Rect2()) { - _exit_grid(&e, e.aabb, e._static); + if (p_aabb != e.aabb) { + if (p_aabb != Rect2()) { + _enter_grid(&e, p_aabb, e._static); + } + if (e.aabb != Rect2()) { + _exit_grid(&e, e.aabb, e._static); + } + e.aabb = p_aabb; } - e.aabb = p_aabb; - _check_motion(&e); - - e.aabb = p_aabb; } void BroadPhase2DHashGrid::set_static(ID p_id, bool p_static) { diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index 84a2baaa74..8caa53680d 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -168,10 +168,16 @@ public: return shapes[p_idx].one_way_collision_margin; } - void set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; } + void set_collision_mask(uint32_t p_mask) { + collision_mask = p_mask; + _shape_changed(); + } _FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; } - void set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; } + void set_collision_layer(uint32_t p_layer) { + collision_layer = p_layer; + _shape_changed(); + } _FORCE_INLINE_ uint32_t get_collision_layer() const { return collision_layer; } void remove_shape(Shape2DSW *p_shape); diff --git a/servers/physics_3d/collision_object_3d_sw.h b/servers/physics_3d/collision_object_3d_sw.h index 9506f14402..a3a5787ced 100644 --- a/servers/physics_3d/collision_object_3d_sw.h +++ b/servers/physics_3d/collision_object_3d_sw.h @@ -142,10 +142,16 @@ public: return shapes[p_idx].disabled; } - _FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; } + _FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) { + collision_layer = p_layer; + _shape_changed(); + } _FORCE_INLINE_ uint32_t get_collision_layer() const { return collision_layer; } - _FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; } + _FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) { + collision_mask = p_mask; + _shape_changed(); + } _FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; } _FORCE_INLINE_ bool test_collision_mask(CollisionObject3DSW *p_other) const { diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 080b8c61ad..19b575a259 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -132,13 +132,21 @@ PhysicsDirectBodyState2D::PhysicsDirectBodyState2D() {} /////////////////////////////////////////////////////// -void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape) { - ERR_FAIL_COND(p_shape.is_null()); - shape = p_shape->get_rid(); +void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape_ref) { + ERR_FAIL_COND(p_shape_ref.is_null()); + shape_ref = p_shape_ref; + shape = p_shape_ref->get_rid(); +} + +RES PhysicsShapeQueryParameters2D::get_shape() const { + return shape_ref; } void PhysicsShapeQueryParameters2D::set_shape_rid(const RID &p_shape) { - shape = p_shape; + if (shape != p_shape) { + shape_ref = RES(); + shape = p_shape; + } } RID PhysicsShapeQueryParameters2D::get_shape_rid() const { @@ -212,6 +220,7 @@ bool PhysicsShapeQueryParameters2D::is_collide_with_areas_enabled() const { void PhysicsShapeQueryParameters2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters2D::set_shape); + ClassDB::bind_method(D_METHOD("get_shape"), &PhysicsShapeQueryParameters2D::get_shape); ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters2D::set_shape_rid); ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters2D::get_shape_rid); @@ -240,7 +249,7 @@ void PhysicsShapeQueryParameters2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion"); - //ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", ""); // FIXME: Lacks a getter + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 549a78aa1f..b2f2e786ee 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -98,6 +98,8 @@ class PhysicsShapeQueryResult2D; class PhysicsShapeQueryParameters2D : public Reference { GDCLASS(PhysicsShapeQueryParameters2D, Reference); friend class PhysicsDirectSpaceState2D; + + RES shape_ref; RID shape; Transform2D transform; Vector2 motion; @@ -112,7 +114,8 @@ protected: static void _bind_methods(); public: - void set_shape(const RES &p_shape); + void set_shape(const RES &p_shape_ref); + RES get_shape() const; void set_shape_rid(const RID &p_shape); RID get_shape_rid() const; diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 9668358710..3b361fee55 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -136,13 +136,21 @@ PhysicsDirectBodyState3D::PhysicsDirectBodyState3D() {} /////////////////////////////////////////////////////// -void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape) { - ERR_FAIL_COND(p_shape.is_null()); - shape = p_shape->get_rid(); +void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape_ref) { + ERR_FAIL_COND(p_shape_ref.is_null()); + shape_ref = p_shape_ref; + shape = p_shape_ref->get_rid(); +} + +RES PhysicsShapeQueryParameters3D::get_shape() const { + return shape_ref; } void PhysicsShapeQueryParameters3D::set_shape_rid(const RID &p_shape) { - shape = p_shape; + if (shape != p_shape) { + shape_ref = RES(); + shape = p_shape; + } } RID PhysicsShapeQueryParameters3D::get_shape_rid() const { @@ -208,6 +216,7 @@ bool PhysicsShapeQueryParameters3D::is_collide_with_areas_enabled() const { void PhysicsShapeQueryParameters3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters3D::set_shape); + ClassDB::bind_method(D_METHOD("get_shape"), &PhysicsShapeQueryParameters3D::get_shape); ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters3D::set_shape_rid); ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters3D::get_shape_rid); @@ -232,7 +241,7 @@ void PhysicsShapeQueryParameters3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin"); - //ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", ""); // FIXME: Lacks a getter + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 2465b40d3e..1cfa4d8565 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -100,6 +100,7 @@ class PhysicsShapeQueryParameters3D : public Reference { GDCLASS(PhysicsShapeQueryParameters3D, Reference); friend class PhysicsDirectSpaceState3D; + RES shape_ref; RID shape; Transform transform; float margin; @@ -113,7 +114,8 @@ protected: static void _bind_methods(); public: - void set_shape(const RES &p_shape); + void set_shape(const RES &p_shape_ref); + RES get_shape() const; void set_shape_rid(const RID &p_shape); RID get_shape_rid() const; diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index 1027034902..348fc423bb 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -32,10 +32,9 @@ #define RASTERIZER_H #include "core/math/camera_matrix.h" -#include "servers/rendering_server.h" - #include "core/pair.h" #include "core/self_list.h" +#include "servers/rendering_server.h" class RasterizerScene { public: @@ -96,7 +95,7 @@ public: virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) = 0; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, bool p_enhance_ssr, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index 8754fe6acb..dd68011111 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -34,6 +34,7 @@ #include "core/project_settings.h" #include "rasterizer_rd.h" #include "servers/rendering/rendering_server_raster.h" + uint64_t RasterizerSceneRD::auto_exposure_counter = 2; void get_vogel_disk(float *r_kernel, int p_sample_count) { @@ -2826,7 +2827,7 @@ void RasterizerSceneRD::environment_glow_set_use_bicubic_upscale(bool p_enable) glow_bicubic_upscale = p_enable; } -void RasterizerSceneRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, bool p_enhance_ssr, float p_energy, float p_normal_bias, float p_probe_bias) { +void RasterizerSceneRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -2836,7 +2837,6 @@ void RasterizerSceneRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::Envi env->sdfgi_use_occlusion = p_use_occlusion; env->sdfgi_use_multibounce = p_use_multibounce; env->sdfgi_read_sky_light = p_read_sky; - env->sdfgi_enhance_ssr = p_enhance_ssr; env->sdfgi_energy = p_energy; env->sdfgi_normal_bias = p_normal_bias; env->sdfgi_probe_bias = p_probe_bias; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index 88c2f5a5e6..83c03399ab 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -689,7 +689,6 @@ private: bool sdfgi_use_occlusion = false; bool sdfgi_use_multibounce = false; bool sdfgi_read_sky_light = false; - bool sdfgi_enhance_ssr = false; float sdfgi_energy = 1.0; float sdfgi_normal_bias = 1.1; float sdfgi_probe_bias = 1.1; @@ -1290,7 +1289,7 @@ public: bool environment_is_ssr_enabled(RID p_env) const; bool environment_is_sdfgi_enabled(RID p_env) const; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, bool p_enhance_ssr, float p_energy, float p_normal_bias, float p_probe_bias); + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias); virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count); virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames); diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp index 79bb990649..1820c39c5a 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp @@ -399,6 +399,9 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S if (i > 0) { header += ", "; } + if (fnode->arguments[i].is_const) { + header += "const "; + } if (fnode->arguments[i].type == SL::TYPE_STRUCT) { header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name); } else { diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl index 9a94a7914e..d6a56b2543 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl @@ -2519,11 +2519,15 @@ FRAGMENT_SHADER_CODE vec3(0, -1, 0), vec3(0, 0, -1)); - vec3 cam_normal = mat3(scene_data.camera_matrix) * normal; + vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp); + + float closest_dist = -1e20; for (uint i = 0; i < 6; i++) { - if (dot(cam_normal, aniso_dir[i]) > 0.001) { - facing_bits |= (1 << i); + float d = dot(cam_normal, aniso_dir[i]); + if (d > closest_dist) { + closest_dist = d; + facing_bits = (1 << i); } } diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl index 7a523d3a3c..d7d19897e3 100644 --- a/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl +++ b/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl @@ -655,105 +655,6 @@ void main() { groupMemoryBarrier(); barrier(); } - /* - for(int s=0;s<8;s++) { - ivec3 local_pos = pos * 2 + ((ivec3(s) >> ivec3(2,1,0)) & ivec3(1,1,1)); - for(int i=0;i<8;i++) { - ivec3 offset = local_pos + ((ivec3(i) >> ivec3(2,1,0)) & ivec3(1,1,1)) * OCCLUSION_SIZE; - - ivec3 global_offset = region_offset + offset; - - if (any(lessThan(global_offset,ivec3(0))) || any(greaterThanEqual(global_offset,ivec3(params.grid_size)))) { - continue; // do not process - } - - ivec3 proc_pos = offset - ivec3(OCCLUSION_SIZE); - proc_pos += mix(ivec3(0),ivec3(1),greaterThanEqual(proc_pos,ivec3(0))); - - ivec3 proc_abs = abs(proc_pos); - ivec3 proc_pass = proc_abs - ivec3(1); - - if (proc_pass.x+proc_pass.y+proc_pass.z != step) { - continue; - } - - offset = global_offset; - - float occ; - - uint facing = imageLoad(src_facing,offset).r; //any bit present in facing means this is solid - - if (facing != 0) { //solid - occ = 0.0; - } else if (step==0) { - occ = 1.0; //first step - } else { - ivec3 read_dir = -sign(proc_pos); - - ivec3 major_axis; - if (proc_pass.x < proc_pass.y) { - if (proc_pass.z < proc_pass.y) { - major_axis = ivec3(0,1,0); - } else { - major_axis = ivec3(0,0,1); - } - } else { - if (proc_pass.z < proc_pass.x) { - major_axis = ivec3(1,0,0); - } else { - major_axis = ivec3(0,0,1); - } - } - - float avg = 0.0; - occ = 0.0; - - ivec3 read_x = offset + ivec3(read_dir.x,0,0) + (proc_pass.x == 0 ? major_axis * read_dir : ivec3(0)); - ivec3 read_y = offset + ivec3(0,read_dir.y,0) + (proc_pass.y == 0 ? major_axis * read_dir : ivec3(0)); - ivec3 read_z = offset + ivec3(0,0,read_dir.z) + (proc_pass.z == 0 ? major_axis * read_dir : ivec3(0)); - - if (all(greaterThanEqual(read_x,ivec3(0))) && all(lessThan(read_x,ivec3(params.grid_size)))) { - - uint f = imageLoad(src_facing,read_x).r; - if (f==0) { //non solid - occ += imageLoad(dst_occlusion[params.occlusion_index],read_x).r; - avg+=1.0; - } - } - - if (all(greaterThanEqual(read_y,ivec3(0))) && all(lessThan(read_y,ivec3(params.grid_size)))) { - - uint f = imageLoad(src_facing,read_y).r; - if (f==0) {//non solid - occ += imageLoad(dst_occlusion[params.occlusion_index],read_y).r; - avg+=1.0; - } - } - - if (all(greaterThanEqual(read_z,ivec3(0))) && all(lessThan(read_z,ivec3(params.grid_size)))) { - - uint f = imageLoad(src_facing,read_z).r; - if (f==0) {//non solid - occ += imageLoad(dst_occlusion[params.occlusion_index],read_z).r; - avg+=1.0; - } - } - - if (avg > 0.0) { - occ/=avg; - } - } - - imageStore(dst_occlusion[params.occlusion_index],offset,vec4(occ)); - - } - } - - groupMemoryBarrier(); - barrier(); - - } -*/ #if 1 //bias solid voxels away diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 7c70148180..83cbfb85bd 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -281,7 +281,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("shader_get_vertex_input_attribute_mask", "shader"), &RenderingDevice::shader_get_vertex_input_attribute_mask); ClassDB::bind_method(D_METHOD("uniform_buffer_create", "size_bytes", "data"), &RenderingDevice::uniform_buffer_create, DEFVAL(Vector<uint8_t>())); - ClassDB::bind_method(D_METHOD("storage_buffer_create", "size_bytes", "data"), &RenderingDevice::storage_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("storage_buffer_create", "size_bytes", "data", "usage"), &RenderingDevice::storage_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("texture_buffer_create", "size_bytes", "format", "data"), &RenderingDevice::texture_buffer_create, DEFVAL(Vector<uint8_t>())); ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create); diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index 27fc6b6f07..706912b353 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -566,7 +566,7 @@ public: BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) BIND5(environment_set_fog_height, RID, bool, float, float, float) - BIND12(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, bool, float, float, float) + BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) BIND1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount) BIND1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge) diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index 5c03fbc0eb..60a694eed5 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -468,7 +468,7 @@ public: FUNC2(environment_set_ssao_quality, EnvironmentSSAOQuality, bool) - FUNC12(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, bool, float, float, float) + FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount) FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 809b03520b..99cc76b2e3 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -643,7 +643,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { } if (hexa_found) { - tk.constant = (double)str.hex_to_int64(true); + tk.constant = (double)str.hex_to_int(true); } else { tk.constant = str.to_double(); } @@ -982,6 +982,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_struct_name) { *r_struct_name = function->arguments[i].type_str; } + if (r_is_const) { + *r_is_const = function->arguments[i].is_const; + } return true; } } @@ -3553,7 +3556,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons for (int i = 0; i < call_function->arguments.size(); i++) { int argidx = i + 1; if (argidx < func->arguments.size()) { - if (call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT || call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT) { + if (call_function->arguments[i].is_const || call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT || call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT) { bool error = false; Node *n = func->arguments[argidx]; if (n->type == Node::TYPE_CONSTANT || n->type == Node::TYPE_OPERATOR) { @@ -6780,15 +6783,29 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct break; } + bool is_const = false; + if (tk.type == TK_CONST) { + is_const = true; + tk = _get_token(); + } + ArgumentQualifier qualifier = ARGUMENT_QUALIFIER_IN; if (tk.type == TK_ARG_IN) { qualifier = ARGUMENT_QUALIFIER_IN; tk = _get_token(); } else if (tk.type == TK_ARG_OUT) { + if (is_const) { + _set_error("'out' qualifier cannot be used within a function parameter declared with 'const'."); + return ERR_PARSE_ERROR; + } qualifier = ARGUMENT_QUALIFIER_OUT; tk = _get_token(); } else if (tk.type == TK_ARG_INOUT) { + if (is_const) { + _set_error("'inout' qualifier cannot be used within a function parameter declared with 'const'."); + return ERR_PARSE_ERROR; + } qualifier = ARGUMENT_QUALIFIER_INOUT; tk = _get_token(); } @@ -6877,6 +6894,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct arg.tex_builtin_check = false; arg.tex_argument_filter = FILTER_DEFAULT; arg.tex_argument_repeat = REPEAT_DEFAULT; + arg.is_const = is_const; func_node->arguments.push_back(arg); @@ -7273,6 +7291,10 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct calltip += CharType(0xFFFF); } + if (shader->functions[i].function->arguments[j].is_const) { + calltip += "const "; + } + if (shader->functions[i].function->arguments[j].qualifier != ArgumentQualifier::ARGUMENT_QUALIFIER_IN) { if (shader->functions[i].function->arguments[j].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT) { calltip += "out "; diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index bc8f03774a..faf06a9a85 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -554,6 +554,7 @@ public: TextureRepeat tex_argument_repeat; bool tex_builtin_check; StringName tex_builtin; + bool is_const; Map<StringName, Set<int>> tex_argument_connect; }; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index d4d5080109..c156313c15 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1995,6 +1995,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX); + BIND_ENUM_CONSTANT(LIGHT_BAKE_DISABLED); + BIND_ENUM_CONSTANT(LIGHT_BAKE_DYNAMIC); + BIND_ENUM_CONSTANT(LIGHT_BAKE_STATIC); + BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DUAL_PARABOLOID); BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_CUBE); @@ -2008,6 +2012,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ONCE); BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ALWAYS); + BIND_ENUM_CONSTANT(REFLECTION_PROBE_AMBIENT_DISABLED); + BIND_ENUM_CONSTANT(REFLECTION_PROBE_AMBIENT_ENVIRONMENT); + BIND_ENUM_CONSTANT(REFLECTION_PROBE_AMBIENT_COLOR); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_ALBEDO); BIND_ENUM_CONSTANT(DECAL_TEXTURE_NORMAL); BIND_ENUM_CONSTANT(DECAL_TEXTURE_ORM); @@ -2374,7 +2382,7 @@ RenderingServer::RenderingServer() { ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/quality", PropertyInfo(Variant::INT, "rendering/quality/ssao/quality", PROPERTY_HINT_ENUM, "Low (Fast),Medium (Average),High (Slow),Ultra (Slower)")); GLOBAL_DEF("rendering/quality/ssao/half_size", false); - GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_enable", true); + GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled", true); GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_amount", 0.25); GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_limit", 0.18); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_roughness_limiter_amount", PropertyInfo(Variant::FLOAT, "rendering/quality/screen_filters/screen_space_roughness_limiter_amount", PROPERTY_HINT_RANGE, "0.01,4.0,0.01")); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 9fdaa8a93e..2e5ceec02f 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -428,7 +428,7 @@ public: enum LightDirectionalShadowMode { LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL, LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS, - LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS + LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS, }; virtual void light_directional_set_shadow_mode(RID p_light, LightDirectionalShadowMode p_mode) = 0; @@ -437,7 +437,6 @@ public: enum LightDirectionalShadowDepthRangeMode { LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE, LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED, - }; virtual void light_directional_set_shadow_depth_range_mode(RID p_light, LightDirectionalShadowDepthRangeMode p_range_mode) = 0; @@ -457,7 +456,7 @@ public: enum ReflectionProbeAmbientMode { REFLECTION_PROBE_AMBIENT_DISABLED, REFLECTION_PROBE_AMBIENT_ENVIRONMENT, - REFLECTION_PROBE_AMBIENT_COLOR + REFLECTION_PROBE_AMBIENT_COLOR, }; virtual void reflection_probe_set_ambient_mode(RID p_probe, ReflectionProbeAmbientMode p_mode) = 0; @@ -608,16 +607,6 @@ public: virtual void camera_set_camera_effects(RID p_camera, RID p_camera_effects) = 0; virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0; - /* - enum ParticlesCollisionMode { - PARTICLES_COLLISION_NONE, - PARTICLES_COLLISION_TEXTURE, - PARTICLES_COLLISION_CUBEMAP, - }; - - virtual void particles_set_collision(RID p_particles,ParticlesCollisionMode p_mode,const Transform&, p_xform,const RID p_depth_tex,const RID p_normal_tex)=0; - */ - /* VIEWPORT TARGET API */ virtual RID viewport_create() = 0; @@ -844,7 +833,7 @@ public: ENV_SDFGI_Y_SCALE_50_PERCENT }; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, EnvironmentSDFGICascades p_cascades, float p_min_cell_size, EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, bool p_enhance_ssr, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + virtual void environment_set_sdfgi(RID p_env, bool p_enable, EnvironmentSDFGICascades p_cascades, float p_min_cell_size, EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; enum EnvironmentSDFGIRayCount { ENV_SDFGI_RAY_COUNT_8, |