Skip to content

Commit

Permalink
Merge pull request #52350 from BimDav/viewport_canvas_cull
Browse files Browse the repository at this point in the history
Added Viewport canvas cull mask feature
  • Loading branch information
akien-mga committed Nov 2, 2022
2 parents 06c8e40 + fcb9be6 commit 604abb4
Show file tree
Hide file tree
Showing 14 changed files with 186 additions and 22 deletions.
18 changes: 18 additions & 0 deletions doc/classes/CanvasItem.xml
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,13 @@
Returns this item's transform in relation to the viewport.
</description>
</method>
<method name="get_visibility_layer_bit" qualifiers="const">
<return type="bool" />
<param index="0" name="layer" type="int" />
<description>
Returns an individual bit on the rendering visibility layer.
</description>
</method>
<method name="get_world_2d" qualifiers="const">
<return type="World2D" />
<description>
Expand Down Expand Up @@ -527,6 +534,14 @@
If [param enable] is [code]true[/code], this node will receive [constant NOTIFICATION_TRANSFORM_CHANGED] when its global transform changes.
</description>
</method>
<method name="set_visibility_layer_bit">
<return type="void" />
<param index="0" name="layer" type="int" />
<param index="1" name="enabled" type="bool" />
<description>
Set/clear individual bits on the rendering visibility layer. This simplifies editing this [CanvasItem]'s visibility layer.
</description>
</method>
<method name="show">
<return type="void" />
<description>
Expand Down Expand Up @@ -565,6 +580,9 @@
<member name="use_parent_material" type="bool" setter="set_use_parent_material" getter="get_use_parent_material" default="false">
If [code]true[/code], the parent [CanvasItem]'s [member material] property is used as this one's material.
</member>
<member name="visibility_layer" type="int" setter="set_visibility_layer" getter="get_visibility_layer" default="1">
The rendering layer in which this [CanvasItem] is rendered by [Viewport] nodes. A [Viewport] will render a [CanvasItem] if it and all its parents share a layer with the [Viewport]'s canvas cull mask.
</member>
<member name="visible" type="bool" setter="set_visible" getter="is_visible" default="true">
If [code]true[/code], this [CanvasItem] is drawn. The node is only visible if all of its antecedents are visible as well (in other words, [method is_visible_in_tree] must return [code]true[/code]).
[b]Note:[/b] For controls that inherit [Popup], the correct way to make them visible is to call one of the multiple [code]popup*()[/code] functions instead.
Expand Down
16 changes: 16 additions & 0 deletions doc/classes/RenderingServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,14 @@
Sets if the [CanvasItem] uses its parent's material.
</description>
</method>
<method name="canvas_item_set_visibility_layer">
<return type="void" />
<param index="0" name="item" type="RID" />
<param index="1" name="visibility_layer" type="int" />
<description>
Sets the rendering visibility layer associated with this [CanvasItem]. Only [Viewport] nodes with a matching rendering mask will render this [CanvasItem].
</description>
</method>
<method name="canvas_item_set_visibility_notifier">
<return type="void" />
<param index="0" name="item" type="RID" />
Expand Down Expand Up @@ -3143,6 +3151,14 @@
If [code]true[/code], sets the viewport active, else sets it inactive.
</description>
</method>
<method name="viewport_set_canvas_cull_mask">
<return type="void" />
<param index="0" name="viewport" type="RID" />
<param index="1" name="canvas_cull_mask" type="int" />
<description>
Sets the rendering mask associated with this [Viewport]. Only [CanvasItem] nodes with a matching rendering visibility layer will be rendered by this [Viewport].
</description>
</method>
<method name="viewport_set_canvas_stacking">
<return type="void" />
<param index="0" name="viewport" type="RID" />
Expand Down
18 changes: 18 additions & 0 deletions doc/classes/Viewport.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
Returns the currently active 3D camera.
</description>
</method>
<method name="get_canvas_cull_mask_bit" qualifiers="const">
<return type="bool" />
<param index="0" name="layer" type="int" />
<description>
Returns an individual bit on the rendering layer mask.
</description>
</method>
<method name="get_final_transform" qualifiers="const">
<return type="Transform2D" />
<description>
Expand Down Expand Up @@ -176,6 +183,14 @@
If none of the methods handle the event and [member physics_object_picking] is [code]true[/code], the event is used for physics object picking.
</description>
</method>
<method name="set_canvas_cull_mask_bit">
<return type="void" />
<param index="0" name="layer" type="int" />
<param index="1" name="enable" type="bool" />
<description>
Set/clear individual bits on the rendering layer mask. This simplifies editing this [Viewport]'s layers.
</description>
</method>
<method name="set_input_as_handled">
<return type="void" />
<description>
Expand Down Expand Up @@ -205,6 +220,9 @@
<member name="audio_listener_enable_3d" type="bool" setter="set_as_audio_listener_3d" getter="is_audio_listener_3d" default="false">
If [code]true[/code], the viewport will process 3D audio streams.
</member>
<member name="canvas_cull_mask" type="int" setter="set_canvas_cull_mask" getter="get_canvas_cull_mask" default="4294967295">
The rendering layers in which this [Viewport] renders [CanvasItem] nodes.
</member>
<member name="canvas_item_default_texture_filter" type="int" setter="set_default_canvas_item_texture_filter" getter="get_default_canvas_item_texture_filter" enum="Viewport.DefaultCanvasItemTextureFilter" default="1">
Sets the default filter mode used by [CanvasItem]s in this Viewport. See [enum DefaultCanvasItemTextureFilter] for options.
</member>
Expand Down
31 changes: 31 additions & 0 deletions scene/main/canvas_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ void CanvasItem::_enter_canvas() {
}

RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, canvas);
RenderingServer::get_singleton()->canvas_item_set_visibility_layer(canvas_item, visibility_layer);

canvas_group = "root_canvas" + itos(canvas.get_id());

Expand All @@ -236,6 +237,7 @@ void CanvasItem::_enter_canvas() {
canvas_layer = parent->canvas_layer;
RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, parent->get_canvas_item());
RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index());
RenderingServer::get_singleton()->canvas_item_set_visibility_layer(canvas_item, visibility_layer);
}

pending_update = false;
Expand Down Expand Up @@ -977,6 +979,11 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("make_canvas_position_local", "screen_point"), &CanvasItem::make_canvas_position_local);
ClassDB::bind_method(D_METHOD("make_input_local", "event"), &CanvasItem::make_input_local);

ClassDB::bind_method(D_METHOD("set_visibility_layer", "layer"), &CanvasItem::set_visibility_layer);
ClassDB::bind_method(D_METHOD("get_visibility_layer"), &CanvasItem::get_visibility_layer);
ClassDB::bind_method(D_METHOD("set_visibility_layer_bit", "layer", "enabled"), &CanvasItem::set_visibility_layer_bit);
ClassDB::bind_method(D_METHOD("get_visibility_layer_bit", "layer"), &CanvasItem::get_visibility_layer_bit);

ClassDB::bind_method(D_METHOD("set_texture_filter", "mode"), &CanvasItem::set_texture_filter);
ClassDB::bind_method(D_METHOD("get_texture_filter"), &CanvasItem::get_texture_filter);

Expand All @@ -996,6 +1003,7 @@ void CanvasItem::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level");
ADD_PROPERTY(PropertyInfo(Variant::INT, "clip_children", PROPERTY_HINT_ENUM, "Disabled,Clip Only,Clip + Draw"), "set_clip_children_mode", "get_clip_children_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_light_mask", "get_light_mask");
ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_layer", PROPERTY_HINT_LAYERS_2D_RENDER), "set_visibility_layer", "get_visibility_layer");

ADD_GROUP("Texture", "texture_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Inherit,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter");
Expand Down Expand Up @@ -1094,6 +1102,29 @@ int CanvasItem::get_canvas_layer() const {
}
}

void CanvasItem::set_visibility_layer(uint32_t p_visibility_layer) {
visibility_layer = p_visibility_layer;
RenderingServer::get_singleton()->canvas_item_set_visibility_layer(canvas_item, p_visibility_layer);
}

uint32_t CanvasItem::get_visibility_layer() const {
return visibility_layer;
}

void CanvasItem::set_visibility_layer_bit(uint32_t p_visibility_layer, bool p_enable) {
ERR_FAIL_INDEX(p_visibility_layer, 32);
if (p_enable) {
set_visibility_layer(visibility_layer | (1 << p_visibility_layer));
} else {
set_visibility_layer(visibility_layer & (~(1 << p_visibility_layer)));
}
}

bool CanvasItem::get_visibility_layer_bit(uint32_t p_visibility_layer) const {
ERR_FAIL_INDEX_V(p_visibility_layer, 32, false);
return (visibility_layer & (1 << p_visibility_layer));
}

void CanvasItem::_refresh_texture_filter_cache() {
if (!is_inside_tree()) {
return;
Expand Down
7 changes: 7 additions & 0 deletions scene/main/canvas_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class CanvasItem : public Node {
List<CanvasItem *>::Element *C = nullptr;

int light_mask = 1;
uint32_t visibility_layer = 1;

Window *window = nullptr;
bool visible = true;
Expand Down Expand Up @@ -223,6 +224,12 @@ class CanvasItem : public Node {
void set_self_modulate(const Color &p_self_modulate);
Color get_self_modulate() const;

void set_visibility_layer(uint32_t p_visibility_layer);
uint32_t get_visibility_layer() const;

void set_visibility_layer_bit(uint32_t p_visibility_layer, bool p_enable);
bool get_visibility_layer_bit(uint32_t p_visibility_layer) const;

/* DRAWING API */

void draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = 1.0, real_t p_dash = 2.0);
Expand Down
36 changes: 31 additions & 5 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ void Viewport::_notification(int p_what) {

current_canvas = find_world_2d()->get_canvas();
RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas);
RenderingServer::get_singleton()->viewport_set_canvas_cull_mask(viewport, canvas_cull_mask);
_update_audio_listener_2d();
#ifndef _3D_DISABLED
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
Expand Down Expand Up @@ -993,11 +994,6 @@ void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
return;
}

if (parent && parent->find_world_2d() == p_world_2d) {
WARN_PRINT("Unable to use parent world_2d as world_2d");
return;
}

if (is_inside_tree()) {
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
}
Expand Down Expand Up @@ -3249,6 +3245,29 @@ Transform2D Viewport::get_screen_transform() const {
return _get_input_pre_xform().affine_inverse() * get_final_transform();
}

void Viewport::set_canvas_cull_mask(uint32_t p_canvas_cull_mask) {
canvas_cull_mask = p_canvas_cull_mask;
RenderingServer::get_singleton()->viewport_set_canvas_cull_mask(viewport, canvas_cull_mask);
}

uint32_t Viewport::get_canvas_cull_mask() const {
return canvas_cull_mask;
}

void Viewport::set_canvas_cull_mask_bit(uint32_t p_layer, bool p_enable) {
ERR_FAIL_INDEX(p_layer, 32);
if (p_enable) {
set_canvas_cull_mask(canvas_cull_mask | (1 << p_layer));
} else {
set_canvas_cull_mask(canvas_cull_mask & (~(1 << p_layer)));
}
}

bool Viewport::get_canvas_cull_mask_bit(uint32_t p_layer) const {
ERR_FAIL_INDEX_V(p_layer, 32, false);
return (canvas_cull_mask & (1 << p_layer));
}

#ifndef _3D_DISABLED
AudioListener3D *Viewport::get_audio_listener_3d() const {
return audio_listener_3d;
Expand Down Expand Up @@ -3820,6 +3839,12 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_embedding_subwindows", "enable"), &Viewport::set_embedding_subwindows);
ClassDB::bind_method(D_METHOD("is_embedding_subwindows"), &Viewport::is_embedding_subwindows);

ClassDB::bind_method(D_METHOD("set_canvas_cull_mask", "mask"), &Viewport::set_canvas_cull_mask);
ClassDB::bind_method(D_METHOD("get_canvas_cull_mask"), &Viewport::get_canvas_cull_mask);

ClassDB::bind_method(D_METHOD("set_canvas_cull_mask_bit", "layer", "enable"), &Viewport::set_canvas_cull_mask_bit);
ClassDB::bind_method(D_METHOD("get_canvas_cull_mask_bit", "layer"), &Viewport::get_canvas_cull_mask_bit);

ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_repeat", "mode"), &Viewport::set_default_canvas_item_texture_repeat);
ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_repeat"), &Viewport::get_default_canvas_item_texture_repeat);

Expand Down Expand Up @@ -3925,6 +3950,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::INT, "positional_shadow_atlas_quad_3", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_positional_shadow_atlas_quadrant_subdiv", "get_positional_shadow_atlas_quadrant_subdiv", 3);
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "canvas_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_canvas_transform", "get_canvas_transform");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_canvas_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_canvas_transform", "get_global_canvas_transform");
ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_canvas_cull_mask", "get_canvas_cull_mask");

ADD_SIGNAL(MethodInfo("size_changed"));
ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
Expand Down
8 changes: 8 additions & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ class Viewport : public Node {
SDFOversize sdf_oversize = SDF_OVERSIZE_120_PERCENT;
SDFScale sdf_scale = SDF_SCALE_50_PERCENT;

uint32_t canvas_cull_mask = 0xffffffff; // by default show everything

enum SubWindowDrag {
SUB_WINDOW_DRAG_DISABLED,
SUB_WINDOW_DRAG_MOVE,
Expand Down Expand Up @@ -639,6 +641,12 @@ class Viewport : public Node {

void pass_mouse_focus_to(Viewport *p_viewport, Control *p_control);

void set_canvas_cull_mask(uint32_t p_layers);
uint32_t get_canvas_cull_mask() const;

void set_canvas_cull_mask_bit(uint32_t p_layer, bool p_enable);
bool get_canvas_cull_mask_bit(uint32_t p_layer) const;

virtual Transform2D get_screen_transform() const;

#ifndef _3D_DISABLED
Expand Down
Loading

0 comments on commit 604abb4

Please sign in to comment.