Viewport canvas cull mask feature
Co-authored-by: Valentin Zagura <puthre@gmail.com>
This commit is contained in:
parent
11e1bac768
commit
fcb9be66a2
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
|
|
@ -498,6 +498,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" />
|
||||
|
@ -3142,6 +3150,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" />
|
||||
|
|
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
|
|
@ -222,6 +222,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());
|
||||
|
||||
|
@ -239,6 +240,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;
|
||||
|
@ -980,6 +982,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);
|
||||
|
||||
|
@ -999,6 +1006,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");
|
||||
|
@ -1097,6 +1105,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;
|
||||
|
|
|
@ -89,6 +89,7 @@ private:
|
|||
List<CanvasItem *>::Element *C = nullptr;
|
||||
|
||||
int light_mask = 1;
|
||||
uint32_t visibility_layer = 1;
|
||||
|
||||
Window *window = nullptr;
|
||||
bool visible = true;
|
||||
|
@ -223,6 +224,12 @@ public:
|
|||
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);
|
||||
|
|
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -3244,6 +3240,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;
|
||||
|
@ -3815,6 +3834,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);
|
||||
|
||||
|
@ -3920,6 +3945,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")));
|
||||
|
|
|
@ -317,6 +317,8 @@ private:
|
|||
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,
|
||||
|
@ -639,6 +641,12 @@ public:
|
|||
|
||||
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
|
||||
|
|
|
@ -38,17 +38,17 @@
|
|||
|
||||
static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
|
||||
|
||||
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) {
|
||||
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 canvas_cull_mask) {
|
||||
RENDER_TIMESTAMP("Cull CanvasItem Tree");
|
||||
|
||||
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);
|
||||
_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, 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);
|
||||
_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, canvas_cull_mask);
|
||||
}
|
||||
|
||||
RendererCanvasRender::Item *list = nullptr;
|
||||
|
@ -223,13 +223,17 @@ void RendererCanvasCull::_attach_canvas_item_for_draw(RendererCanvasCull::Item *
|
|||
}
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, 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 allow_y_sort) {
|
||||
void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, 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 allow_y_sort, uint32_t canvas_cull_mask) {
|
||||
Item *ci = p_canvas_item;
|
||||
|
||||
if (!ci->visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(ci->visibility_layer & canvas_cull_mask)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ci->children_order_dirty) {
|
||||
ci->child_items.sort_custom<ItemIndexSort>();
|
||||
ci->children_order_dirty = false;
|
||||
|
@ -313,7 +317,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|||
sorter.sort(child_items, child_item_count);
|
||||
|
||||
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_parent_abs_z_index, r_z_list, r_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, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false, canvas_cull_mask);
|
||||
}
|
||||
} else {
|
||||
RendererCanvasRender::Item *canvas_group_from = nullptr;
|
||||
|
@ -337,19 +341,19 @@ 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], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true);
|
||||
_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, canvas_cull_mask);
|
||||
}
|
||||
_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, xform);
|
||||
for (int i = 0; i < child_item_count; i++) {
|
||||
if (child_items[i]->behind || use_canvas_group) {
|
||||
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);
|
||||
_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, canvas_cull_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) {
|
||||
void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask) {
|
||||
RENDER_TIMESTAMP("> Render Canvas");
|
||||
|
||||
sdf_used = false;
|
||||
|
@ -372,26 +376,26 @@ void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, co
|
|||
}
|
||||
|
||||
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);
|
||||
_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);
|
||||
|
||||
} 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);
|
||||
_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);
|
||||
|
||||
//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);
|
||||
_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);
|
||||
}
|
||||
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);
|
||||
_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);
|
||||
}
|
||||
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);
|
||||
_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -513,6 +517,20 @@ void RendererCanvasCull::canvas_item_set_transform(RID p_item, const Transform2D
|
|||
canvas_item->xform = p_transform;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_visibility_layer(RID p_item, uint32_t p_visibility_layer) {
|
||||
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
canvas_item->visibility_layer = p_visibility_layer;
|
||||
}
|
||||
|
||||
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)
|
||||
return 0;
|
||||
return canvas_item->visibility_layer;
|
||||
}
|
||||
|
||||
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_COND(!canvas_item);
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
Vector2 ysort_pos;
|
||||
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;
|
||||
|
||||
Vector<Item *> child_items;
|
||||
|
||||
|
@ -179,14 +180,14 @@ public:
|
|||
_FORCE_INLINE_ void _attach_canvas_item_for_draw(Item *ci, Item *p_canvas_clip, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, const Transform2D &xform, const Rect2 &p_clip_rect, Rect2 global_rect, const Color &modulate, int p_z, RendererCanvasCull::Item *p_material_owner, bool p_use_canvas_group, RendererCanvasRender::Item *canvas_group_from, const Transform2D &p_xform);
|
||||
|
||||
private:
|
||||
void _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, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel);
|
||||
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, 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 allow_y_sort);
|
||||
void _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, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask);
|
||||
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, 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 allow_y_sort, uint32_t canvas_cull_mask);
|
||||
|
||||
RendererCanvasRender::Item **z_list;
|
||||
RendererCanvasRender::Item **z_last_list;
|
||||
|
||||
public:
|
||||
void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel);
|
||||
void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask);
|
||||
|
||||
bool was_sdf_used();
|
||||
|
||||
|
@ -206,6 +207,9 @@ public:
|
|||
void canvas_item_set_visible(RID p_item, bool p_visible);
|
||||
void canvas_item_set_light_mask(RID p_item, int p_mask);
|
||||
|
||||
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_transform(RID p_item, const Transform2D &p_transform);
|
||||
void canvas_item_set_clip(RID p_item, bool p_clip);
|
||||
void canvas_item_set_distance_field_mode(RID p_item, bool p_enable);
|
||||
|
|
|
@ -530,7 +530,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
|||
ptr = ptr->filter_next_ptr;
|
||||
}
|
||||
|
||||
RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel);
|
||||
RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel, p_viewport->canvas_cull_mask);
|
||||
if (RSG::canvas->was_sdf_used()) {
|
||||
p_viewport->sdf_active = true;
|
||||
}
|
||||
|
@ -1349,6 +1349,12 @@ void RendererViewport::set_default_clear_color(const Color &p_color) {
|
|||
RSG::texture_storage->set_default_clear_color(p_color);
|
||||
}
|
||||
|
||||
void RendererViewport::viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask) {
|
||||
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
viewport->canvas_cull_mask = p_canvas_cull_mask;
|
||||
}
|
||||
|
||||
// Workaround for setting this on thread.
|
||||
void RendererViewport::call_set_vsync_mode(DisplayServer::VSyncMode p_mode, DisplayServer::WindowID p_window) {
|
||||
DisplayServer::get_singleton()->window_set_vsync_mode(p_mode, p_window);
|
||||
|
|
|
@ -117,6 +117,8 @@ public:
|
|||
|
||||
bool transparent_bg = false;
|
||||
|
||||
uint32_t canvas_cull_mask = 0xffffffff;
|
||||
|
||||
struct CanvasKey {
|
||||
int64_t stacking;
|
||||
RID canvas;
|
||||
|
@ -249,6 +251,8 @@ public:
|
|||
void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform);
|
||||
void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer);
|
||||
|
||||
void viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask);
|
||||
|
||||
void viewport_set_positional_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = true);
|
||||
void viewport_set_positional_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
|
||||
|
||||
|
|
|
@ -610,6 +610,8 @@ public:
|
|||
FUNC2(viewport_set_disable_environment, RID, bool)
|
||||
FUNC2(viewport_set_disable_3d, RID, bool)
|
||||
|
||||
FUNC2(viewport_set_canvas_cull_mask, RID, uint32_t)
|
||||
|
||||
FUNC2(viewport_attach_camera, RID, RID)
|
||||
FUNC2(viewport_set_scenario, RID, RID)
|
||||
FUNC2(viewport_attach_canvas, RID, RID)
|
||||
|
@ -828,6 +830,8 @@ public:
|
|||
FUNC2(canvas_item_set_visible, RID, bool)
|
||||
FUNC2(canvas_item_set_light_mask, RID, int)
|
||||
|
||||
FUNC2(canvas_item_set_visibility_layer, RID, uint32_t)
|
||||
|
||||
FUNC2(canvas_item_set_update_when_visible, RID, bool)
|
||||
|
||||
FUNC2(canvas_item_set_transform, RID, const Transform2D &)
|
||||
|
|
|
@ -2182,6 +2182,7 @@ void RenderingServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &RenderingServer::viewport_set_parent_viewport);
|
||||
ClassDB::bind_method(D_METHOD("viewport_attach_to_screen", "viewport", "rect", "screen"), &RenderingServer::viewport_attach_to_screen, DEFVAL(Rect2()), DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_render_direct_to_screen", "viewport", "enabled"), &RenderingServer::viewport_set_render_direct_to_screen);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_canvas_cull_mask", "viewport", "canvas_cull_mask"), &RenderingServer::viewport_set_canvas_cull_mask);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_mode", "viewport", "scaling_3d_mode"), &RenderingServer::viewport_set_scaling_3d_mode);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_scale", "viewport", "scale"), &RenderingServer::viewport_set_scaling_3d_scale);
|
||||
|
@ -2575,6 +2576,7 @@ void RenderingServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("canvas_item_set_default_texture_repeat", "item", "repeat"), &RenderingServer::canvas_item_set_default_texture_repeat);
|
||||
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_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);
|
||||
|
|
|
@ -807,6 +807,7 @@ public:
|
|||
virtual void viewport_set_size(RID p_viewport, int p_width, int p_height) = 0;
|
||||
virtual void viewport_set_active(RID p_viewport, bool p_active) = 0;
|
||||
virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0;
|
||||
virtual void viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask) = 0;
|
||||
|
||||
virtual void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) = 0;
|
||||
virtual void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) = 0;
|
||||
|
@ -1320,6 +1321,7 @@ public:
|
|||
virtual void canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect = Rect2()) = 0;
|
||||
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_draw_behind_parent(RID p_item, bool p_enable) = 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue