|
@@ -37,17 +37,14 @@
|
|
#include "rendering_server_globals.h"
|
|
#include "rendering_server_globals.h"
|
|
#include "servers/rendering/storage/texture_storage.h"
|
|
#include "servers/rendering/storage/texture_storage.h"
|
|
|
|
|
|
-void RendererCanvasCull::_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, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info) {
|
|
|
|
|
|
+void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info) {
|
|
RENDER_TIMESTAMP("Cull CanvasItem Tree");
|
|
RENDER_TIMESTAMP("Cull CanvasItem Tree");
|
|
|
|
|
|
memset(z_list, 0, z_range * sizeof(RendererCanvasRender::Item *));
|
|
memset(z_list, 0, z_range * sizeof(RendererCanvasRender::Item *));
|
|
memset(z_last_list, 0, z_range * sizeof(RendererCanvasRender::Item *));
|
|
memset(z_last_list, 0, z_range * sizeof(RendererCanvasRender::Item *));
|
|
|
|
|
|
for (int i = 0; i < p_child_item_count; i++) {
|
|
for (int i = 0; i < p_child_item_count; i++) {
|
|
- _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true, p_canvas_cull_mask);
|
|
|
|
- }
|
|
|
|
- if (p_canvas_item) {
|
|
|
|
- _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true, p_canvas_cull_mask);
|
|
|
|
|
|
+ _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true, p_canvas_cull_mask, p_child_items[i].mirror, 1);
|
|
}
|
|
}
|
|
|
|
|
|
RendererCanvasRender::Item *list = nullptr;
|
|
RendererCanvasRender::Item *list = nullptr;
|
|
@@ -223,7 +220,7 @@ void RendererCanvasCull::_attach_canvas_item_for_draw(RendererCanvasCull::Item *
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_parent_xform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool p_allow_y_sort, uint32_t p_canvas_cull_mask) {
|
|
|
|
|
|
+void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_parent_xform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool p_allow_y_sort, uint32_t p_canvas_cull_mask, const Point2 &p_repeat_size, int p_repeat_times) {
|
|
Item *ci = p_canvas_item;
|
|
Item *ci = p_canvas_item;
|
|
|
|
|
|
if (!ci->visible) {
|
|
if (!ci->visible) {
|
|
@@ -250,6 +247,22 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|
Transform2D xform = ci->xform;
|
|
Transform2D xform = ci->xform;
|
|
Transform2D parent_xform = p_parent_xform;
|
|
Transform2D parent_xform = p_parent_xform;
|
|
|
|
|
|
|
|
+ Point2 repeat_size = p_repeat_size;
|
|
|
|
+ int repeat_times = p_repeat_times;
|
|
|
|
+
|
|
|
|
+ if (ci->repeat_source) {
|
|
|
|
+ repeat_size = ci->repeat_size;
|
|
|
|
+ repeat_times = ci->repeat_times;
|
|
|
|
+ } else {
|
|
|
|
+ ci->repeat_size = repeat_size;
|
|
|
|
+ ci->repeat_times = repeat_times;
|
|
|
|
+
|
|
|
|
+ if (repeat_size.x || repeat_size.y) {
|
|
|
|
+ rect.size += repeat_size * repeat_times / ci->xform.get_scale();
|
|
|
|
+ rect.position -= repeat_size * (repeat_times / 2);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
if (snapping_2d_transforms_to_pixel) {
|
|
if (snapping_2d_transforms_to_pixel) {
|
|
xform.columns[2] = xform.columns[2].round();
|
|
xform.columns[2] = xform.columns[2].round();
|
|
parent_xform.columns[2] = parent_xform.columns[2].round();
|
|
parent_xform.columns[2] = parent_xform.columns[2].round();
|
|
@@ -324,7 +337,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|
sorter.sort(child_items, child_item_count);
|
|
sorter.sort(child_items, child_item_count);
|
|
|
|
|
|
for (i = 0; i < child_item_count; i++) {
|
|
for (i = 0; i < child_item_count; i++) {
|
|
- _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, child_items[i]->ysort_parent_abs_z_index, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false, p_canvas_cull_mask);
|
|
|
|
|
|
+ _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, child_items[i]->ysort_parent_abs_z_index, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false, p_canvas_cull_mask, repeat_size, repeat_times);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
RendererCanvasRender::Item *canvas_group_from = nullptr;
|
|
RendererCanvasRender::Item *canvas_group_from = nullptr;
|
|
@@ -348,14 +361,14 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|
if (!child_items[i]->behind && !use_canvas_group) {
|
|
if (!child_items[i]->behind && !use_canvas_group) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true, p_canvas_cull_mask);
|
|
|
|
|
|
+ _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true, p_canvas_cull_mask, repeat_size, repeat_times);
|
|
}
|
|
}
|
|
_attach_canvas_item_for_draw(ci, p_canvas_clip, r_z_list, r_z_last_list, xform, p_clip_rect, global_rect, modulate, p_z, p_material_owner, use_canvas_group, canvas_group_from);
|
|
_attach_canvas_item_for_draw(ci, p_canvas_clip, r_z_list, r_z_last_list, xform, p_clip_rect, global_rect, modulate, p_z, p_material_owner, use_canvas_group, canvas_group_from);
|
|
for (int i = 0; i < child_item_count; i++) {
|
|
for (int i = 0; i < child_item_count; i++) {
|
|
if (child_items[i]->behind || use_canvas_group) {
|
|
if (child_items[i]->behind || use_canvas_group) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true, p_canvas_cull_mask);
|
|
|
|
|
|
+ _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true, p_canvas_cull_mask, repeat_size, repeat_times);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -374,38 +387,7 @@ void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, co
|
|
int l = p_canvas->child_items.size();
|
|
int l = p_canvas->child_items.size();
|
|
Canvas::ChildItem *ci = p_canvas->child_items.ptrw();
|
|
Canvas::ChildItem *ci = p_canvas->child_items.ptrw();
|
|
|
|
|
|
- bool has_mirror = false;
|
|
|
|
- for (int i = 0; i < l; i++) {
|
|
|
|
- if (ci[i].mirror.x || ci[i].mirror.y) {
|
|
|
|
- has_mirror = true;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!has_mirror) {
|
|
|
|
- _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, canvas_cull_mask, r_render_info);
|
|
|
|
-
|
|
|
|
- } 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_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask, r_render_info);
|
|
|
|
-
|
|
|
|
- //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_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask, r_render_info);
|
|
|
|
- }
|
|
|
|
- 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_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask, r_render_info);
|
|
|
|
- }
|
|
|
|
- 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_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask, r_render_info);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ _render_canvas_item_tree(p_render_target, ci, l, 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, canvas_cull_mask, r_render_info);
|
|
|
|
|
|
RENDER_TIMESTAMP("< Render Canvas");
|
|
RENDER_TIMESTAMP("< Render Canvas");
|
|
}
|
|
}
|
|
@@ -432,6 +414,15 @@ void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, con
|
|
canvas->child_items.write[idx].mirror = p_mirroring;
|
|
canvas->child_items.write[idx].mirror = p_mirroring;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void RendererCanvasCull::canvas_set_item_repeat(RID p_item, const Point2 &p_repeat_size, int p_repeat_times) {
|
|
|
|
+ Item *canvas_item = canvas_item_owner.get_or_null(p_item);
|
|
|
|
+ ERR_FAIL_NULL(canvas_item);
|
|
|
|
+
|
|
|
|
+ canvas_item->repeat_source = true;
|
|
|
|
+ canvas_item->repeat_size = p_repeat_size;
|
|
|
|
+ canvas_item->repeat_times = p_repeat_times;
|
|
|
|
+}
|
|
|
|
+
|
|
void RendererCanvasCull::canvas_set_modulate(RID p_canvas, const Color &p_color) {
|
|
void RendererCanvasCull::canvas_set_modulate(RID p_canvas, const Color &p_color) {
|
|
Canvas *canvas = canvas_owner.get_or_null(p_canvas);
|
|
Canvas *canvas = canvas_owner.get_or_null(p_canvas);
|
|
ERR_FAIL_NULL(canvas);
|
|
ERR_FAIL_NULL(canvas);
|