diff --git a/inox2d/src/puppet/tree.rs b/inox2d/src/puppet/tree.rs index 4adf19cf..73526385 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 c77fe74d..9181d677 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,18 @@ 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, }; + if !as_mask && !puppet.nodes.is_node_enabled(id) { + // 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 +303,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 +312,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 +320,25 @@ 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; } + if !as_mask && !puppet.nodes.is_node_enabled(id) { + // 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 +361,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 +372,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); } } }