diff options
35 files changed, 180 insertions, 113 deletions
diff --git a/core/io/image.cpp b/core/io/image.cpp index fad9942017..4aed5a913a 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -3276,7 +3276,7 @@ Ref<Image> Image::rgbe_to_srgb() { for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { - new_image->set_pixel(col, row, get_pixel(col, row).to_srgb()); + new_image->set_pixel(col, row, get_pixel(col, row).linear_to_srgb()); } } diff --git a/core/math/color.h b/core/math/color.h index b90a0f33a2..91e0bf5532 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -169,14 +169,14 @@ struct _NO_DISCARD_ Color { return res; } - _FORCE_INLINE_ Color to_linear() const { + _FORCE_INLINE_ Color srgb_to_linear() const { return Color( r < 0.04045f ? r * (1.0 / 12.92) : Math::pow((r + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f), g < 0.04045f ? g * (1.0 / 12.92) : Math::pow((g + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f), b < 0.04045f ? b * (1.0 / 12.92) : Math::pow((b + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f), a); } - _FORCE_INLINE_ Color to_srgb() const { + _FORCE_INLINE_ Color linear_to_srgb() const { return Color( r < 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * Math::pow(r, 1.0f / 2.4f) - 0.055f, g < 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * Math::pow(g, 1.0f / 2.4f) - 0.055f, diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index debc5cd00d..e146c4a4e3 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -231,14 +231,14 @@ Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const { } case VISIT_LEFT_BIT: { stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.left | TEST_AABB_BIT; level++; + stack[level] = b.left | TEST_AABB_BIT; continue; } case VISIT_RIGHT_BIT: { stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.right | TEST_AABB_BIT; level++; + stack[level] = b.right | TEST_AABB_BIT; continue; } case VISIT_DONE_BIT: { @@ -331,14 +331,14 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en } case VISIT_LEFT_BIT: { stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.left | TEST_AABB_BIT; level++; + stack[level] = b.left | TEST_AABB_BIT; continue; } case VISIT_RIGHT_BIT: { stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.right | TEST_AABB_BIT; level++; + stack[level] = b.right | TEST_AABB_BIT; continue; } case VISIT_DONE_BIT: { @@ -431,14 +431,14 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V } case VISIT_LEFT_BIT: { stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.left | TEST_AABB_BIT; level++; + stack[level] = b.left | TEST_AABB_BIT; continue; } case VISIT_RIGHT_BIT: { stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.right | TEST_AABB_BIT; level++; + stack[level] = b.right | TEST_AABB_BIT; continue; } case VISIT_DONE_BIT: { @@ -551,14 +551,14 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou } case VISIT_LEFT_BIT: { stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.left | TEST_AABB_BIT; level++; + stack[level] = b.left | TEST_AABB_BIT; continue; } case VISIT_RIGHT_BIT: { stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.right | TEST_AABB_BIT; level++; + stack[level] = b.right | TEST_AABB_BIT; continue; } case VISIT_DONE_BIT: { @@ -644,14 +644,14 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count, } case VISIT_LEFT_BIT: { stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.left | TEST_AABB_BIT; level++; + stack[level] = b.left | TEST_AABB_BIT; continue; } case VISIT_RIGHT_BIT: { stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - stack[level + 1] = b.right | TEST_AABB_BIT; level++; + stack[level] = b.right | TEST_AABB_BIT; continue; } case VISIT_DONE_BIT: { diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index c11925fa8c..f1daf1de13 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1656,8 +1656,8 @@ static void _register_variant_builtin_methods() { bind_method(Color, darkened, sarray("amount"), varray()); bind_method(Color, blend, sarray("over"), varray()); bind_method(Color, get_luminance, sarray(), varray()); - bind_method(Color, to_linear, sarray(), varray()); - bind_method(Color, to_srgb, sarray(), varray()); + bind_method(Color, srgb_to_linear, sarray(), varray()); + bind_method(Color, linear_to_srgb, sarray(), varray()); bind_method(Color, is_equal_approx, sarray("to"), varray()); diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml index f7a0d41626..5008cd826e 100644 --- a/doc/classes/Camera3D.xml +++ b/doc/classes/Camera3D.xml @@ -192,7 +192,7 @@ The camera's projection mode. In [constant PROJECTION_PERSPECTIVE] mode, objects' Z distance from the camera's local space scales their perceived size. </member> <member name="size" type="float" setter="set_size" getter="get_size" default="1.0"> - The camera's size measured as 1/2 the width or height. Only applicable in orthogonal mode. Since [member keep_aspect] locks on axis, [code]size[/code] sets the other axis' size length. + The camera's size measured as 1/2 the width or height. Only applicable in orthogonal and frustum modes. Since [member keep_aspect] locks on axis, [code]size[/code] sets the other axis' size length. </member> <member name="v_offset" type="float" setter="set_v_offset" getter="get_v_offset" default="0.0"> The vertical (Y) offset of the camera viewport. diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml index 99bf9f7853..5d025985cc 100644 --- a/doc/classes/CollisionObject2D.xml +++ b/doc/classes/CollisionObject2D.xml @@ -5,6 +5,7 @@ </brief_description> <description> CollisionObject2D is the base class for 2D physics objects. It can hold any number of 2D collision [Shape2D]s. Each shape must be assigned to a [i]shape owner[/i]. The CollisionObject2D can have any number of shape owners. Shape owners are not nodes and do not appear in the editor, but are accessible through code using the [code]shape_owner_*[/code] methods. + [b]Note:[/b] Only collisions between objects within the same canvas ([Viewport] canvas or [CanvasLayer]) are supported. The behavior of collisions between objects in different canvases is undefined. </description> <tutorials> </tutorials> diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 5b48804d9d..7b8a57ed22 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -183,7 +183,7 @@ <description> Returns the luminance of the color in the [code][0.0, 1.0][/code] range. This is useful when determining light or dark color. Colors with a luminance smaller than 0.5 can be generally considered dark. - [b]Note:[/b] [method get_luminance] relies on the colour being in the linear color space to return an accurate relative luminance value. If the color is in the sRGB color space, use [method to_linear] to convert it to the linear color space first. + [b]Note:[/b] [method get_luminance] relies on the colour being in the linear color space to return an accurate relative luminance value. If the color is in the sRGB color space, use [method srgb_to_linear] to convert it to the linear color space first. </description> </method> <method name="get_named_color" qualifiers="static"> @@ -321,6 +321,18 @@ [/codeblocks] </description> </method> + <method name="linear_to_srgb" qualifiers="const"> + <return type="Color" /> + <description> + Returns the color converted to the [url=https://en.wikipedia.org/wiki/SRGB]sRGB[/url] color space. This assumes the original color is in the linear color space. See also [method srgb_to_linear] which performs the opposite operation. + </description> + </method> + <method name="srgb_to_linear" qualifiers="const"> + <return type="Color" /> + <description> + Returns the color converted to the linear color space. This assumes the original color is in the sRGB color space. See also [method linear_to_srgb] which performs the opposite operation. + </description> + </method> <method name="to_abgr32" qualifiers="const"> <return type="int" /> <description> @@ -405,12 +417,6 @@ [/codeblocks] </description> </method> - <method name="to_linear" qualifiers="const"> - <return type="Color" /> - <description> - Returns the color converted to the linear color space. This assumes the original color is in the sRGB color space. See also [method to_srgb] which performs the opposite operation. - </description> - </method> <method name="to_rgba32" qualifiers="const"> <return type="int" /> <description> @@ -443,12 +449,6 @@ [/codeblocks] </description> </method> - <method name="to_srgb" qualifiers="const"> - <return type="Color" /> - <description> - Returns the color converted to the [url=https://en.wikipedia.org/wiki/SRGB]sRGB[/url] color space. This assumes the original color is in the linear color space. See also [method to_linear] which performs the opposite operation. - </description> - </method> </methods> <members> <member name="a" type="float" setter="" getter="" default="1.0"> diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml index a59666356c..e007dfd9b5 100644 --- a/doc/classes/NavigationServer2D.xml +++ b/doc/classes/NavigationServer2D.xml @@ -110,11 +110,11 @@ Sets the current velocity of the agent. </description> </method> - <method name="free" qualifiers="const"> + <method name="free_rid" qualifiers="const"> <return type="void" /> - <argument index="0" name="object" type="RID" /> + <argument index="0" name="rid" type="RID" /> <description> - Destroy the RID + Destroys the given RID. </description> </method> <method name="map_create" qualifiers="const"> diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index 7d11a30647..c987bc9042 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -110,11 +110,11 @@ Sets the current velocity of the agent. </description> </method> - <method name="free" qualifiers="const"> + <method name="free_rid" qualifiers="const"> <return type="void" /> - <argument index="0" name="object" type="RID" /> + <argument index="0" name="rid" type="RID" /> <description> - Destroy the RID + Destroys the given RID. </description> </method> <method name="map_create" qualifiers="const"> diff --git a/doc/classes/Signal.xml b/doc/classes/Signal.xml index c5855e30a4..049e7f8777 100644 --- a/doc/classes/Signal.xml +++ b/doc/classes/Signal.xml @@ -6,6 +6,8 @@ <description> </description> <tutorials> + <link title="Using Signals">$DOCS_URL/getting_started/step_by_step/signals.html</link> + <link title="GDScript Basics">$DOCS_URL/tutorials/scripting/gdscript/gdscript_basics.html#signals</link> </tutorials> <constructors> <constructor name="Signal"> diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 53631c1e3b..685dde4d98 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -2252,6 +2252,8 @@ void AnimationTrackEdit::_notification(int p_what) { break; case NOTIFICATION_MOUSE_EXIT: hovered = false; + // When the mouse cursor exits the track, we're no longer hovering any keyframe. + hovering_key_idx = -1; update(); [[fallthrough]]; case NOTIFICATION_DRAG_END: { @@ -2365,7 +2367,13 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool } } - draw_texture(icon_to_draw, ofs); + // Use a different color for the currently hovered key. + // The color multiplier is chosen to work with both dark and light editor themes, + // and on both unselected and selected key icons. + draw_texture( + icon_to_draw, + ofs, + p_index == hovering_key_idx ? get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")) : Color(1, 1, 1)); } // Helper. @@ -2952,6 +2960,59 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid()) { + const int previous_hovering_key_idx = hovering_key_idx; + + // Hovering compressed keyframes for editing is not possible. + if (!animation->track_is_compressed(track)) { + const float scale = timeline->get_zoom_scale(); + const int limit = timeline->get_name_limit(); + const int limit_end = get_size().width - timeline->get_buttons_width(); + // Left Border including space occupied by keyframes on t=0. + const int limit_start_hitbox = limit - type_icon->get_width(); + const Point2 pos = mm->get_position(); + + if (pos.x >= limit_start_hitbox && pos.x <= limit_end) { + // Use the same logic as key selection to ensure that hovering accurately represents + // which key will be selected when clicking. + int key_idx = -1; + float key_distance = 1e20; + + hovering_key_idx = -1; + + // Hovering should happen in the opposite order of drawing for more accurate overlap hovering. + for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) { + Rect2 rect = get_key_rect(i, scale); + float offset = animation->track_get_key_time(track, i) - timeline->get_value(); + offset = offset * scale + limit; + rect.position.x += offset; + + if (rect.has_point(pos)) { + if (is_key_selectable_by_distance()) { + const float distance = ABS(offset - pos.x); + if (key_idx == -1 || distance < key_distance) { + key_idx = i; + key_distance = distance; + hovering_key_idx = i; + } + } else { + // First one does it. + hovering_key_idx = i; + break; + } + } + } + + print_line(hovering_key_idx); + + if (hovering_key_idx != previous_hovering_key_idx) { + // Required to draw keyframe hover feedback on the correct keyframe. + update(); + } + } + } + } + if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE && moving_selection_attempt) { if (!moving_selection) { moving_selection = true; diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index a8a5d11c12..0f6d12b4d4 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -173,6 +173,7 @@ class AnimationTrackEdit : public Control { bool hovered = false; bool clicking_on_name = false; + int hovering_key_idx = -1; void _zoom_changed(); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index a90e151adb..8d0db697e2 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2298,7 +2298,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { } add_node_menu->reset_size(); - add_node_menu->set_position(get_screen_transform().xform(b->get_position())); + add_node_menu->set_position(viewport->get_screen_transform().xform(b->get_position())); add_node_menu->popup(); node_create_position = transform.affine_inverse().xform(b->get_position()); return true; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 855fc2b2a9..f2ca1fcfeb 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -7120,7 +7120,9 @@ void Node3DEditor::_request_gizmo(Object *p_obj) { } } } - sp->update_gizmos(); + if (!sp->get_gizmos().is_empty()) { + sp->update_gizmos(); + } } } diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 73222330db..784733aba2 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -3272,7 +3272,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { Dictionary mr; { Array arr; - const Color c = material->get_albedo().to_linear(); + const Color c = material->get_albedo().srgb_to_linear(); arr.push_back(c.r); arr.push_back(c.g); arr.push_back(c.b); @@ -3473,7 +3473,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { } if (material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) { - const Color c = material->get_emission().to_srgb(); + const Color c = material->get_emission().linear_to_srgb(); Array arr; arr.push_back(c.r); arr.push_back(c.g); @@ -3555,7 +3555,7 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) { if (sgm.has("diffuseFactor")) { const Array &arr = sgm["diffuseFactor"]; ERR_FAIL_COND_V(arr.size() != 4, ERR_PARSE_ERROR); - const Color c = Color(arr[0], arr[1], arr[2], arr[3]).to_srgb(); + const Color c = Color(arr[0], arr[1], arr[2], arr[3]).linear_to_srgb(); spec_gloss->diffuse_factor = c; material->set_albedo(spec_gloss->diffuse_factor); } @@ -3586,7 +3586,7 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) { if (mr.has("baseColorFactor")) { const Array &arr = mr["baseColorFactor"]; ERR_FAIL_COND_V(arr.size() != 4, ERR_PARSE_ERROR); - const Color c = Color(arr[0], arr[1], arr[2], arr[3]).to_srgb(); + const Color c = Color(arr[0], arr[1], arr[2], arr[3]).linear_to_srgb(); material->set_albedo(c); } @@ -3653,7 +3653,7 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) { if (d.has("emissiveFactor")) { const Array &arr = d["emissiveFactor"]; ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR); - const Color c = Color(arr[0], arr[1], arr[2]).to_srgb(); + const Color c = Color(arr[0], arr[1], arr[2]).linear_to_srgb(); material->set_feature(BaseMaterial3D::FEATURE_EMISSION, true); material->set_emission(c); @@ -3737,11 +3737,11 @@ void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Re } for (int32_t y = 0; y < r_spec_gloss->spec_gloss_img->get_height(); y++) { for (int32_t x = 0; x < r_spec_gloss->spec_gloss_img->get_width(); x++) { - const Color specular_pixel = r_spec_gloss->spec_gloss_img->get_pixel(x, y).to_linear(); + const Color specular_pixel = r_spec_gloss->spec_gloss_img->get_pixel(x, y).srgb_to_linear(); Color specular = Color(specular_pixel.r, specular_pixel.g, specular_pixel.b); specular *= r_spec_gloss->specular_factor; Color diffuse = Color(1.0f, 1.0f, 1.0f); - diffuse *= r_spec_gloss->diffuse_img->get_pixel(x, y).to_linear(); + diffuse *= r_spec_gloss->diffuse_img->get_pixel(x, y).srgb_to_linear(); float metallic = 0.0f; Color base_color; spec_gloss_to_metal_base_color(specular, diffuse, base_color, metallic); @@ -3758,7 +3758,7 @@ void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Re mr.g = 1.0f - mr.g; rm_img->set_pixel(x, y, mr); if (r_spec_gloss->diffuse_img.is_valid()) { - r_spec_gloss->diffuse_img->set_pixel(x, y, base_color.to_srgb()); + r_spec_gloss->diffuse_img->set_pixel(x, y, base_color.linear_to_srgb()); } } } @@ -4626,7 +4626,7 @@ Error GLTFDocument::_parse_lights(Ref<GLTFState> state) { if (d.has("color")) { const Array &arr = d["color"]; ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR); - const Color c = Color(arr[0], arr[1], arr[2]).to_srgb(); + const Color c = Color(arr[0], arr[1], arr[2]).linear_to_srgb(); light->color = c; } if (d.has("intensity")) { diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp index 4588caf0a5..eca689e87a 100644 --- a/modules/hdr/image_loader_hdr.cpp +++ b/modules/hdr/image_loader_hdr.cpp @@ -132,7 +132,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_f ptr[2] * exp / 255.0); if (p_force_linear) { - c = c.to_linear(); + c = c.srgb_to_linear(); } *(uint32_t *)ptr = c.to_rgbe9995(); diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index 1ff2600839..864df765ee 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -230,7 +230,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool } if (p_force_linear) { - color = color.to_linear(); + color = color.srgb_to_linear(); } *row_w++ = Math::make_half_float(color.r); @@ -261,7 +261,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool } if (p_force_linear) { - color = color.to_linear(); + color = color.srgb_to_linear(); } *row_w++ = color.r; diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index db2fe274d9..7da30ac363 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -3062,7 +3062,7 @@ void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) { Callable::CallError ce; { - List<WindowID>::Element *E = popup_list.front(); + List<WindowID>::Element *E = popup_list.back(); if (E && Object::cast_to<InputEventKey>(*p_event)) { // Redirect keyboard input to active popup. if (windows.has(E->get())) { diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index c7381f06e3..d209c90d87 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -326,7 +326,7 @@ void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) { Callable::CallError ce; { - List<WindowID>::Element *E = popup_list.front(); + List<WindowID>::Element *E = popup_list.back(); if (E && Object::cast_to<InputEventKey>(*p_event)) { // Redirect keyboard input to active popup. if (windows.has(E->get())) { diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 736dc7d383..31bad0f053 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -2003,7 +2003,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) Callable::CallError ce; { - List<WindowID>::Element *E = popup_list.front(); + List<WindowID>::Element *E = popup_list.back(); if (E && Object::cast_to<InputEventKey>(*p_event)) { // Redirect keyboard input to active popup. if (windows.has(E->get())) { diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 4eace17cc0..1f0c9acef5 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -509,7 +509,7 @@ void Camera3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal,Frustum"), "set_projection", "get_projection"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1,degrees"), "set_fov", "get_fov"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.001,16384,0.001"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset"), "set_frustum_offset", "get_frustum_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater,exp"), "set_near", "get_near"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_RANGE, "0.01,4000,0.01,or_greater,exp"), "set_far", "get_far"); @@ -557,7 +557,7 @@ void Camera3D::set_fov(real_t p_fov) { } void Camera3D::set_size(real_t p_size) { - ERR_FAIL_COND(p_size < 0.1 || p_size > 16384); + ERR_FAIL_COND(p_size < 0.001 || p_size > 16384); size = p_size; _update_camera_mode(); } diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 3461caf638..8b457b683d 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -884,7 +884,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa Light3D *light = lights_found[i].light; Transform3D xf = lights_found[i].xform; - Color linear_color = light->get_color().to_linear(); + Color linear_color = light->get_color().srgb_to_linear(); if (Object::cast_to<DirectionalLight3D>(light)) { DirectionalLight3D *l = Object::cast_to<DirectionalLight3D>(light); lightmapper->add_directional_light(light->get_bake_mode() == Light3D::BAKE_STATIC, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_SIZE)); diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 62cc7c143b..bbc977647e 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -181,15 +181,6 @@ void Node3D::_notification(int p_what) { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) { get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this); - if (!data.gizmos_disabled) { - for (int i = 0; i < data.gizmos.size(); i++) { - data.gizmos.write[i]->create(); - if (is_visible_in_tree()) { - data.gizmos.write[i]->redraw(); - } - data.gizmos.write[i]->transform(); - } - } } #endif } break; @@ -427,6 +418,7 @@ void Node3D::update_gizmos() { } if (data.gizmos.is_empty()) { + get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this); return; } if (data.gizmos_dirty) { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 9fc1fb072c..b01f45e9ab 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -169,7 +169,7 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const { return -1; } -void PopupMenu::_activate_submenu(int p_over) { +void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) { Node *n = get_node(items[p_over].submenu); ERR_FAIL_COND_MSG(!n, "Item subnode does not exist: " + items[p_over].submenu + "."); Popup *submenu_popup = Object::cast_to<Popup>(n); @@ -213,8 +213,10 @@ void PopupMenu::_activate_submenu(int p_over) { return; } + submenu_pum->activated_by_keyboard = p_by_keyboard; + // If not triggered by the mouse, start the popup with its first item selected. - if (submenu_pum->get_item_count() > 0 && Input::get_singleton()->is_action_just_pressed("ui_accept")) { + if (submenu_pum->get_item_count() > 0 && p_by_keyboard) { submenu_pum->set_current_index(0); } @@ -323,14 +325,14 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { set_input_as_handled(); } } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { - if (mouse_over >= 0 && mouse_over < items.size() && !!items[mouse_over].separator && items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { - _activate_submenu(mouse_over); + if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && !items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { + _activate_submenu(mouse_over, true); set_input_as_handled(); } } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { if (!items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { - _activate_submenu(mouse_over); + _activate_submenu(mouse_over, true); } else { activate_item(mouse_over); } @@ -396,6 +398,11 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> m = p_event; if (m.is_valid()) { + if (m->get_velocity().is_equal_approx(Vector2())) { + return; + } + activated_by_keyboard = false; + for (const Rect2 &E : autohide_areas) { if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E.has_point(m->get_position())) { _close_pressed(); @@ -687,7 +694,7 @@ void PopupMenu::_draw_background() { void PopupMenu::_minimum_lifetime_timeout() { close_allowed = true; // If the mouse still isn't in this popup after timer expires, close. - if (!get_visible_rect().has_point(get_mouse_position())) { + if (!activated_by_keyboard && !get_visible_rect().has_point(get_mouse_position())) { _close_pressed(); } } @@ -772,7 +779,7 @@ void PopupMenu::_notification(int p_what) { case NOTIFICATION_INTERNAL_PROCESS: { // Only used when using operating system windows. - if (!is_embedded() && autohide_areas.size()) { + if (!activated_by_keyboard && !is_embedded() && autohide_areas.size()) { Point2 mouse_pos = DisplayServer::get_singleton()->mouse_get_position(); mouse_pos -= get_position(); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 518ba14dae..98d76875cb 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -87,6 +87,7 @@ class PopupMenu : public Popup { }; bool close_allowed = false; + bool activated_by_keyboard = false; Timer *minimum_lifetime_timer = nullptr; Timer *submenu_timer = nullptr; @@ -107,7 +108,7 @@ class PopupMenu : public Popup { void _shape_item(int p_item); virtual void gui_input(const Ref<InputEvent> &p_event); - void _activate_submenu(int p_over); + void _activate_submenu(int p_over, bool p_by_keyboard = false); void _submenu_timeout(); uint64_t popup_time_msec = 0; diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 0ddf164c79..e045a379d2 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -3828,7 +3828,7 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("compress", "page_size", "fps", "split_tolerance"), &Animation::compress, DEFVAL(8192), DEFVAL(120), DEFVAL(4.0)); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode"), "set_loop_mode", "get_loop_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Ping-Pong"), "set_loop_mode", "get_loop_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step"); ADD_SIGNAL(MethodInfo("tracks_changed")); diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index ee196673a3..0fef416680 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -193,7 +193,7 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("agent_is_map_changed", "agent"), &NavigationServer2D::agent_is_map_changed); ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "receiver", "method", "userdata"), &NavigationServer2D::agent_set_callback, DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("free", "object"), &NavigationServer2D::free); + ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer2D::free); ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map"))); } diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index d18777869a..46192772f6 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -72,7 +72,7 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("agent_is_map_changed", "agent"), &NavigationServer3D::agent_is_map_changed); ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "receiver", "method", "userdata"), &NavigationServer3D::agent_set_callback, DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("free", "object"), &NavigationServer3D::free); + ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer3D::free); ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer3D::set_active); ClassDB::bind_method(D_METHOD("process", "delta_time"), &NavigationServer3D::process); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 365bef896f..b541e6ca88 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -783,7 +783,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat //ambient if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); - color = color.to_linear(); + color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy; @@ -793,7 +793,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat } else { float energy = environment_get_ambient_light_energy(p_render_data->environment); Color color = environment_get_ambient_light_color(p_render_data->environment); - color = color.to_linear(); + color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; scene_state.ubo.ambient_light_color_energy[2] = color.b * energy; @@ -829,7 +829,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment); - Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear(); + Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear(); float fog_energy = environment_get_fog_light_energy(p_render_data->environment); scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; @@ -844,7 +844,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat } else { scene_state.ubo.use_ambient_light = true; Color clear_color = p_default_bg_color; - clear_color = clear_color.to_linear(); + clear_color = clear_color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = clear_color.r; scene_state.ubo.ambient_light_color_energy[1] = clear_color.g; scene_state.ubo.ambient_light_color_energy[2] = clear_color.b; @@ -1391,7 +1391,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color.b *= bg_energy; if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; - RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear())); + RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } } break; case RS::ENV_BG_COLOR: { @@ -1401,7 +1401,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color.b *= bg_energy; if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; - RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear())); + RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } } break; case RS::ENV_BG_SKY: { @@ -1520,7 +1520,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co Vector<Color> c; { - Color cc = clear_color.to_linear(); + Color cc = clear_color.srgb_to_linear(); if (using_separate_specular) { cc.a = 0; //subsurf scatter must be 0 } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 7272b2f8d0..6988e3c1dd 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -596,7 +596,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color /* if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; - RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear())); + RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } */ } break; @@ -608,7 +608,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color /* if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; - RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear())); + RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } */ } break; @@ -723,10 +723,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color { // regular forward for now Vector<Color> c; - c.push_back(clear_color.to_linear()); // our render buffer + c.push_back(clear_color.srgb_to_linear()); // our render buffer if (render_buffer) { if (render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - c.push_back(clear_color.to_linear()); // our resolve buffer + c.push_back(clear_color.srgb_to_linear()); // our resolve buffer } if (using_subpass_post_process) { c.push_back(Color()); // our 2D buffer we're copying into @@ -1616,7 +1616,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, //ambient if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); - color = color.to_linear(); + color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy; @@ -1626,7 +1626,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, } else { float energy = environment_get_ambient_light_energy(p_render_data->environment); Color color = environment_get_ambient_light_color(p_render_data->environment); - color = color.to_linear(); + color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; scene_state.ubo.ambient_light_color_energy[2] = color.b * energy; @@ -1657,7 +1657,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment); - Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear(); + Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear(); float fog_energy = environment_get_fog_light_energy(p_render_data->environment); scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; @@ -1672,7 +1672,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, } else { scene_state.ubo.use_ambient_light = true; Color clear_color = p_default_bg_color; - clear_color = clear_color.to_linear(); + clear_color = clear_color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = clear_color.r; scene_state.ubo.ambient_light_color_energy[1] = clear_color.g; scene_state.ubo.ambient_light_color_energy[2] = clear_color.b; diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp index 75202d5abb..c735fda5f8 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp @@ -921,7 +921,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, if (p_env->background == RS::ENV_BG_CLEAR_COLOR) { push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; - Color c = storage->get_default_clear_color().to_linear(); + Color c = storage->get_default_clear_color().srgb_to_linear(); push_constant.sky_color[0] = c.r; push_constant.sky_color[1] = c.g; push_constant.sky_color[2] = c.b; @@ -1469,7 +1469,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re lights[idx].direction[1] = dir.y; lights[idx].direction[2] = dir.z; Color color = storage->light_get_color(li->light); - color = color.to_linear(); + color = color.srgb_to_linear(); lights[idx].color[0] = color.r; lights[idx].color[1] = color.g; lights[idx].color[2] = color.b; @@ -1514,7 +1514,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re lights[idx].position[1] = pos.y; lights[idx].position[2] = pos.z; Color color = storage->light_get_color(li->light); - color = color.to_linear(); + color = color.srgb_to_linear(); lights[idx].color[0] = color.r; lights[idx].color[1] = color.g; lights[idx].color[2] = color.b; @@ -1953,7 +1953,7 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32 lights[idx].position[1] = pos.y; lights[idx].position[2] = pos.z; Color color = storage->light_get_color(li->light); - color = color.to_linear(); + color = color.srgb_to_linear(); lights[idx].color[0] = color.r; lights[idx].color[1] = color.g; lights[idx].color[2] = color.b; @@ -2396,7 +2396,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c l.attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION); l.energy = storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); l.radius = to_cell.basis.xform(Vector3(storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length(); - Color color = storage->light_get_color(light).to_linear(); + Color color = storage->light_get_color(light).srgb_to_linear(); l.color[0] = color.r; l.color[1] = color.g; l.color[2] = color.b; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index ac7ac692ce..b342e8f043 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -517,7 +517,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba ambient_color_sky_mix = env->ambient_sky_contribution; const float ambient_energy = env->ambient_light_energy; ambient_color = env->ambient_light; - ambient_color = ambient_color.to_linear(); + ambient_color = ambient_color.srgb_to_linear(); ambient_color.r *= ambient_energy; ambient_color.g *= ambient_energy; ambient_color.b *= ambient_energy; @@ -536,7 +536,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba } else { const float bg_energy = env->bg_energy; Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? storage->get_default_clear_color() : env->bg_color); - panorama_color = panorama_color.to_linear(); + panorama_color = panorama_color.srgb_to_linear(); panorama_color.r *= bg_energy; panorama_color.g *= bg_energy; panorama_color.b *= bg_energy; @@ -3245,7 +3245,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti reflection_ubo.exterior = !storage->reflection_probe_is_interior(base_probe); reflection_ubo.box_project = storage->reflection_probe_is_box_projection(base_probe); - Color ambient_linear = storage->reflection_probe_get_ambient_color(base_probe).to_linear(); + Color ambient_linear = storage->reflection_probe_get_ambient_color(base_probe).srgb_to_linear(); float interior_ambient_energy = storage->reflection_probe_get_ambient_color_energy(base_probe); reflection_ubo.ambient[0] = ambient_linear.r * interior_ambient_energy; reflection_ubo.ambient[1] = ambient_linear.g * interior_ambient_energy; @@ -3312,7 +3312,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI; - Color linear_col = storage->light_get_color(base).to_linear(); + Color linear_col = storage->light_get_color(base).srgb_to_linear(); light_data.color[0] = linear_col.r; light_data.color[1] = linear_col.g; light_data.color[2] = linear_col.b; @@ -3491,7 +3491,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D light_transform = li->transform; float sign = storage->light_is_negative(base) ? -1 : 1; - Color linear_col = storage->light_get_color(base).to_linear(); + Color linear_col = storage->light_get_color(base).srgb_to_linear(); light_data.attenuation = storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION); @@ -4641,7 +4641,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e params.fog_frustum_end = fog_end; - Color ambient_color = env->ambient_light.to_linear(); + Color ambient_color = env->ambient_light.srgb_to_linear(); params.ambient_color[0] = ambient_color.r; params.ambient_color[1] = ambient_color.g; params.ambient_color[2] = ambient_color.b; @@ -4653,13 +4653,13 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e params.directional_light_count = p_directional_light_count; - Color emission = env->volumetric_fog_emission.to_linear(); + Color emission = env->volumetric_fog_emission.srgb_to_linear(); params.base_emission[0] = emission.r * env->volumetric_fog_emission_energy; params.base_emission[1] = emission.g * env->volumetric_fog_emission_energy; params.base_emission[2] = emission.b * env->volumetric_fog_emission_energy; params.base_density = env->volumetric_fog_density; - Color base_scattering = env->volumetric_fog_scattering.to_linear(); + Color base_scattering = env->volumetric_fog_scattering.srgb_to_linear(); params.base_scattering[0] = base_scattering.r; params.base_scattering[1] = base_scattering.g; params.base_scattering[2] = base_scattering.b; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 061aa8b4aa..44298711cd 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -1194,7 +1194,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b float sign = storage->light_is_negative(base) ? -1 : 1; sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY); - Color linear_col = storage->light_get_color(base).to_linear(); + Color linear_col = storage->light_get_color(base).srgb_to_linear(); sky_light_data.color[0] = linear_col.r; sky_light_data.color[1] = linear_col.g; sky_light_data.color[2] = linear_col.b; @@ -1286,7 +1286,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b sky_scene_state.ubo.fog_enabled = p_env->fog_enabled; sky_scene_state.ubo.fog_density = p_env->fog_density; sky_scene_state.ubo.fog_aerial_perspective = p_env->fog_aerial_perspective; - Color fog_color = p_env->fog_light_color.to_linear(); + Color fog_color = p_env->fog_light_color.srgb_to_linear(); float fog_energy = p_env->fog_light_energy; sky_scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; sky_scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index 9e3d124bbb..2a2c5f350a 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -422,7 +422,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (i < s) { Color color = a[i]; if (p_linear_color) { - color = color.to_linear(); + color = color.srgb_to_linear(); } gui[j] = color.r; gui[j + 1] = color.g; @@ -459,7 +459,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy Color v = value; if (p_linear_color) { - v = v.to_linear(); + v = v.srgb_to_linear(); } gui[0] = v.r; @@ -1498,7 +1498,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.a; GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1]; - v = v.to_linear(); + v = v.srgb_to_linear(); bv_linear.x = v.r; bv_linear.y = v.g; bv_linear.z = v.b; diff --git a/tests/core/math/test_color.h b/tests/core/math/test_color.h index 6f40f8ecc0..51c3bc8bdc 100644 --- a/tests/core/math/test_color.h +++ b/tests/core/math/test_color.h @@ -146,8 +146,8 @@ TEST_CASE("[Color] Conversion methods") { TEST_CASE("[Color] Linear <-> sRGB conversion") { const Color color = Color(0.35, 0.5, 0.6, 0.7); - const Color color_linear = color.to_linear(); - const Color color_srgb = color.to_srgb(); + const Color color_linear = color.srgb_to_linear(); + const Color color_srgb = color.linear_to_srgb(); CHECK_MESSAGE( color_linear.is_equal_approx(Color(0.100481, 0.214041, 0.318547, 0.7)), "The color converted to linear color space should match the expected value."); @@ -155,10 +155,10 @@ TEST_CASE("[Color] Linear <-> sRGB conversion") { color_srgb.is_equal_approx(Color(0.62621, 0.735357, 0.797738, 0.7)), "The color converted to sRGB color space should match the expected value."); CHECK_MESSAGE( - color_linear.to_srgb().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)), + color_linear.linear_to_srgb().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)), "The linear color converted back to sRGB color space should match the expected value."); CHECK_MESSAGE( - color_srgb.to_linear().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)), + color_srgb.srgb_to_linear().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)), "The sRGB color converted back to linear color space should match the expected value."); } |