summaryrefslogtreecommitdiff
path: root/servers/rendering/rendering_server_canvas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/rendering_server_canvas.cpp')
-rw-r--r--servers/rendering/rendering_server_canvas.cpp152
1 files changed, 75 insertions, 77 deletions
diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp
index fd7c022d62..ffc1ec391d 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, bool p_snap_2d_vertices_to_pixel) {
+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, RasterizerCanvas::Light *p_directional_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,11 @@ 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, p_snap_2d_vertices_to_pixel);
+ bool sdf_flag;
+ RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_directional_lights, p_transform, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, sdf_flag);
+ if (sdf_flag) {
+ sdf_used = true;
+ }
}
void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transform2D p_transform, RenderingServerCanvas::Item *p_material_owner, RenderingServerCanvas::Item **r_items, int &r_index) {
@@ -115,7 +119,7 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
Rect2 rect = ci->get_rect();
Transform2D xform = ci->xform;
if (snapping_2d_transforms_to_pixel) {
- xform.elements[2].floor();
+ xform.elements[2] = xform.elements[2].floor();
}
xform = p_transform * xform;
@@ -298,30 +302,10 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
}
}
-void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights) {
- if (!p_masked_lights) {
- return;
- }
-
- RasterizerCanvas::Item *ci = p_canvas_item;
-
- while (ci) {
- RasterizerCanvas::Light *light = p_masked_lights;
- while (light) {
- if (ci->light_mask & light->item_mask && p_z >= light->z_min && p_z <= light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) {
- ci->light_masked = true;
- }
-
- light = light->mask_next_ptr;
- }
-
- ci = ci->next;
- }
-}
-
-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) {
+void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::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) {
RENDER_TIMESTAMP(">Render Canvas");
+ sdf_used = false;
snapping_2d_transforms_to_pixel = p_snap_2d_transforms_to_pixel;
if (p_canvas->children_order_dirty) {
@@ -341,26 +325,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, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_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, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_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, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_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, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_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, p_snap_2d_vertices_to_pixel);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel);
}
}
}
@@ -368,6 +352,10 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas,
RENDER_TIMESTAMP("<End Render Canvas");
}
+bool RenderingServerCanvas::was_sdf_used() {
+ return sdf_used;
+}
+
RID RenderingServerCanvas::canvas_create() {
Canvas *canvas = memnew(Canvas);
ERR_FAIL_COND_V(!canvas, RID());
@@ -603,7 +591,6 @@ void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Po
}
for (int i = 0; i < p_points.size(); i++) {
-
Vector2 t;
if (i == p_points.size() - 1) {
t = prev_t;
@@ -629,7 +616,6 @@ void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Po
pline->triangles.write[i * 2 + 1] = p_points[i] - tangent;
if (pline->triangle_colors.size() > 1) {
-
pline->triangle_colors.write[i * 2 + 0] = p_colors[i];
pline->triangle_colors.write[i * 2 + 1] = p_colors[i];
}
@@ -1040,13 +1026,38 @@ RID RenderingServerCanvas::canvas_light_create() {
return canvas_light_owner.make_rid(clight);
}
+void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) {
+ RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+ ERR_FAIL_COND(!clight);
+
+ if (clight->mode == p_mode) {
+ return;
+ }
+
+ RID canvas = clight->canvas;
+
+ if (canvas.is_valid()) {
+ canvas_light_attach_to_canvas(p_light, RID());
+ }
+
+ clight->mode = p_mode;
+
+ if (canvas.is_valid()) {
+ canvas_light_attach_to_canvas(p_light, canvas);
+ }
+}
+
void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
if (clight->canvas.is_valid()) {
Canvas *canvas = canvas_owner.getornull(clight->canvas);
- canvas->lights.erase(clight);
+ if (clight->mode == RS::CANVAS_LIGHT_MODE_POINT) {
+ canvas->lights.erase(clight);
+ } else {
+ canvas->directional_lights.erase(clight);
+ }
}
if (!canvas_owner.owns(p_canvas)) {
@@ -1057,7 +1068,11 @@ void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_can
if (clight->canvas.is_valid()) {
Canvas *canvas = canvas_owner.getornull(clight->canvas);
- canvas->lights.insert(clight);
+ if (clight->mode == RS::CANVAS_LIGHT_MODE_POINT) {
+ canvas->lights.insert(clight);
+ } else {
+ canvas->directional_lights.insert(clight);
+ }
}
}
@@ -1068,7 +1083,7 @@ void RenderingServerCanvas::canvas_light_set_enabled(RID p_light, bool p_enabled
clight->enabled = p_enabled;
}
-void RenderingServerCanvas::canvas_light_set_scale(RID p_light, float p_scale) {
+void RenderingServerCanvas::canvas_light_set_texture_scale(RID p_light, float p_scale) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
@@ -1152,11 +1167,18 @@ void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light,
clight->item_shadow_mask = p_mask;
}
-void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) {
+void RenderingServerCanvas::canvas_light_set_directional_distance(RID p_light, float p_distance) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
- clight->mode = p_mode;
+ clight->directional_distance = p_distance;
+}
+
+void RenderingServerCanvas::canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode) {
+ RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->blend_mode = p_mode;
}
void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) {
@@ -1253,6 +1275,11 @@ void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RI
}
}
+void RenderingServerCanvas::canvas_light_occluder_set_as_sdf_collision(RID p_occluder, bool p_enable) {
+ RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
+ ERR_FAIL_COND(!occluder);
+}
+
void RenderingServerCanvas::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) {
RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
@@ -1274,53 +1301,24 @@ RID RenderingServerCanvas::canvas_occluder_polygon_create() {
}
void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) {
- if (p_shape.size() < 3) {
- canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, p_shape);
- return;
- }
-
- Vector<Vector2> lines;
- int lc = p_shape.size() * 2;
-
- lines.resize(lc - (p_closed ? 0 : 2));
- {
- Vector2 *w = lines.ptrw();
- const Vector2 *r = p_shape.ptr();
-
- int max = lc / 2;
- if (!p_closed) {
- max--;
- }
- for (int i = 0; i < max; i++) {
- Vector2 a = r[i];
- Vector2 b = r[(i + 1) % (lc / 2)];
- w[i * 2 + 0] = a;
- w[i * 2 + 1] = b;
- }
- }
-
- canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, lines);
-}
-
-void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon, const Vector<Vector2> &p_shape) {
LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon);
ERR_FAIL_COND(!occluder_poly);
- ERR_FAIL_COND(p_shape.size() & 1);
- int lc = p_shape.size();
+ uint32_t pc = p_shape.size();
+ ERR_FAIL_COND(pc < 2);
+
occluder_poly->aabb = Rect2();
- {
- const Vector2 *r = p_shape.ptr();
- for (int i = 0; i < lc; i++) {
- if (i == 0) {
- occluder_poly->aabb.position = r[i];
- } else {
- occluder_poly->aabb.expand_to(r[i]);
- }
+ const Vector2 *r = p_shape.ptr();
+ for (uint32_t i = 0; i < pc; i++) {
+ if (i == 0) {
+ occluder_poly->aabb.position = r[i];
+ } else {
+ occluder_poly->aabb.expand_to(r[i]);
}
}
- RSG::canvas_render->occluder_polygon_set_shape_as_lines(occluder_poly->occluder, p_shape);
+ RSG::canvas_render->occluder_polygon_set_shape(occluder_poly->occluder, p_shape, p_closed);
+
for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) {
E->get()->aabb_cache = occluder_poly->aabb;
}