Skip to content

Commit

Permalink
Add inherit_visibility_layer to Parallax2D
Browse files Browse the repository at this point in the history
  • Loading branch information
markdibarry committed Aug 22, 2024
1 parent 826de79 commit 0d1d318
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 11 deletions.
3 changes: 3 additions & 0 deletions doc/classes/Parallax2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,8 @@
Multiplier to the final [Parallax2D]'s offset. Can be used to simulate distance from the camera.
For example, a value of [code]1[/code] scrolls at the same speed as the camera. A value greater than [code]1[/code] scrolls faster, making objects appear closer. Less than [code]1[/code] scrolls slower, making objects appear further, and a value of [code]0[/code] stops the objects completely.
</member>
<member name="inherit_visibility_layer" type="bool" setter="set_inherit_visibility_layer" getter="is_inherit_visibility_layer" default="false">
If [code]true[/code], this node and all descendents will inherit the visibility layers of the [Parallax2D]'s parent.
</member>
</members>
</class>
8 changes: 8 additions & 0 deletions doc/classes/RenderingServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,14 @@
Sets the index for the [CanvasItem].
</description>
</method>
<method name="canvas_item_set_inherit_visibility_layer">
<return type="void" />
<param index="0" name="item" type="RID" />
<param index="1" name="enabled" type="bool" />
<description>
If [param enabled] is [code]true[/code], the given canvas item inherits its parent's visibility layers. Used only for [Parallax2D].
</description>
</method>
<method name="canvas_item_set_interpolated">
<return type="void" />
<param index="0" name="item" type="RID" />
Expand Down
14 changes: 14 additions & 0 deletions scene/2d/parallax_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,17 @@ bool Parallax2D::is_ignore_camera_scroll() {
return ignore_camera_scroll;
}

void Parallax2D::set_inherit_visibility_layer(bool p_enable) {
ERR_THREAD_GUARD;
inherit_visibility_layer = p_enable;
RenderingServer::get_singleton()->canvas_item_set_inherit_visibility_layer(get_canvas_item(), p_enable);
}

bool Parallax2D::is_inherit_visibility_layer() const {
ERR_READ_THREAD_GUARD_V(false);
return inherit_visibility_layer;
}

void Parallax2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_camera_moved", "transform", "screen_offset", "adj_screen_offset"), &Parallax2D::_camera_moved);
ClassDB::bind_method(D_METHOD("set_scroll_scale", "scale"), &Parallax2D::set_scroll_scale);
Expand All @@ -271,6 +282,8 @@ void Parallax2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_follow_viewport"), &Parallax2D::get_follow_viewport);
ClassDB::bind_method(D_METHOD("set_ignore_camera_scroll", "ignore"), &Parallax2D::set_ignore_camera_scroll);
ClassDB::bind_method(D_METHOD("is_ignore_camera_scroll"), &Parallax2D::is_ignore_camera_scroll);
ClassDB::bind_method(D_METHOD("set_inherit_visibility_layer", "enabled"), &Parallax2D::set_inherit_visibility_layer);
ClassDB::bind_method(D_METHOD("is_inherit_visibility_layer"), &Parallax2D::is_inherit_visibility_layer);

ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_scale", PROPERTY_HINT_LINK), "set_scroll_scale", "get_scroll_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_scroll_offset", "get_scroll_offset");
Expand All @@ -288,6 +301,7 @@ void Parallax2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_viewport"), "set_follow_viewport", "get_follow_viewport");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_camera_scroll"), "set_ignore_camera_scroll", "is_ignore_camera_scroll");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "screen_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_screen_offset", "get_screen_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "inherit_visibility_layer"), "set_inherit_visibility_layer", "is_inherit_visibility_layer");
}

Parallax2D::Parallax2D() {
Expand Down
4 changes: 4 additions & 0 deletions scene/2d/parallax_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Parallax2D : public Node2D {
Point2 autoscroll_offset;
bool follow_viewport = true;
bool ignore_camera_scroll = false;
bool inherit_visibility_layer = false;

void _update_process();
void _update_repeat();
Expand Down Expand Up @@ -95,6 +96,9 @@ class Parallax2D : public Node2D {
void set_ignore_camera_scroll(bool p_ignore);
bool is_ignore_camera_scroll();

void set_inherit_visibility_layer(bool p_enable);
bool is_inherit_visibility_layer() const;

Parallax2D();
};

Expand Down
38 changes: 28 additions & 10 deletions servers/rendering/renderer_canvas_cull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas
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, Point2(), 1, nullptr);
_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, Point2(), 1, nullptr, 0xffffffff, false);
}

RendererCanvasRender::Item *list = nullptr;
Expand Down Expand Up @@ -79,11 +79,19 @@ 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 _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, uint32_t p_canvas_cull_mask, uint32_t p_parent_visibility_layer, bool p_inherit_visibility_layer) {
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;

bool inherit_visibility_layer = p_inherit_visibility_layer || p_canvas_item->inherit_visibility_layer;
uint32_t visibility_layer = p_inherit_visibility_layer ? p_parent_visibility_layer : p_canvas_item->visibility_layer;

if (!(visibility_layer & p_canvas_cull_mask)) {
continue;
}

if (child_items[i]->visible) {
if (r_items) {
r_items[r_index] = child_items[i];
Expand Down Expand Up @@ -111,7 +119,7 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, const Tran
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], 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, p_canvas_cull_mask, visibility_layer, inherit_visibility_layer);
}
}
}
Expand Down Expand Up @@ -236,14 +244,17 @@ 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, const Point2 &p_repeat_size, int p_repeat_times, RendererCanvasRender::Item *p_repeat_source_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, const Point2 &p_repeat_size, int p_repeat_times, RendererCanvasRender::Item *p_repeat_source_item, uint32_t p_parent_visibility_layer, bool p_inherit_visibility_layer) {
Item *ci = p_canvas_item;

if (!ci->visible) {
return;
}

if (!(ci->visibility_layer & p_canvas_cull_mask)) {
bool inherit_visibility_layer = p_inherit_visibility_layer || ci->inherit_visibility_layer;
uint32_t visibility_layer = inherit_visibility_layer ? p_parent_visibility_layer : ci->visibility_layer;

if (!(visibility_layer & p_canvas_cull_mask)) {
return;
}

Expand Down Expand Up @@ -358,7 +369,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (p_allow_y_sort) {
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);
_collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), nullptr, ci->ysort_children_count, p_z, p_canvas_cull_mask, visibility_layer, inherit_visibility_layer);
}

child_item_count = ci->ysort_children_count + 1;
Expand All @@ -371,13 +382,13 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
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, Transform2D(), p_material_owner, Color(1, 1, 1, 1), child_items, i, p_z, p_canvas_cull_mask, visibility_layer, inherit_visibility_layer);

SortArray<Item *, ItemPtrSort> 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, child_items[i]->repeat_source_item);
_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, child_items[i]->repeat_source_item, p_parent_visibility_layer, inherit_visibility_layer);
}
} else {
RendererCanvasRender::Item *canvas_group_from = nullptr;
Expand All @@ -401,14 +412,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, repeat_source_item);
_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, repeat_source_item, p_parent_visibility_layer, inherit_visibility_layer);
}
_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, repeat_source_item);
_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, repeat_source_item, p_parent_visibility_layer, inherit_visibility_layer);
}
}
}
Expand Down Expand Up @@ -586,6 +597,13 @@ uint32_t RendererCanvasCull::canvas_item_get_visibility_layer(RID p_item) {
return canvas_item->visibility_layer;
}

void RendererCanvasCull::canvas_item_set_inherit_visibility_layer(RID p_item, bool p_enable) {
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
ERR_FAIL_NULL(canvas_item);

canvas_item->inherit_visibility_layer = p_enable;
}

void RendererCanvasCull::canvas_item_set_clip(RID p_item, bool p_clip) {
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
ERR_FAIL_NULL(canvas_item);
Expand Down
5 changes: 4 additions & 1 deletion servers/rendering/renderer_canvas_cull.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class RendererCanvasCull {
int ysort_index;
int ysort_parent_abs_z_index; // Absolute Z index of parent. Only populated and used when y-sorting.
uint32_t visibility_layer = 0xffffffff;
bool inherit_visibility_layer;

Vector<Item *> child_items;

Expand Down Expand Up @@ -87,6 +88,7 @@ class RendererCanvasCull {
ysort_pos = Vector2();
ysort_index = 0;
ysort_parent_abs_z_index = 0;
inherit_visibility_layer = false;
}
};

Expand Down Expand Up @@ -187,7 +189,7 @@ class RendererCanvasCull {

private:
void _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, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info = nullptr);
void _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, RendererCanvasRender::Item *p_repeat_source_item);
void _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, RendererCanvasRender::Item *p_repeat_source_item, uint32_t p_parent_visibility_layer, bool p_inherit_visibility_layer);

static constexpr int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;

Expand Down Expand Up @@ -218,6 +220,7 @@ class RendererCanvasCull {

void canvas_item_set_visibility_layer(RID p_item, uint32_t p_layer);
uint32_t canvas_item_get_visibility_layer(RID p_item);
void canvas_item_set_inherit_visibility_layer(RID p_item, bool p_enable);

void canvas_item_set_transform(RID p_item, const Transform2D &p_transform);
void canvas_item_set_clip(RID p_item, bool p_clip);
Expand Down
1 change: 1 addition & 0 deletions servers/rendering/rendering_server_default.h
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,7 @@ class RenderingServerDefault : public RenderingServer {

FUNC2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter)
FUNC2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat)
FUNC2(canvas_item_set_inherit_visibility_layer, RID, bool)

FUNC2(canvas_item_set_visible, RID, bool)
FUNC2(canvas_item_set_light_mask, RID, int)
Expand Down
1 change: 1 addition & 0 deletions servers/rendering_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3227,6 +3227,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_set_visible", "item", "visible"), &RenderingServer::canvas_item_set_visible);
ClassDB::bind_method(D_METHOD("canvas_item_set_light_mask", "item", "mask"), &RenderingServer::canvas_item_set_light_mask);
ClassDB::bind_method(D_METHOD("canvas_item_set_visibility_layer", "item", "visibility_layer"), &RenderingServer::canvas_item_set_visibility_layer);
ClassDB::bind_method(D_METHOD("canvas_item_set_inherit_visibility_layer", "item", "enabled"), &RenderingServer::canvas_item_set_inherit_visibility_layer);
ClassDB::bind_method(D_METHOD("canvas_item_set_transform", "item", "transform"), &RenderingServer::canvas_item_set_transform);
ClassDB::bind_method(D_METHOD("canvas_item_set_clip", "item", "clip"), &RenderingServer::canvas_item_set_clip);
ClassDB::bind_method(D_METHOD("canvas_item_set_distance_field_mode", "item", "enabled"), &RenderingServer::canvas_item_set_distance_field_mode);
Expand Down
1 change: 1 addition & 0 deletions servers/rendering_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,7 @@ class RenderingServer : public Object {
virtual void canvas_item_set_modulate(RID p_item, const Color &p_color) = 0;
virtual void canvas_item_set_self_modulate(RID p_item, const Color &p_color) = 0;
virtual void canvas_item_set_visibility_layer(RID p_item, uint32_t p_visibility_layer) = 0;
virtual void canvas_item_set_inherit_visibility_layer(RID p_item, bool p_enable) = 0;

virtual void canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) = 0;

Expand Down

0 comments on commit 0d1d318

Please sign in to comment.