From d815fe2ae824953ee9395b3ac989d86ee92ce747 Mon Sep 17 00:00:00 2001 From: Arcturus Emrys Date: Mon, 23 Feb 2026 23:57:19 +0000 Subject: [PATCH 1/2] Disabled nodes do not render (though they can still mask other nodes) --- inox2d/src/render.rs | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/inox2d/src/render.rs b/inox2d/src/render.rs index c77fe74..07f7165 100644 --- a/inox2d/src/render.rs +++ b/inox2d/src/render.rs @@ -264,10 +264,17 @@ pub trait InoxRenderer { pub trait InoxRendererExt { /// Draw a Drawable, which is potentially masked. - fn draw_drawable(&self, as_mask: bool, comps: &World, id: InoxNodeUuid); + fn draw_drawable(&self, puppet: &Puppet, as_mask: bool, comps: &World, id: InoxNodeUuid); /// Draw one composite. `components` must be referencing `comps`. - fn draw_composite(&self, as_mask: bool, comps: &World, components: &CompositeComponents, id: InoxNodeUuid); + fn draw_composite( + &self, + puppet: &Puppet, + as_mask: bool, + comps: &World, + components: &CompositeComponents, + id: InoxNodeUuid, + ); /// Iterate over top-level drawables (excluding masks) in zsort order, /// and make draw calls correspondingly. @@ -277,13 +284,19 @@ pub trait InoxRendererExt { } impl InoxRendererExt for T { - fn draw_drawable(&self, as_mask: bool, comps: &World, id: InoxNodeUuid) { + fn draw_drawable(&self, puppet: &Puppet, as_mask: bool, comps: &World, id: InoxNodeUuid) { let drawable_kind = DrawableKind::new(id, comps, false).expect("Node must be a Drawable."); let masks = match drawable_kind { DrawableKind::TexturedMesh(ref components) => &components.drawable.masks, DrawableKind::Composite(ref components) => &components.drawable.masks, }; + let is_enabled = puppet.nodes.get_node(id).unwrap().enabled; + if !is_enabled && !as_mask { + // Disabled nodes don't render, but they can still be used as masks. + return; + } + let mut has_masks = false; if let Some(ref masks) = masks { has_masks = true; @@ -291,7 +304,7 @@ impl InoxRendererExt for T { for mask in &masks.masks { self.on_begin_mask(mask); - self.draw_drawable(true, comps, mask.source); + self.draw_drawable(puppet, true, comps, mask.source); } self.on_begin_masked_content(); } @@ -300,7 +313,7 @@ impl InoxRendererExt for T { DrawableKind::TexturedMesh(ref components) => { self.draw_textured_mesh_content(as_mask, components, comps.get(id).unwrap(), id) } - DrawableKind::Composite(ref components) => self.draw_composite(as_mask, comps, components, id), + DrawableKind::Composite(ref components) => self.draw_composite(puppet, as_mask, comps, components, id), } if has_masks { @@ -308,13 +321,26 @@ impl InoxRendererExt for T { } } - fn draw_composite(&self, as_mask: bool, comps: &World, components: &CompositeComponents, id: InoxNodeUuid) { + fn draw_composite( + &self, + puppet: &Puppet, + as_mask: bool, + comps: &World, + components: &CompositeComponents, + id: InoxNodeUuid, + ) { let render_ctx = comps.get::(id).unwrap(); if render_ctx.zsorted_children_list.is_empty() { // Optimization: Nothing to be drawn, skip context switching return; } + let is_enabled = puppet.nodes.get_node(id).unwrap().enabled; + if !is_enabled && !as_mask { + // Disabled nodes don't render, but they can still be used as masks. + return; + } + self.begin_composite_content(as_mask, components, render_ctx, id); for uuid in &render_ctx.zsorted_children_list { @@ -337,7 +363,7 @@ impl InoxRendererExt for T { /// /// This does not guarantee the display of a puppet on screen due to these possible reasons: /// - Only provided `InoxRenderer` method implementations are called. - /// + /// /// For example, maybe the caller still need to transfer content from a texture buffer to the screen surface buffer. /// - The provided `InoxRender` implementation is wrong. /// - `puppet` here does not belong to the `model` this `renderer` is initialized with. This will likely result in panics for non-existent node uuids. @@ -348,7 +374,7 @@ impl InoxRendererExt for T { .expect("RenderCtx of puppet must be initialized before calling draw().") .root_drawables_zsorted { - self.draw_drawable(false, &puppet.node_comps, *uuid); + self.draw_drawable(puppet, false, &puppet.node_comps, *uuid); } } } From 129a878e87ab71198412740814b4748f4cd6c51c Mon Sep 17 00:00:00 2001 From: Arcturus Emrys Date: Mon, 16 Mar 2026 13:22:30 +0000 Subject: [PATCH 2/2] Disabled nodes transitiviely disable all their children. --- inox2d/src/puppet/tree.rs | 18 ++++++++++++++++++ inox2d/src/render.rs | 6 ++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/inox2d/src/puppet/tree.rs b/inox2d/src/puppet/tree.rs index 4adf19c..7352638 100644 --- a/inox2d/src/puppet/tree.rs +++ b/inox2d/src/puppet/tree.rs @@ -93,4 +93,22 @@ impl InoxNodeTree { .children(&self.arena) .map(|id| self.arena.get(id).unwrap().get()) } + + pub fn is_node_enabled(&self, node: InoxNodeUuid) -> bool { + let mut node = self.get_node(node).unwrap(); + + loop { + if !node.enabled { + return false; + } + + if node.uuid == self.root_node_id { + break; + } + + node = self.get_parent(node.uuid); + } + + return true; + } } diff --git a/inox2d/src/render.rs b/inox2d/src/render.rs index 07f7165..9181d67 100644 --- a/inox2d/src/render.rs +++ b/inox2d/src/render.rs @@ -291,8 +291,7 @@ impl InoxRendererExt for T { DrawableKind::Composite(ref components) => &components.drawable.masks, }; - let is_enabled = puppet.nodes.get_node(id).unwrap().enabled; - if !is_enabled && !as_mask { + if !as_mask && !puppet.nodes.is_node_enabled(id) { // Disabled nodes don't render, but they can still be used as masks. return; } @@ -335,8 +334,7 @@ impl InoxRendererExt for T { return; } - let is_enabled = puppet.nodes.get_node(id).unwrap().enabled; - if !is_enabled && !as_mask { + if !as_mask && !puppet.nodes.is_node_enabled(id) { // Disabled nodes don't render, but they can still be used as masks. return; }