summaryrefslogtreecommitdiffstats
path: root/servers/rendering/renderer_viewport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_viewport.cpp')
-rw-r--r--servers/rendering/renderer_viewport.cpp17
1 files changed, 17 insertions, 0 deletions
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) {