|
@@ -76,10 +76,11 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, RendererCanvasCull::Item **r_items, int &r_index) {
|
|
|
|
|
|
+void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, RendererCanvasCull::Item **r_items, int &r_index, int p_z) {
|
|
int child_item_count = p_canvas_item->child_items.size();
|
|
int child_item_count = p_canvas_item->child_items.size();
|
|
RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw();
|
|
RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw();
|
|
for (int i = 0; i < child_item_count; i++) {
|
|
for (int i = 0; i < child_item_count; i++) {
|
|
|
|
+ int abs_z = 0;
|
|
if (child_items[i]->visible) {
|
|
if (child_items[i]->visible) {
|
|
if (r_items) {
|
|
if (r_items) {
|
|
r_items[r_index] = child_items[i];
|
|
r_items[r_index] = child_items[i];
|
|
@@ -87,12 +88,20 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2
|
|
child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.columns[2]);
|
|
child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.columns[2]);
|
|
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr;
|
|
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr;
|
|
child_items[i]->ysort_index = r_index;
|
|
child_items[i]->ysort_index = r_index;
|
|
|
|
+ child_items[i]->ysort_parent_abs_z_index = p_z;
|
|
|
|
+
|
|
|
|
+ // Y sorted canvas items are flattened into r_items. Calculate their absolute z index to use when rendering r_items.
|
|
|
|
+ if (child_items[i]->z_relative) {
|
|
|
|
+ abs_z = CLAMP(p_z + child_items[i]->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
|
|
|
|
+ } else {
|
|
|
|
+ abs_z = child_items[i]->z_index;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
r_index++;
|
|
r_index++;
|
|
|
|
|
|
if (child_items[i]->sort_y) {
|
|
if (child_items[i]->sort_y) {
|
|
- _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index);
|
|
|
|
|
|
+ _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index, abs_z);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -277,6 +286,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|
ci->final_clip_owner = p_canvas_clip;
|
|
ci->final_clip_owner = p_canvas_clip;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ int parent_z = p_z;
|
|
if (ci->z_relative) {
|
|
if (ci->z_relative) {
|
|
p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
|
|
p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
|
|
} else {
|
|
} else {
|
|
@@ -287,22 +297,23 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|
if (allow_y_sort) {
|
|
if (allow_y_sort) {
|
|
if (ci->ysort_children_count == -1) {
|
|
if (ci->ysort_children_count == -1) {
|
|
ci->ysort_children_count = 0;
|
|
ci->ysort_children_count = 0;
|
|
- _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count);
|
|
|
|
|
|
+ _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count, p_z);
|
|
}
|
|
}
|
|
|
|
|
|
child_item_count = ci->ysort_children_count + 1;
|
|
child_item_count = ci->ysort_children_count + 1;
|
|
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
|
|
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
|
|
|
|
|
|
|
|
+ ci->ysort_parent_abs_z_index = parent_z;
|
|
child_items[0] = ci;
|
|
child_items[0] = ci;
|
|
int i = 1;
|
|
int i = 1;
|
|
- _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i);
|
|
|
|
|
|
+ _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i, p_z);
|
|
ci->ysort_xform = ci->xform.affine_inverse();
|
|
ci->ysort_xform = ci->xform.affine_inverse();
|
|
|
|
|
|
SortArray<Item *, ItemPtrSort> sorter;
|
|
SortArray<Item *, ItemPtrSort> sorter;
|
|
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, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false);
|
|
|
|
|
|
+ _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, child_items[i]->ysort_parent_abs_z_index, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
RendererCanvasRender::Item *canvas_group_from = nullptr;
|
|
RendererCanvasRender::Item *canvas_group_from = nullptr;
|