Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions inox2d/src/puppet/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
40 changes: 32 additions & 8 deletions inox2d/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -277,21 +284,26 @@ pub trait InoxRendererExt {
}

impl<T: InoxRenderer> 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;
self.on_begin_masks(masks);
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();
}
Expand All @@ -300,21 +312,33 @@ impl<T: InoxRenderer> 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 {
self.on_end_mask();
}
}

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::<CompositeRenderCtx>(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 {
Expand All @@ -337,7 +361,7 @@ impl<T: InoxRenderer> 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.
Expand All @@ -348,7 +372,7 @@ impl<T: InoxRenderer> 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);
}
}
}
Loading