feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -44,14 +44,42 @@
|
|||
// while not making lines appear too soft.
|
||||
const static float FEATHER_SIZE = 1.25f;
|
||||
|
||||
static RendererCanvasCull *_canvas_cull_singleton = nullptr;
|
||||
|
||||
void RendererCanvasCull::_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) {
|
||||
Item *item = (Item *)p_tracker->userdata;
|
||||
|
||||
switch (p_notification) {
|
||||
case Dependency::DEPENDENCY_CHANGED_MATERIAL: {
|
||||
_canvas_cull_singleton->_item_queue_update(item, true);
|
||||
} break;
|
||||
default: {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
|
||||
Item *item = (Item *)p_tracker->userdata;
|
||||
|
||||
if (p_dependency == item->material) {
|
||||
_canvas_cull_singleton->canvas_item_set_material(item->self, RID());
|
||||
}
|
||||
_canvas_cull_singleton->_item_queue_update(item, true);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
// This is used to avoid passing the camera transform down the rendering
|
||||
// function calls, as it won't be used in 99% of cases, because the camera
|
||||
// transform is normally concatenated with the item global transform.
|
||||
_current_camera_transform = p_transform;
|
||||
|
||||
memset(z_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++) {
|
||||
_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);
|
||||
_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, false, p_canvas_cull_mask, Point2(), 1, nullptr);
|
||||
}
|
||||
|
||||
RendererCanvasRender::Item *list = nullptr;
|
||||
|
|
@ -79,44 +107,71 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas
|
|||
}
|
||||
}
|
||||
|
||||
void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, const Transform2D &p_transform, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int p_z) {
|
||||
void RendererCanvasCull::_collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int p_z) {
|
||||
int child_item_count = p_canvas_item->child_items.size();
|
||||
RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw();
|
||||
for (int i = 0; i < child_item_count; i++) {
|
||||
int abs_z = 0;
|
||||
if (child_items[i]->visible) {
|
||||
if (r_items) {
|
||||
r_items[r_index] = child_items[i];
|
||||
child_items[i]->ysort_xform = p_transform;
|
||||
child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform_curr.columns[2]);
|
||||
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr;
|
||||
child_items[i]->ysort_modulate = p_modulate;
|
||||
child_items[i]->ysort_index = r_index;
|
||||
child_items[i]->ysort_parent_abs_z_index = p_z;
|
||||
// To y-sort according to the item's final position, physics interpolation
|
||||
// and transform snapping need to be applied before y-sorting.
|
||||
Transform2D child_xform;
|
||||
if (!_interpolation_data.interpolation_enabled || !child_items[i]->interpolated) {
|
||||
child_xform = child_items[i]->xform_curr;
|
||||
} else {
|
||||
real_t f = Engine::get_singleton()->get_physics_interpolation_fraction();
|
||||
TransformInterpolator::interpolate_transform_2d(child_items[i]->xform_prev, child_items[i]->xform_curr, child_xform, f);
|
||||
}
|
||||
|
||||
if (!child_items[i]->repeat_source) {
|
||||
child_items[i]->repeat_size = p_canvas_item->repeat_size;
|
||||
child_items[i]->repeat_times = p_canvas_item->repeat_times;
|
||||
}
|
||||
if (snapping_2d_transforms_to_pixel) {
|
||||
child_xform.columns[2] = (child_xform.columns[2] + Point2(0.5, 0.5)).floor();
|
||||
}
|
||||
|
||||
// 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_items[r_index] = child_items[i];
|
||||
child_items[i]->ysort_xform = p_canvas_item->ysort_xform * child_xform;
|
||||
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr;
|
||||
child_items[i]->ysort_modulate = p_modulate;
|
||||
child_items[i]->ysort_index = r_index;
|
||||
child_items[i]->ysort_parent_abs_z_index = p_z;
|
||||
|
||||
if (!child_items[i]->repeat_source) {
|
||||
child_items[i]->repeat_size = p_canvas_item->repeat_size;
|
||||
child_items[i]->repeat_times = p_canvas_item->repeat_times;
|
||||
child_items[i]->repeat_source_item = p_canvas_item->repeat_source_item;
|
||||
}
|
||||
|
||||
// Y sorted canvas items are flattened into r_items. Calculate their absolute z index to use when rendering r_items.
|
||||
int abs_z = 0;
|
||||
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++;
|
||||
|
||||
if (child_items[i]->sort_y) {
|
||||
_collect_ysort_children(child_items[i], p_transform * child_items[i]->xform_curr, child_items[i]->use_parent_material ? p_material_owner : child_items[i], p_modulate * child_items[i]->modulate, r_items, r_index, abs_z);
|
||||
_collect_ysort_children(child_items[i], child_items[i]->use_parent_material ? p_material_owner : child_items[i], p_modulate * child_items[i]->modulate, r_items, r_index, abs_z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_Owner<RendererCanvasCull::Item, true> &canvas_item_owner) {
|
||||
int RendererCanvasCull::_count_ysort_children(RendererCanvasCull::Item *p_canvas_item) {
|
||||
int ysort_children_count = 0;
|
||||
int child_item_count = p_canvas_item->child_items.size();
|
||||
RendererCanvasCull::Item *const *child_items = p_canvas_item->child_items.ptr();
|
||||
for (int i = 0; i < child_item_count; i++) {
|
||||
if (child_items[i]->visible) {
|
||||
ysort_children_count++;
|
||||
if (child_items[i]->sort_y) {
|
||||
ysort_children_count += _count_ysort_children(child_items[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ysort_children_count;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner) {
|
||||
do {
|
||||
ysort_owner->ysort_children_count = -1;
|
||||
ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.get_or_null(ysort_owner->parent) : nullptr;
|
||||
|
|
@ -192,14 +247,14 @@ void RendererCanvasCull::_attach_canvas_item_for_draw(RendererCanvasCull::Item *
|
|||
}
|
||||
|
||||
if (((ci->commands != nullptr || ci->visibility_notifier) && p_clip_rect.intersects(p_global_rect, true)) || ci->vp_render || ci->copy_back_buffer) {
|
||||
//something to draw?
|
||||
// Something to draw?
|
||||
|
||||
if (ci->update_when_visible) {
|
||||
RenderingServerDefault::redraw_request();
|
||||
}
|
||||
|
||||
if (ci->commands != nullptr || ci->copy_back_buffer) {
|
||||
ci->final_transform = p_transform;
|
||||
ci->final_transform = !ci->use_identity_transform ? p_transform : _current_camera_transform;
|
||||
ci->final_modulate = p_modulate * ci->self_modulate;
|
||||
ci->global_rect_cache = p_global_rect;
|
||||
ci->global_rect_cache.position -= p_clip_rect.position;
|
||||
|
|
@ -229,10 +284,13 @@ void RendererCanvasCull::_attach_canvas_item_for_draw(RendererCanvasCull::Item *
|
|||
|
||||
ci->visibility_notifier->visible_in_frame = RSG::rasterizer->get_frame_number();
|
||||
}
|
||||
} else if (ci->repeat_source) {
|
||||
// If repeat source does not draw itself it still needs transform updated as its child items' repeat offsets are relative to it.
|
||||
ci->final_transform = p_transform;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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_is_already_y_sorted, uint32_t p_canvas_cull_mask, const Point2 &p_repeat_size, int p_repeat_times, RendererCanvasRender::Item *p_repeat_source_item) {
|
||||
Item *ci = p_canvas_item;
|
||||
|
||||
if (!ci->visible) {
|
||||
|
|
@ -248,6 +306,19 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|||
ci->children_order_dirty = false;
|
||||
}
|
||||
|
||||
if (ci->use_parent_material && p_material_owner) {
|
||||
ci->material_owner = p_material_owner;
|
||||
} else {
|
||||
p_material_owner = ci;
|
||||
ci->material_owner = nullptr;
|
||||
}
|
||||
|
||||
Color modulate = ci->modulate * p_modulate;
|
||||
|
||||
if (modulate.a < 0.007) {
|
||||
return;
|
||||
}
|
||||
|
||||
Rect2 rect = ci->get_rect();
|
||||
|
||||
if (ci->visibility_notifier) {
|
||||
|
|
@ -256,55 +327,74 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|||
}
|
||||
}
|
||||
|
||||
// Always calculate final transform as if not using identity xform.
|
||||
// This is so the expected transform is passed to children.
|
||||
// However, if use_identity_xform is set,
|
||||
// we can override the transform for rendering purposes for this item only.
|
||||
Transform2D self_xform;
|
||||
Transform2D final_xform;
|
||||
if (!_interpolation_data.interpolation_enabled || !ci->interpolated) {
|
||||
final_xform = ci->xform_curr;
|
||||
if (p_is_already_y_sorted) {
|
||||
// Y-sorted item's final transform is calculated before y-sorting,
|
||||
// and is passed as `p_parent_xform` afterwards. No need to recalculate.
|
||||
final_xform = p_parent_xform;
|
||||
} else {
|
||||
real_t f = Engine::get_singleton()->get_physics_interpolation_fraction();
|
||||
TransformInterpolator::interpolate_transform_2d(ci->xform_prev, ci->xform_curr, final_xform, f);
|
||||
}
|
||||
if (!_interpolation_data.interpolation_enabled || !ci->interpolated) {
|
||||
self_xform = ci->xform_curr;
|
||||
} else {
|
||||
real_t f = Engine::get_singleton()->get_physics_interpolation_fraction();
|
||||
TransformInterpolator::interpolate_transform_2d(ci->xform_prev, ci->xform_curr, self_xform, f);
|
||||
}
|
||||
|
||||
Transform2D parent_xform = p_parent_xform;
|
||||
Transform2D parent_xform = p_parent_xform;
|
||||
|
||||
if (snapping_2d_transforms_to_pixel) {
|
||||
self_xform.columns[2] = (self_xform.columns[2] + Point2(0.5, 0.5)).floor();
|
||||
parent_xform.columns[2] = (parent_xform.columns[2] + Point2(0.5, 0.5)).floor();
|
||||
}
|
||||
|
||||
final_xform = parent_xform * self_xform;
|
||||
}
|
||||
|
||||
Point2 repeat_size = p_repeat_size;
|
||||
int repeat_times = p_repeat_times;
|
||||
RendererCanvasRender::Item *repeat_source_item = p_repeat_source_item;
|
||||
|
||||
if (ci->repeat_source) {
|
||||
repeat_size = ci->repeat_size;
|
||||
repeat_times = ci->repeat_times;
|
||||
repeat_source_item = ci;
|
||||
} else {
|
||||
ci->repeat_size = repeat_size;
|
||||
ci->repeat_times = repeat_times;
|
||||
ci->repeat_source_item = repeat_source_item;
|
||||
}
|
||||
|
||||
if (repeat_size.x || repeat_size.y) {
|
||||
Size2 scale = final_xform.get_scale();
|
||||
rect.size += repeat_size * repeat_times / scale;
|
||||
rect.position -= repeat_size / scale * (repeat_times / 2);
|
||||
}
|
||||
|
||||
if (snapping_2d_transforms_to_pixel) {
|
||||
final_xform.columns[2] = (final_xform.columns[2] + Point2(0.5, 0.5)).floor();
|
||||
parent_xform.columns[2] = (parent_xform.columns[2] + Point2(0.5, 0.5)).floor();
|
||||
}
|
||||
|
||||
final_xform = parent_xform * final_xform;
|
||||
|
||||
Rect2 global_rect = final_xform.xform(rect);
|
||||
global_rect.position += p_clip_rect.position;
|
||||
|
||||
if (ci->use_parent_material && p_material_owner) {
|
||||
ci->material_owner = p_material_owner;
|
||||
Rect2 global_rect;
|
||||
if (!p_canvas_item->use_identity_transform) {
|
||||
global_rect = final_xform.xform(rect);
|
||||
} else {
|
||||
p_material_owner = ci;
|
||||
ci->material_owner = nullptr;
|
||||
global_rect = _current_camera_transform.xform(rect);
|
||||
}
|
||||
if (repeat_source_item && (repeat_size.x || repeat_size.y)) {
|
||||
// Top-left repeated rect.
|
||||
Rect2 corner_rect = global_rect;
|
||||
corner_rect.position -= repeat_source_item->final_transform.basis_xform((repeat_times / 2) * repeat_size);
|
||||
global_rect = corner_rect;
|
||||
|
||||
Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a);
|
||||
// Plus top-right repeated rect.
|
||||
Size2 size_x_offset = repeat_source_item->final_transform.basis_xform(repeat_times * Size2(repeat_size.x, 0));
|
||||
corner_rect.position += size_x_offset;
|
||||
global_rect = global_rect.merge(corner_rect);
|
||||
|
||||
if (modulate.a < 0.007) {
|
||||
return;
|
||||
// Plus bottom-right repeated rect.
|
||||
corner_rect.position += repeat_source_item->final_transform.basis_xform(repeat_times * Size2(0, repeat_size.y));
|
||||
global_rect = global_rect.merge(corner_rect);
|
||||
|
||||
// Plus bottom-left repeated rect.
|
||||
corner_rect.position -= size_x_offset;
|
||||
global_rect = global_rect.merge(corner_rect);
|
||||
}
|
||||
global_rect.position += p_clip_rect.position;
|
||||
|
||||
int child_item_count = ci->child_items.size();
|
||||
Item **child_items = ci->child_items.ptrw();
|
||||
|
|
@ -335,29 +425,27 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|||
}
|
||||
|
||||
if (ci->sort_y) {
|
||||
if (p_allow_y_sort) {
|
||||
if (!p_is_already_y_sorted) {
|
||||
if (ci->ysort_children_count == -1) {
|
||||
ci->ysort_children_count = 0;
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), nullptr, ci->ysort_children_count, p_z);
|
||||
ci->ysort_children_count = _count_ysort_children(ci);
|
||||
}
|
||||
|
||||
child_item_count = ci->ysort_children_count + 1;
|
||||
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
|
||||
|
||||
ci->ysort_xform = ci->xform_curr.affine_inverse();
|
||||
ci->ysort_pos = Vector2();
|
||||
ci->ysort_modulate = Color(1, 1, 1, 1);
|
||||
ci->ysort_xform = Transform2D();
|
||||
ci->ysort_modulate = Color(1, 1, 1, 1) / ci->modulate;
|
||||
ci->ysort_index = 0;
|
||||
ci->ysort_parent_abs_z_index = parent_z;
|
||||
child_items[0] = ci;
|
||||
int i = 1;
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), child_items, i, p_z);
|
||||
_collect_ysort_children(ci, p_material_owner, Color(1, 1, 1, 1), child_items, i, p_z);
|
||||
|
||||
SortArray<Item *, ItemPtrSort> sorter;
|
||||
SortArray<Item *, ItemYSort> sorter;
|
||||
sorter.sort(child_items, child_item_count);
|
||||
|
||||
for (i = 0; i < child_item_count; i++) {
|
||||
_cull_canvas_item(child_items[i], final_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, child_items[i]->repeat_size, child_items[i]->repeat_times);
|
||||
_cull_canvas_item(child_items[i], final_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, true, p_canvas_cull_mask, child_items[i]->repeat_size, child_items[i]->repeat_times, child_items[i]->repeat_source_item);
|
||||
}
|
||||
} else {
|
||||
RendererCanvasRender::Item *canvas_group_from = nullptr;
|
||||
|
|
@ -381,14 +469,14 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|||
if (!child_items[i]->behind && !use_canvas_group) {
|
||||
continue;
|
||||
}
|
||||
_cull_canvas_item(child_items[i], final_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);
|
||||
_cull_canvas_item(child_items[i], final_xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, false, p_canvas_cull_mask, repeat_size, repeat_times, repeat_source_item);
|
||||
}
|
||||
_attach_canvas_item_for_draw(ci, p_canvas_clip, r_z_list, r_z_last_list, final_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++) {
|
||||
if (child_items[i]->behind || use_canvas_group) {
|
||||
continue;
|
||||
}
|
||||
_cull_canvas_item(child_items[i], final_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);
|
||||
_cull_canvas_item(child_items[i], final_xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, false, p_canvas_cull_mask, repeat_size, repeat_times, repeat_source_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -431,14 +519,22 @@ void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, con
|
|||
|
||||
int idx = canvas->find_item(canvas_item);
|
||||
ERR_FAIL_COND(idx == -1);
|
||||
canvas->child_items.write[idx].mirror = p_mirroring;
|
||||
|
||||
bool is_repeat_source = (p_mirroring.x || p_mirroring.y);
|
||||
canvas_item->repeat_source = is_repeat_source;
|
||||
canvas_item->repeat_source_item = is_repeat_source ? canvas_item : nullptr;
|
||||
canvas_item->repeat_size = p_mirroring;
|
||||
canvas_item->repeat_times = 1;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_set_item_repeat(RID p_item, const Point2 &p_repeat_size, int p_repeat_times) {
|
||||
ERR_FAIL_COND(p_repeat_times < 0);
|
||||
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL(canvas_item);
|
||||
|
||||
canvas_item->repeat_source = true;
|
||||
bool is_repeat_source = (p_repeat_size.x || p_repeat_size.y) && p_repeat_times;
|
||||
canvas_item->repeat_source = is_repeat_source;
|
||||
canvas_item->repeat_source_item = is_repeat_source ? canvas_item : nullptr;
|
||||
canvas_item->repeat_size = p_repeat_size;
|
||||
canvas_item->repeat_times = p_repeat_times;
|
||||
}
|
||||
|
|
@ -466,6 +562,8 @@ RID RendererCanvasCull::canvas_item_allocate() {
|
|||
}
|
||||
void RendererCanvasCull::canvas_item_initialize(RID p_rid) {
|
||||
canvas_item_owner.initialize_rid(p_rid);
|
||||
Item *instance = canvas_item_owner.get_or_null(p_rid);
|
||||
instance->self = p_rid;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) {
|
||||
|
|
@ -481,7 +579,7 @@ void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) {
|
|||
item_owner->child_items.erase(canvas_item);
|
||||
|
||||
if (item_owner->sort_y) {
|
||||
_mark_ysort_dirty(item_owner, canvas_item_owner);
|
||||
_mark_ysort_dirty(item_owner);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -501,7 +599,7 @@ void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) {
|
|||
item_owner->children_order_dirty = true;
|
||||
|
||||
if (item_owner->sort_y) {
|
||||
_mark_ysort_dirty(item_owner, canvas_item_owner);
|
||||
_mark_ysort_dirty(item_owner);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -518,7 +616,7 @@ void RendererCanvasCull::canvas_item_set_visible(RID p_item, bool p_visible) {
|
|||
|
||||
canvas_item->visible = p_visible;
|
||||
|
||||
_mark_ysort_dirty(canvas_item, canvas_item_owner);
|
||||
_mark_ysort_dirty(canvas_item);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_light_mask(RID p_item, int p_mask) {
|
||||
|
|
@ -553,8 +651,9 @@ void RendererCanvasCull::canvas_item_set_visibility_layer(RID p_item, uint32_t p
|
|||
|
||||
uint32_t RendererCanvasCull::canvas_item_get_visibility_layer(RID p_item) {
|
||||
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
|
||||
if (!canvas_item)
|
||||
if (!canvas_item) {
|
||||
return 0;
|
||||
}
|
||||
return canvas_item->visibility_layer;
|
||||
}
|
||||
|
||||
|
|
@ -601,6 +700,13 @@ void RendererCanvasCull::canvas_item_set_draw_behind_parent(RID p_item, bool p_e
|
|||
canvas_item->behind = p_enable;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_use_identity_transform(RID p_item, bool p_enable) {
|
||||
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL(canvas_item);
|
||||
|
||||
canvas_item->use_identity_transform = p_enable;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_update_when_visible(RID p_item, bool p_update) {
|
||||
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL(canvas_item);
|
||||
|
|
@ -1714,7 +1820,7 @@ void RendererCanvasCull::canvas_item_set_sort_children_by_y(RID p_item, bool p_e
|
|||
|
||||
canvas_item->sort_y = p_enable;
|
||||
|
||||
_mark_ysort_dirty(canvas_item, canvas_item_owner);
|
||||
_mark_ysort_dirty(canvas_item);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_z_index(RID p_item, int p_z) {
|
||||
|
|
@ -1784,6 +1890,7 @@ void RendererCanvasCull::canvas_item_clear(RID p_item) {
|
|||
ERR_FAIL_NULL(canvas_item);
|
||||
|
||||
canvas_item->clear();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (debug_redraw) {
|
||||
canvas_item->debug_redraw_time = debug_redraw_time;
|
||||
|
|
@ -1815,6 +1922,7 @@ void RendererCanvasCull::canvas_item_set_material(RID p_item, RID p_material) {
|
|||
ERR_FAIL_NULL(canvas_item);
|
||||
|
||||
canvas_item->material = p_material;
|
||||
_item_queue_update(canvas_item, true);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_use_parent_material(RID p_item, bool p_enable) {
|
||||
|
|
@ -1822,6 +1930,37 @@ void RendererCanvasCull::canvas_item_set_use_parent_material(RID p_item, bool p_
|
|||
ERR_FAIL_NULL(canvas_item);
|
||||
|
||||
canvas_item->use_parent_material = p_enable;
|
||||
_item_queue_update(canvas_item, true);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_instance_shader_parameter(RID p_item, const StringName &p_parameter, const Variant &p_value) {
|
||||
Item *item = canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL(item);
|
||||
|
||||
item->instance_uniforms.set(item->self, p_parameter, p_value);
|
||||
}
|
||||
|
||||
Variant RendererCanvasCull::canvas_item_get_instance_shader_parameter(RID p_item, const StringName &p_parameter) const {
|
||||
const Item *item = const_cast<RendererCanvasCull *>(this)->canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL_V(item, Variant());
|
||||
|
||||
return item->instance_uniforms.get(p_parameter);
|
||||
}
|
||||
|
||||
Variant RendererCanvasCull::canvas_item_get_instance_shader_parameter_default_value(RID p_item, const StringName &p_parameter) const {
|
||||
const Item *item = const_cast<RendererCanvasCull *>(this)->canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL_V(item, Variant());
|
||||
|
||||
return item->instance_uniforms.get_default(p_parameter);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_get_instance_shader_parameter_list(RID p_item, List<PropertyInfo> *p_parameters) const {
|
||||
ERR_FAIL_NULL(p_parameters);
|
||||
const Item *item = const_cast<RendererCanvasCull *>(this)->canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL(item);
|
||||
const_cast<RendererCanvasCull *>(this)->update_dirty_items();
|
||||
|
||||
item->instance_uniforms.get_property_list(*p_parameters);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_visibility_notifier(RID p_item, bool p_enable, const Rect2 &p_area, const Callable &p_enter_callable, const Callable &p_exit_callable) {
|
||||
|
|
@ -2351,6 +2490,63 @@ Rect2 RendererCanvasCull::_debug_canvas_item_get_rect(RID p_item) {
|
|||
return canvas_item->get_rect();
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_item_queue_update(Item *p_item, bool p_update_dependencies) {
|
||||
if (p_update_dependencies) {
|
||||
p_item->update_dependencies = true;
|
||||
}
|
||||
|
||||
if (!p_item->update_item.in_list()) {
|
||||
_item_update_list.add(&p_item->update_item);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererCanvasCull::update_dirty_items() {
|
||||
while (_item_update_list.first()) {
|
||||
_update_dirty_item(_item_update_list.first()->self());
|
||||
}
|
||||
|
||||
// Instance updates may affect resources.
|
||||
RSG::utilities->update_dirty_resources();
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_update_dirty_item(Item *p_item) {
|
||||
if (p_item->update_dependencies) {
|
||||
RID material = p_item->material;
|
||||
|
||||
if (p_item->use_parent_material) {
|
||||
Item *parent = canvas_item_owner.get_or_null(p_item->parent);
|
||||
while (parent != nullptr) {
|
||||
material = parent->material;
|
||||
if (!parent->use_parent_material) {
|
||||
break;
|
||||
}
|
||||
parent = canvas_item_owner.get_or_null(parent->parent);
|
||||
}
|
||||
}
|
||||
|
||||
p_item->dependency_tracker.update_begin();
|
||||
|
||||
p_item->instance_uniforms.materials_start();
|
||||
|
||||
if (material.is_valid()) {
|
||||
p_item->instance_uniforms.materials_append(material);
|
||||
RSG::material_storage->material_update_dependency(material, &p_item->dependency_tracker);
|
||||
}
|
||||
|
||||
if (p_item->instance_uniforms.materials_finish(p_item->self)) {
|
||||
p_item->instance_allocated_shader_uniforms_offset = p_item->instance_uniforms.location();
|
||||
}
|
||||
|
||||
p_item->dependency_tracker.update_end();
|
||||
}
|
||||
_item_update_list.remove(&p_item->update_item);
|
||||
p_item->update_dependencies = false;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::update() {
|
||||
update_dirty_items();
|
||||
}
|
||||
|
||||
bool RendererCanvasCull::free(RID p_rid) {
|
||||
if (canvas_owner.owns(p_rid)) {
|
||||
Canvas *canvas = canvas_owner.get_or_null(p_rid);
|
||||
|
|
@ -2395,7 +2591,7 @@ bool RendererCanvasCull::free(RID p_rid) {
|
|||
item_owner->child_items.erase(canvas_item);
|
||||
|
||||
if (item_owner->sort_y) {
|
||||
_mark_ysort_dirty(item_owner, canvas_item_owner);
|
||||
_mark_ysort_dirty(item_owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2408,11 +2604,9 @@ bool RendererCanvasCull::free(RID p_rid) {
|
|||
visibility_notifier_allocator.free(canvas_item->visibility_notifier);
|
||||
}
|
||||
|
||||
/*
|
||||
if (canvas_item->material) {
|
||||
canvas_item->material->owners.erase(canvas_item);
|
||||
}
|
||||
*/
|
||||
canvas_item_set_material(canvas_item->self, RID());
|
||||
update_dirty_items();
|
||||
canvas_item->instance_uniforms.free(canvas_item->self);
|
||||
|
||||
if (canvas_item->canvas_group != nullptr) {
|
||||
memdelete(canvas_item->canvas_group);
|
||||
|
|
@ -2574,16 +2768,19 @@ void RendererCanvasCull::InterpolationData::notify_free_canvas_light_occluder(RI
|
|||
}
|
||||
|
||||
RendererCanvasCull::RendererCanvasCull() {
|
||||
_canvas_cull_singleton = this;
|
||||
|
||||
z_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *));
|
||||
z_last_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *));
|
||||
|
||||
disable_scale = false;
|
||||
|
||||
debug_redraw_time = GLOBAL_DEF("debug/canvas_items/debug_redraw_time", 1.0);
|
||||
debug_redraw_color = GLOBAL_DEF("debug/canvas_items/debug_redraw_color", Color(1.0, 0.2, 0.2, 0.5));
|
||||
debug_redraw_time = GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "debug/canvas_items/debug_redraw_time", PROPERTY_HINT_RANGE, "0.1,2,0.001,or_greater"), 1.0);
|
||||
debug_redraw_color = GLOBAL_DEF(PropertyInfo(Variant::COLOR, "debug/canvas_items/debug_redraw_color"), Color(1.0, 0.2, 0.2, 0.5));
|
||||
}
|
||||
|
||||
RendererCanvasCull::~RendererCanvasCull() {
|
||||
memfree(z_list);
|
||||
memfree(z_last_list);
|
||||
_canvas_cull_singleton = nullptr;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue