summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/rendering/rasterizer.h2
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp4
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h5
-rw-r--r--servers/rendering/rasterizer_rd/shaders/canvas.glsl2
-rw-r--r--servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl4
-rw-r--r--servers/rendering/rendering_server_canvas.cpp25
-rw-r--r--servers/rendering/rendering_server_canvas.h5
-rw-r--r--servers/rendering/rendering_server_raster.h2
-rw-r--r--servers/rendering/rendering_server_viewport.cpp28
-rw-r--r--servers/rendering/rendering_server_viewport.h9
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h2
-rw-r--r--servers/rendering_server.h2
12 files changed, 68 insertions, 22 deletions
diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h
index 88b92bd35d..b2b2b4977b 100644
--- a/servers/rendering/rasterizer.h
+++ b/servers/rendering/rasterizer.h
@@ -1322,7 +1322,7 @@ public:
}
};
- virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat) = 0;
+ virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) = 0;
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0;
struct LightOccluderInstance {
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
index b268db5989..da30291353 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
@@ -1194,7 +1194,7 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
RD::get_singleton()->draw_list_end();
}
-void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat) {
+void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) {
int item_count = 0;
//setup canvas state uniforms if needed
@@ -1229,6 +1229,8 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y;
state_buffer.time = state.time;
+ state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel;
+
RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer, true);
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
index 4a79134c24..3412435367 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
@@ -79,7 +79,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
FLAGS_NINEPACH_DRAW_CENTER = (1 << 12),
FLAGS_USING_PARTICLES = (1 << 13),
- FLAGS_USE_PIXEL_SNAP = (1 << 14),
FLAGS_USE_SKELETON = (1 << 15),
FLAGS_NINEPATCH_H_MODE_SHIFT = 16,
@@ -334,7 +333,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
float canvas_modulate[4];
float screen_pixel_size[2];
float time;
- float pad;
+ uint32_t use_pixel_snap;
//uint32_t light_count;
//uint32_t pad[3];
@@ -422,7 +421,7 @@ public:
void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines);
void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode);
- void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat);
+ void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel);
void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {}
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/rasterizer_rd/shaders/canvas.glsl
index 04a37e501f..b382c0d85f 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/canvas.glsl
@@ -144,7 +144,7 @@ VERTEX_SHADER_CODE
color_interp = color;
- if (bool(draw_data.flags & FLAGS_USE_PIXEL_SNAP)) {
+ if (canvas_data.use_pixel_snap) {
vertex = floor(vertex + 0.5);
// precision issue on some hardware creates artifacts within texture
// offset uv by a small amount to avoid
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
index e4dc326af6..1a226a87d3 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
@@ -15,7 +15,6 @@
#define FLAGS_USING_LIGHT_MASK (1 << 11)
#define FLAGS_NINEPACH_DRAW_CENTER (1 << 12)
#define FLAGS_USING_PARTICLES (1 << 13)
-#define FLAGS_USE_PIXEL_SNAP (1 << 14)
#define FLAGS_NINEPATCH_H_MODE_SHIFT 16
#define FLAGS_NINEPATCH_V_MODE_SHIFT 18
@@ -67,7 +66,8 @@ layout(set = 0, binding = 1, std140) uniform CanvasData {
vec4 canvas_modulation;
vec2 screen_pixel_size;
float time;
- float time_pad;
+ bool use_pixel_snap;
+
//uint light_count;
}
canvas_data;
diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp
index f06667a460..fd7c022d62 100644
--- a/servers/rendering/rendering_server_canvas.cpp
+++ b/servers/rendering/rendering_server_canvas.cpp
@@ -37,7 +37,7 @@
static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
-void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat) {
+void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) {
RENDER_TIMESTAMP("Cull CanvasItem Tree");
memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *));
@@ -68,7 +68,7 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can
RENDER_TIMESTAMP("Render Canvas Items");
- RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform, p_default_filter, p_default_repeat);
+ RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
}
void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transform2D p_transform, RenderingServerCanvas::Item *p_material_owner, RenderingServerCanvas::Item **r_items, int &r_index) {
@@ -113,7 +113,12 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
}
Rect2 rect = ci->get_rect();
- Transform2D xform = p_transform * ci->xform;
+ Transform2D xform = ci->xform;
+ if (snapping_2d_transforms_to_pixel) {
+ xform.elements[2].floor();
+ }
+ xform = p_transform * xform;
+
Rect2 global_rect = xform.xform(rect);
global_rect.position += p_clip_rect.position;
@@ -314,9 +319,11 @@ void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::
}
}
-void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat) {
+void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_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) {
RENDER_TIMESTAMP(">Render Canvas");
+ snapping_2d_transforms_to_pixel = p_snap_2d_transforms_to_pixel;
+
if (p_canvas->children_order_dirty) {
p_canvas->child_items.sort();
p_canvas->children_order_dirty = false;
@@ -334,26 +341,26 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas,
}
if (!has_mirror) {
- _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
+ _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
} else {
//used for parallaxlayer mirroring
for (int i = 0; i < l; i++) {
const Canvas::ChildItem &ci2 = p_canvas->child_items[i];
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
//mirroring (useful for scrolling backgrounds)
if (ci2.mirror.x != 0) {
Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0));
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
}
if (ci2.mirror.y != 0) {
Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y));
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
}
if (ci2.mirror.y != 0 && ci2.mirror.x != 0) {
Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror);
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
}
}
}
diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/rendering_server_canvas.h
index 8eed6e72d9..a9a81888aa 100644
--- a/servers/rendering/rendering_server_canvas.h
+++ b/servers/rendering/rendering_server_canvas.h
@@ -152,9 +152,10 @@ public:
RID_PtrOwner<RasterizerCanvas::Light> canvas_light_owner;
bool disable_scale;
+ bool snapping_2d_transforms_to_pixel = false;
private:
- void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat);
+ void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel);
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner);
void _light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights);
@@ -162,7 +163,7 @@ private:
RasterizerCanvas::Item **z_last_list;
public:
- void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat);
+ void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_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);
RID canvas_create();
void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring);
diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h
index 1c222a48c4..a89d4db1f8 100644
--- a/servers/rendering/rendering_server_raster.h
+++ b/servers/rendering/rendering_server_raster.h
@@ -528,6 +528,8 @@ public:
BIND2(viewport_remove_canvas, RID, RID)
BIND3(viewport_set_canvas_transform, RID, RID, const Transform2D &)
BIND2(viewport_set_transparent_background, RID, bool)
+ BIND2(viewport_set_snap_2d_transforms_to_pixel, RID, bool)
+ BIND2(viewport_set_snap_2d_vertices_to_pixel, RID, bool)
BIND2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter)
BIND2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat)
diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp
index a8dbe1e254..b5d8f0da40 100644
--- a/servers/rendering/rendering_server_viewport.cpp
+++ b/servers/rendering/rendering_server_viewport.cpp
@@ -40,11 +40,21 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi
float scale = 1.0;
if (p_viewport->canvas_map.has(p_canvas->parent)) {
- xf = xf * p_viewport->canvas_map[p_canvas->parent].transform;
+ Transform2D c_xform = p_viewport->canvas_map[p_canvas->parent].transform;
+ if (p_viewport->snap_2d_transforms_to_pixel) {
+ c_xform.elements[2] = c_xform.elements[2].floor();
+ }
+ xf = xf * c_xform;
scale = p_canvas->parent_scale;
}
- xf = xf * p_canvas_data->transform;
+ Transform2D c_xform = p_canvas_data->transform;
+
+ if (p_viewport->snap_2d_transforms_to_pixel) {
+ c_xform.elements[2] = c_xform.elements[2].floor();
+ }
+
+ xf = xf * c_xform;
if (scale != 1.0 && !RSG::canvas->disable_scale) {
Vector2 pivot = p_vp_size * 0.5;
@@ -255,7 +265,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
ptr = ptr->filter_next_ptr;
}
- RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, lights_with_mask, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat);
+ RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, lights_with_mask, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel);
i++;
if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) {
@@ -774,6 +784,18 @@ float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewp
return double((viewport->time_gpu_end - viewport->time_gpu_begin) / 1000) / 1000.0;
}
+void RenderingServerViewport::viewport_set_snap_2d_transforms_to_pixel(RID p_viewport, bool p_enabled) {
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+ viewport->snap_2d_transforms_to_pixel = p_enabled;
+}
+
+void RenderingServerViewport::viewport_set_snap_2d_vertices_to_pixel(RID p_viewport, bool p_enabled) {
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+ viewport->snap_2d_vertices_to_pixel = p_enabled;
+}
+
void RenderingServerViewport::viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter) {
ERR_FAIL_COND_MSG(p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, "Viewport does not accept DEFAULT as texture filter (it's the topmost choice already).)");
Viewport *viewport = viewport_owner.getornull(p_viewport);
diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h
index 161ae94fb0..d00a06c5ee 100644
--- a/servers/rendering/rendering_server_viewport.h
+++ b/servers/rendering/rendering_server_viewport.h
@@ -70,6 +70,9 @@ public:
bool disable_environment;
bool measure_render_time;
+ bool snap_2d_transforms_to_pixel;
+ bool snap_2d_vertices_to_pixel;
+
uint64_t time_cpu_begin;
uint64_t time_cpu_end;
@@ -136,6 +139,9 @@ public:
screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED;
use_debanding = false;
+ snap_2d_transforms_to_pixel = false;
+ snap_2d_vertices_to_pixel = false;
+
for (int i = 0; i < RS::VIEWPORT_RENDER_INFO_MAX; i++) {
render_info[i] = 0;
}
@@ -220,6 +226,9 @@ public:
float viewport_get_measured_render_time_cpu(RID p_viewport) const;
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_vertices_to_pixel(RID p_viewport, bool p_enabled);
+
void viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter);
void viewport_set_default_canvas_item_texture_repeat(RID p_viewport, RS::CanvasItemTextureRepeat p_repeat);
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
index 89fd713265..42f1b5bcc8 100644
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ b/servers/rendering/rendering_server_wrap_mt.h
@@ -431,6 +431,8 @@ public:
FUNC2(viewport_remove_canvas, RID, RID)
FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &)
FUNC2(viewport_set_transparent_background, RID, bool)
+ FUNC2(viewport_set_snap_2d_transforms_to_pixel, RID, bool)
+ FUNC2(viewport_set_snap_2d_vertices_to_pixel, RID, bool)
FUNC2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter)
FUNC2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat)
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index a7df1687e0..a33215a882 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -720,6 +720,8 @@ public:
virtual void viewport_remove_canvas(RID p_viewport, RID p_canvas) = 0;
virtual void viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) = 0;
virtual void viewport_set_transparent_background(RID p_viewport, bool p_enabled) = 0;
+ virtual void viewport_set_snap_2d_transforms_to_pixel(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;
virtual void viewport_set_default_canvas_item_texture_repeat(RID p_viewport, CanvasItemTextureRepeat p_repeat) = 0;