From a122d133d4152576f007b33d5331b7beb1b74a7a Mon Sep 17 00:00:00 2001 From: Adam Scott Date: Fri, 26 Jul 2024 15:33:58 -0400 Subject: [PATCH] Add true center snap option --- editor/editor_node.cpp | 1 + scene/main/canvas_item.cpp | 62 +++++++++++++++++++- scene/main/canvas_item.h | 16 +++++ scene/main/scene_tree.cpp | 3 + scene/main/viewport.cpp | 15 +++++ scene/main/viewport.h | 4 ++ servers/rendering/renderer_canvas_cull.cpp | 39 ++++++++++-- servers/rendering/renderer_canvas_cull.h | 4 +- servers/rendering/renderer_canvas_render.h | 1 + servers/rendering/renderer_viewport.cpp | 8 ++- servers/rendering/renderer_viewport.h | 2 + servers/rendering/rendering_server_default.h | 2 + servers/rendering_server.cpp | 1 + servers/rendering_server.h | 9 +++ 14 files changed, 159 insertions(+), 8 deletions(-) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index cb647ffc35d..67a17d0a554 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -659,6 +659,7 @@ void EditorNode::_notification(int p_what) { get_tree()->get_root()->set_as_audio_listener_3d(false); get_tree()->get_root()->set_as_audio_listener_2d(false); get_tree()->get_root()->set_snap_2d_transforms_to_pixel(false); + get_tree()->get_root()->set_snap_2d_transforms_to_pixel_true_center(false); get_tree()->get_root()->set_snap_2d_vertices_to_pixel(false); get_tree()->set_auto_accept_quit(false); #ifdef ANDROID_ENABLED diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index ce372cf13b7..27520927fe6 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -329,6 +329,7 @@ void CanvasItem::_notification(int p_what) { _update_texture_filter_changed(false); _update_texture_repeat_changed(false); _update_snap_to_pixel_changed(false); + _update_snap_to_pixel_true_center_changed(false); if (!block_transform_notify && !xform_change.in_list()) { get_tree()->xform_change_list.add(&xform_change); @@ -1271,9 +1272,12 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("set_clip_children_mode", "mode"), &CanvasItem::set_clip_children_mode); ClassDB::bind_method(D_METHOD("get_clip_children_mode"), &CanvasItem::get_clip_children_mode); - ClassDB::bind_method(D_METHOD("set_snap_to_pixel", "snap"), &CanvasItem::set_snap_to_pixel); + ClassDB::bind_method(D_METHOD("set_snap_to_pixel", "mode"), &CanvasItem::set_snap_to_pixel); ClassDB::bind_method(D_METHOD("get_snap_to_pixel"), &CanvasItem::get_snap_to_pixel); + ClassDB::bind_method(D_METHOD("set_snap_to_pixel_true_center", "mode"), &CanvasItem::set_snap_to_pixel_true_center); + ClassDB::bind_method(D_METHOD("get_snap_to_pixel_true_center"), &CanvasItem::get_snap_to_pixel_true_center); + GDVIRTUAL_BIND(_draw); ADD_GROUP("Visibility", ""); @@ -1301,6 +1305,7 @@ void CanvasItem::_bind_methods() { ADD_GROUP("Snap", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_to_pixel", PROPERTY_HINT_ENUM, "Inherit,Disabled,Enabled"), "set_snap_to_pixel", "get_snap_to_pixel"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_to_pixel_true_center", PROPERTY_HINT_ENUM, "Inherit,Disabled,Enabled"), "set_snap_to_pixel_true_center", "get_snap_to_pixel_true_center"); // ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),"set_transform_notify","is_transform_notify_enabled"); @@ -1634,6 +1639,61 @@ CanvasItem::SnapToPixel CanvasItem::get_snap_to_pixel() const { return snap_to_pixel; } +void CanvasItem::_refresh_snap_to_pixel_true_center_cache() const { + if (!is_inside_tree()) { + return; + } + + if (snap_to_pixel_true_center == SNAP_TO_PIXEL_TRUE_CENTER_PARENT_NODE) { + CanvasItem *parent_item = get_parent_item(); + if (parent_item) { + snap_to_pixel_true_center_cache = parent_item->snap_to_pixel_true_center_cache; + } else { + snap_to_pixel_true_center_cache = RS::CANVAS_ITEM_SNAP_TO_PIXEL_TRUE_CENTER_DEFAULT; + } + } else { + snap_to_pixel_true_center_cache = RS::CanvasItemSnapToPixelTrueCenter(snap_to_pixel_true_center); + } +} + +void CanvasItem::_update_self_snap_to_pixel_true_center(RS::CanvasItemSnapToPixelTrueCenter p_snap_to_pixel_true_center) { + RS::get_singleton()->canvas_item_set_snap_to_pixel_true_center(get_canvas_item(), p_snap_to_pixel_true_center); + queue_redraw(); +} + +void CanvasItem::_update_snap_to_pixel_true_center_changed(bool p_propagate) { + if (!is_inside_tree()) { + return; + } + _refresh_snap_to_pixel_true_center_cache(); + _update_self_snap_to_pixel_true_center(snap_to_pixel_true_center_cache); + + if (p_propagate) { + for (CanvasItem *E : children_items) { + if (!E->top_level && E->snap_to_pixel_true_center == SNAP_TO_PIXEL_TRUE_CENTER_PARENT_NODE) { + E->_update_snap_to_pixel_true_center_changed(true); + } + } + } +} + +void CanvasItem::set_snap_to_pixel_true_center(SnapToPixelTrueCenter p_snap_to_pixel_true_center) { + ERR_THREAD_GUARD; + + if (snap_to_pixel_true_center == p_snap_to_pixel_true_center) { + return; + } + + snap_to_pixel_true_center = p_snap_to_pixel_true_center; + _update_snap_to_pixel_true_center_changed(true); + notify_property_list_changed(); +} + +CanvasItem::SnapToPixelTrueCenter CanvasItem::get_snap_to_pixel_true_center() const { + ERR_READ_THREAD_GUARD_V(SNAP_TO_PIXEL_TRUE_CENTER_DISABLED); + return snap_to_pixel_true_center; +} + CanvasItem::CanvasItem() : xform_change(this) { canvas_item = RenderingServer::get_singleton()->canvas_item_create(); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 4bf169d127a..b43ed96b964 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -80,6 +80,13 @@ public: SNAP_TO_PIXEL_MAX, }; + enum SnapToPixelTrueCenter { + SNAP_TO_PIXEL_TRUE_CENTER_PARENT_NODE, + SNAP_TO_PIXEL_TRUE_CENTER_DISABLED, + SNAP_TO_PIXEL_TRUE_CENTER_ENABLED, + SNAP_TO_PIXEL_TRUE_CENTER_MAX, + }; + private: mutable SelfList xform_change; @@ -120,9 +127,11 @@ private: mutable RS::CanvasItemTextureFilter texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; mutable RS::CanvasItemTextureRepeat texture_repeat_cache = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; mutable RS::CanvasItemSnapToPixel snap_to_pixel_cache = RS::CANVAS_ITEM_SNAP_TO_PIXEL_DISABLED; + mutable RS::CanvasItemSnapToPixelTrueCenter snap_to_pixel_true_center_cache = RS::CANVAS_ITEM_SNAP_TO_PIXEL_TRUE_CENTER_DISABLED; TextureFilter texture_filter = TEXTURE_FILTER_PARENT_NODE; TextureRepeat texture_repeat = TEXTURE_REPEAT_PARENT_NODE; SnapToPixel snap_to_pixel = SNAP_TO_PIXEL_PARENT_NODE; + SnapToPixelTrueCenter snap_to_pixel_true_center = SNAP_TO_PIXEL_TRUE_CENTER_PARENT_NODE; Ref material; @@ -159,6 +168,8 @@ private: void _update_texture_filter_changed(bool p_propagate); void _refresh_snap_to_pixel_cache() const; void _update_snap_to_pixel_changed(bool p_propagate); + void _refresh_snap_to_pixel_true_center_cache() const; + void _update_snap_to_pixel_true_center_changed(bool p_propagate); void _notify_transform_deferred(); @@ -166,6 +177,7 @@ protected: virtual void _update_self_texture_repeat(RS::CanvasItemTextureRepeat p_texture_repeat); virtual void _update_self_texture_filter(RS::CanvasItemTextureFilter p_texture_filter); virtual void _update_self_snap_to_pixel(RS::CanvasItemSnapToPixel p_snap); + virtual void _update_self_snap_to_pixel_true_center(RS::CanvasItemSnapToPixelTrueCenter p_snap_true_center); _FORCE_INLINE_ void _notify_transform() { _notify_transform(this); @@ -395,6 +407,9 @@ public: virtual void set_snap_to_pixel(SnapToPixel p_snap_to_pixel); SnapToPixel get_snap_to_pixel() const; + virtual void set_snap_to_pixel_true_center(SnapToPixelTrueCenter p_snap_to_pixel_true_center); + SnapToPixelTrueCenter get_snap_to_pixel_true_center() const; + CanvasItem(); ~CanvasItem(); }; @@ -403,6 +418,7 @@ VARIANT_ENUM_CAST(CanvasItem::TextureFilter) VARIANT_ENUM_CAST(CanvasItem::TextureRepeat) VARIANT_ENUM_CAST(CanvasItem::ClipChildrenMode) VARIANT_ENUM_CAST(CanvasItem::SnapToPixel) +VARIANT_ENUM_CAST(CanvasItem::SnapToPixelTrueCenter) class CanvasTexture : public Texture2D { GDCLASS(CanvasTexture, Texture2D); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index ced6d9aaa63..1d26b24f159 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1797,6 +1797,9 @@ SceneTree::SceneTree() { bool snap_2d_transforms = GLOBAL_DEF_BASIC("rendering/2d/snap/snap_2d_transforms_to_pixel", false); root->set_snap_2d_transforms_to_pixel(snap_2d_transforms); + bool snap_2d_transforms_true_center = GLOBAL_DEF_BASIC("rendering/2d/snap/snap_2d_transforms_to_pixel_true_center", false); + root->set_snap_2d_transforms_to_pixel_true_center(snap_2d_transforms_true_center); + bool snap_2d_vertices = GLOBAL_DEF("rendering/2d/snap/snap_2d_vertices_to_pixel", false); root->set_snap_2d_vertices_to_pixel(snap_2d_vertices); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 1302e3c53e6..64ac41cebb2 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -3576,6 +3576,17 @@ bool Viewport::is_snap_2d_transforms_to_pixel_enabled() const { return snap_2d_transforms_to_pixel; } +void Viewport::set_snap_2d_transforms_to_pixel_true_center(bool p_enable) { + ERR_MAIN_THREAD_GUARD; + snap_2d_transforms_to_pixel_true_center = p_enable; + RS::get_singleton()->viewport_set_snap_2d_transforms_to_pixel_true_center(viewport, snap_2d_transforms_to_pixel_true_center); +} + +bool Viewport::is_snap_2d_transforms_to_pixel_true_center_enabled() const { + ERR_READ_THREAD_GUARD_V(false); + return snap_2d_transforms_to_pixel_true_center; +} + void Viewport::set_snap_2d_vertices_to_pixel(bool p_enable) { ERR_MAIN_THREAD_GUARD; snap_2d_vertices_to_pixel = p_enable; @@ -4729,6 +4740,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_snap_2d_transforms_to_pixel", "enabled"), &Viewport::set_snap_2d_transforms_to_pixel); ClassDB::bind_method(D_METHOD("is_snap_2d_transforms_to_pixel_enabled"), &Viewport::is_snap_2d_transforms_to_pixel_enabled); + ClassDB::bind_method(D_METHOD("set_snap_2d_transforms_to_pixel_true_center", "enabled"), &Viewport::set_snap_2d_transforms_to_pixel_true_center); + ClassDB::bind_method(D_METHOD("is_snap_2d_transforms_to_pixel_true_center_enabled"), &Viewport::is_snap_2d_transforms_to_pixel_true_center_enabled); + ClassDB::bind_method(D_METHOD("set_snap_2d_vertices_to_pixel", "enabled"), &Viewport::set_snap_2d_vertices_to_pixel); ClassDB::bind_method(D_METHOD("is_snap_2d_vertices_to_pixel_enabled"), &Viewport::is_snap_2d_vertices_to_pixel_enabled); @@ -4820,6 +4834,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent_bg"), "set_transparent_background", "has_transparent_background"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel"), "set_snap_2d_transforms_to_pixel", "is_snap_2d_transforms_to_pixel_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel_true_center"), "set_snap_2d_transforms_to_pixel_true_center", "is_snap_2d_transforms_to_pixel_true_center_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_vertices_to_pixel"), "set_snap_2d_vertices_to_pixel", "is_snap_2d_vertices_to_pixel_enabled"); ADD_GROUP("Rendering", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa_2d", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Average),4× (Slow),8× (Slowest)")), "set_msaa_2d", "get_msaa_2d"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 0d31c07e57e..c8b272530cd 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -255,6 +255,7 @@ private: bool snap_controls_to_pixels = true; bool snap_2d_transforms_to_pixel = false; + bool snap_2d_transforms_to_pixel_true_center = false; bool snap_2d_vertices_to_pixel = false; bool physics_object_picking = false; @@ -613,6 +614,9 @@ public: void set_snap_2d_transforms_to_pixel(bool p_enable); bool is_snap_2d_transforms_to_pixel_enabled() const; + void set_snap_2d_transforms_to_pixel_true_center(bool p_enable); + bool is_snap_2d_transforms_to_pixel_true_center_enabled() const; + void set_snap_2d_vertices_to_pixel(bool p_enable); bool is_snap_2d_vertices_to_pixel_enabled() const; diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index cef9d3ad299..bc9e6185e06 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -285,12 +285,34 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 rect.position -= repeat_size / scale * (repeat_times / 2); } - if ((p_canvas_item->snap_to_pixel == RS::CANVAS_ITEM_SNAP_TO_PIXEL_DEFAULT && snapping_2d_transforms_to_pixel) || (p_canvas_item->snap_to_pixel == RS::CANVAS_ITEM_SNAP_TO_PIXEL_ENABLED)) { + // Snapping to pixels. + const bool snap_to_pixel_default = p_canvas_item->snap_to_pixel == RS::CANVAS_ITEM_SNAP_TO_PIXEL_DEFAULT; + const bool snap_to_pixel_force = p_canvas_item->snap_to_pixel == RS::CANVAS_ITEM_SNAP_TO_PIXEL_ENABLED; + if ((snap_to_pixel_default && snapping_2d_transforms_to_pixel) || snap_to_pixel_force) { Size2 scale = final_xform.get_scale().snappedf(0.0001); Point2 abs_scaled_position = (rect.position * scale).abs(); - Point2 odd_sized_correction = Point2( - Math::abs(Math::fmod(rect.position.x, 1.0l)), - Math::abs(Math::fmod(rect.position.y, 1.0l))); + Point2 odd_sized_correction; + + const bool snap_to_pixel_true_center_default = p_canvas_item->snap_to_pixel_true_center == RS::CANVAS_ITEM_SNAP_TO_PIXEL_TRUE_CENTER_DEFAULT; + const bool snap_to_pixel_true_center_force = p_canvas_item->snap_to_pixel_true_center == RS::CANVAS_ITEM_SNAP_TO_PIXEL_TRUE_CENTER_ENABLED; + if ((snap_to_pixel_true_center_default && snapping_2d_transforms_to_pixel_true_center) || snap_to_pixel_true_center_force) { + odd_sized_correction = Point2( + Math::abs(Math::fmod(rect.position.x * scale.x, 1.0l)), + Math::abs(Math::fmod(rect.position.y * scale.y, 1.0l))); + + if (scale.x >= 0.5) { + odd_sized_correction.x = (2 * odd_sized_correction.x) * (1 - odd_sized_correction.x); + odd_sized_correction.x = odd_sized_correction.x >= 0.25 ? 0.5 : 0.0; + } + if (scale.y >= 0.5) { + odd_sized_correction.y = (2 * odd_sized_correction.y) * (1 - odd_sized_correction.y); + odd_sized_correction.y = odd_sized_correction.y >= 0.25 ? 0.5 : 0.0; + } + } else { + odd_sized_correction = Point2( + Math::abs(Math::fmod(rect.position.x, 1.0l)), + Math::abs(Math::fmod(rect.position.y, 1.0l))); + } // If the snapped canvas is smaller than a pixel, snap to the origin. if (abs_scaled_position.x < 0.5) { @@ -409,11 +431,12 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 } } -void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info) { +void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_transforms_to_pixel_true_center, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info) { RENDER_TIMESTAMP("> Render Canvas"); sdf_used = false; snapping_2d_transforms_to_pixel = p_snap_2d_transforms_to_pixel; + snapping_2d_transforms_to_pixel_true_center = p_snap_2d_transforms_to_pixel_true_center; if (p_canvas->children_order_dirty) { p_canvas->child_items.sort(); @@ -2333,6 +2356,12 @@ void RendererCanvasCull::canvas_item_set_snap_to_pixel(RID p_item, RS::CanvasIte ci->snap_to_pixel = p_snap; } +void RendererCanvasCull::canvas_item_set_snap_to_pixel_true_center(RID p_item, RS::CanvasItemSnapToPixelTrueCenter p_snap_to_pixel_true_center) { + Item *ci = canvas_item_owner.get_or_null(p_item); + ERR_FAIL_NULL(ci); + ci->snap_to_pixel_true_center = p_snap_to_pixel_true_center; +} + void RendererCanvasCull::update_visibility_notifiers() { SelfList *E = visibility_notifier_list.first(); while (E) { diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index edcba0c2cbb..ec0c1bb9648 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -176,6 +176,7 @@ public: bool disable_scale; bool sdf_used = false; bool snapping_2d_transforms_to_pixel = false; + bool snapping_2d_transforms_to_pixel_true_center = false; bool debug_redraw = false; double debug_redraw_time = 0; @@ -196,7 +197,7 @@ private: RendererCanvasRender::Item **z_last_list; public: - void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info = nullptr); + void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_transforms_to_pixel_true_center, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info = nullptr); bool was_sdf_used(); @@ -340,6 +341,7 @@ public: void canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter); void canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat); void canvas_item_set_snap_to_pixel(RID p_item, RS::CanvasItemSnapToPixel p_snap); + void canvas_item_set_snap_to_pixel_true_center(RID p_item, RS::CanvasItemSnapToPixelTrueCenter p_snap_true_center); void update_visibility_notifiers(); diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h index 2c0d9bd6328..b34cbb7bbb2 100644 --- a/servers/rendering/renderer_canvas_render.h +++ b/servers/rendering/renderer_canvas_render.h @@ -459,6 +459,7 @@ public: RS::CanvasItemTextureFilter texture_filter; RS::CanvasItemTextureRepeat texture_repeat; RS::CanvasItemSnapToPixel snap_to_pixel; + RS::CanvasItemSnapToPixelTrueCenter snap_to_pixel_true_center; Item() { commands = nullptr; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 10e295ab04d..c7b6ab6f826 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -613,7 +613,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { ptr = ptr->filter_next_ptr; } - RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel, p_viewport->canvas_cull_mask, &p_viewport->render_info); + RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_transforms_to_pixel_true_center, p_viewport->snap_2d_vertices_to_pixel, p_viewport->canvas_cull_mask, &p_viewport->render_info); if (RSG::canvas->was_sdf_used()) { p_viewport->sdf_active = true; } @@ -1407,6 +1407,12 @@ void RendererViewport::viewport_set_snap_2d_transforms_to_pixel(RID p_viewport, viewport->snap_2d_transforms_to_pixel = p_enabled; } +void RendererViewport::viewport_set_snap_2d_transforms_to_pixel_true_center(RID p_viewport, bool p_enabled) { + Viewport *viewport = viewport_owner.get_or_null(p_viewport); + ERR_FAIL_NULL(viewport); + viewport->snap_2d_transforms_to_pixel_true_center = p_enabled; +} + void RendererViewport::viewport_set_snap_2d_vertices_to_pixel(RID p_viewport, bool p_enabled) { Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_NULL(viewport); diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index b36fc7f57ff..087d6dfc9d7 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -94,6 +94,7 @@ public: bool measure_render_time = false; bool snap_2d_transforms_to_pixel = false; + bool snap_2d_transforms_to_pixel_true_center = false; bool snap_2d_vertices_to_pixel = false; uint64_t time_cpu_begin; @@ -288,6 +289,7 @@ public: float viewport_get_measured_render_time_gpu(RID p_viewport) const; void viewport_set_snap_2d_transforms_to_pixel(RID p_viewport, bool p_enabled); + void viewport_set_snap_2d_transforms_to_pixel_true_center(RID p_viewport, bool p_enabled); void viewport_set_snap_2d_vertices_to_pixel(RID p_viewport, bool p_enabled); void viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 3e28839bd05..4e82dffccad 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -640,6 +640,7 @@ public: FUNC2(viewport_set_transparent_background, RID, bool) FUNC2(viewport_set_use_hdr_2d, RID, bool) FUNC2(viewport_set_snap_2d_transforms_to_pixel, RID, bool) + FUNC2(viewport_set_snap_2d_transforms_to_pixel_true_center, RID, bool) FUNC2(viewport_set_snap_2d_vertices_to_pixel, RID, bool) FUNC2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter) @@ -884,6 +885,7 @@ public: FUNC2(canvas_item_set_draw_behind_parent, RID, bool) FUNC2(canvas_item_set_snap_to_pixel, RID, CanvasItemSnapToPixel) + FUNC2(canvas_item_set_snap_to_pixel_true_center, RID, CanvasItemSnapToPixelTrueCenter) FUNC6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool) FUNC5(canvas_item_add_polyline, RID, const Vector &, const Vector &, float, bool) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 70b585d6834..834644c3057 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2793,6 +2793,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_attach_canvas", "viewport", "canvas"), &RenderingServer::viewport_attach_canvas); ClassDB::bind_method(D_METHOD("viewport_remove_canvas", "viewport", "canvas"), &RenderingServer::viewport_remove_canvas); ClassDB::bind_method(D_METHOD("viewport_set_snap_2d_transforms_to_pixel", "viewport", "enabled"), &RenderingServer::viewport_set_snap_2d_transforms_to_pixel); + ClassDB::bind_method(D_METHOD("viewport_set_snap_2d_transforms_to_pixel_true_center", "viewport", "enabled"), &RenderingServer::viewport_set_snap_2d_transforms_to_pixel_true_center); ClassDB::bind_method(D_METHOD("viewport_set_snap_2d_vertices_to_pixel", "viewport", "enabled"), &RenderingServer::viewport_set_snap_2d_vertices_to_pixel); ClassDB::bind_method(D_METHOD("viewport_set_default_canvas_item_texture_filter", "viewport", "filter"), &RenderingServer::viewport_set_default_canvas_item_texture_filter); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index d9ee94d942c..66e2eae9ab8 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -867,6 +867,13 @@ public: CANVAS_ITEM_SNAP_TO_PIXEL_MAX, }; + enum CanvasItemSnapToPixelTrueCenter { + CANVAS_ITEM_SNAP_TO_PIXEL_TRUE_CENTER_DEFAULT, + CANVAS_ITEM_SNAP_TO_PIXEL_TRUE_CENTER_DISABLED, + CANVAS_ITEM_SNAP_TO_PIXEL_TRUE_CENTER_ENABLED, + CANVAS_ITEM_SNAP_TO_PIXEL_TRUE_CENTER_MAX, + }; + virtual RID viewport_create() = 0; enum ViewportScaling3DMode { @@ -932,6 +939,7 @@ public: virtual void viewport_set_transparent_background(RID p_viewport, bool p_enabled) = 0; virtual void viewport_set_use_hdr_2d(RID p_viewport, bool p_use_hdr) = 0; virtual void viewport_set_snap_2d_transforms_to_pixel(RID p_viewport, bool p_enabled) = 0; + virtual void viewport_set_snap_2d_transforms_to_pixel_true_center(RID p_viewport, bool p_enabled) = 0; virtual void viewport_set_snap_2d_vertices_to_pixel(RID p_viewport, bool p_enabled) = 0; virtual void viewport_set_default_canvas_item_texture_filter(RID p_viewport, CanvasItemTextureFilter p_filter) = 0; @@ -1459,6 +1467,7 @@ public: virtual void canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) = 0; virtual void canvas_item_set_snap_to_pixel(RID p_item, CanvasItemSnapToPixel p_snap) = 0; + virtual void canvas_item_set_snap_to_pixel_true_center(RID p_item, CanvasItemSnapToPixelTrueCenter p_snap_to_pixel_true_center) = 0; enum NinePatchAxisMode { NINE_PATCH_STRETCH,