diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-09-25 12:39:10 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-09-25 12:39:10 +0200 |
commit | 73bf121ceb8637c88d5ed4bb8721a1feda80dc42 (patch) | |
tree | 4672d32dd4b53a82c4ada16fc78c98a3f9487e1e | |
parent | 70fede82c52998bc3fc7201d8406d21b4e8a6023 (diff) | |
parent | 3f9bb596064b0fb15ad2e5a6a59a9efd339a1974 (diff) | |
download | redot-engine-73bf121ceb8637c88d5ed4bb8721a1feda80dc42.tar.gz |
Merge pull request #93786 from alvinhochun/viewport-pixel-snap-fix
Apply "snap 2D transforms to pixel" to viewport
-rw-r--r-- | scene/2d/parallax_2d.cpp | 6 | ||||
-rw-r--r-- | servers/rendering/renderer_viewport.cpp | 17 |
2 files changed, 22 insertions, 1 deletions
diff --git a/scene/2d/parallax_2d.cpp b/scene/2d/parallax_2d.cpp index fdb2d2cdd0..c6176390dc 100644 --- a/scene/2d/parallax_2d.cpp +++ b/scene/2d/parallax_2d.cpp @@ -83,7 +83,11 @@ void Parallax2D::_validate_property(PropertyInfo &p_property) const { void Parallax2D::_camera_moved(const Transform2D &p_transform, const Point2 &p_screen_offset, const Point2 &p_adj_screen_pos) { if (!ignore_camera_scroll) { if (get_viewport() && get_viewport()->is_snap_2d_transforms_to_pixel_enabled()) { - set_screen_offset((p_adj_screen_pos + Vector2(0.5, 0.5)).floor()); + Size2 vps = get_viewport_rect().size; + Vector2 offset; + offset.x = ((int)vps.width % 2) ? 0.0 : 0.5; + offset.y = ((int)vps.height % 2) ? 0.0 : 0.5; + set_screen_offset((p_adj_screen_pos + offset).floor()); } else { set_screen_offset(p_adj_screen_pos); } diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 781d29ffaa..4d6435f48a 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -41,14 +41,31 @@ static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport, RendererCanvasCull::Canvas *p_canvas, RendererViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) { Transform2D xf = p_viewport->global_transform; + Vector2 pixel_snap_offset; + if (p_viewport->snap_2d_transforms_to_pixel) { + // We use `floor(p + 0.5)` to snap canvas items, but `ceil(p - 0.5)` + // to snap viewport transform because the viewport transform is inverse + // to the camera transform. Also, if the viewport size is not divisible + // by 2, the center point is offset by 0.5 px and we need to add 0.5 + // before rounding to cancel it out. + pixel_snap_offset.x = (p_viewport->size.width % 2) ? 0.0 : -0.5; + pixel_snap_offset.y = (p_viewport->size.height % 2) ? 0.0 : -0.5; + } + float scale = 1.0; if (p_viewport->canvas_map.has(p_canvas->parent)) { Transform2D c_xform = p_viewport->canvas_map[p_canvas->parent].transform; + if (p_viewport->snap_2d_transforms_to_pixel) { + c_xform.columns[2] = (c_xform.columns[2] * p_canvas->parent_scale + pixel_snap_offset).ceil() / p_canvas->parent_scale; + } xf = xf * c_xform; scale = p_canvas->parent_scale; } Transform2D c_xform = p_canvas_data->transform; + if (p_viewport->snap_2d_transforms_to_pixel) { + c_xform.columns[2] = (c_xform.columns[2] + pixel_snap_offset).ceil(); + } xf = xf * c_xform; if (scale != 1.0 && !RSG::canvas->disable_scale) { |