Output Modes: Preview, Split, and Multi-Window

Here’s the thing about creative coding tools: the editor is where you build, but the output is what the audience sees. And during a live show, you need total control over where that output goes.

So I built four output modes. Cycle through them and pick what fits your workflow.

The modes

Hidden, Editor only. You’re building, not performing. The graph still evaluates (nodes need their outputs for the inspector), but nothing renders to an output surface.

Preview, A draggable floating window inside the editor. Resize it, move it around, tuck it in a corner. Good for “I want to see what’s happening while I patch.”

SplitView, Vertical split. Editor on the left, output on the right. Configurable ratio. This is the “serious work” mode, full editor access with live output always visible.

Background, The output renders behind the editor canvas. The canvas becomes semi-transparent so you can see through it. Looks cool. Slightly chaotic. Good for when you want to feel like you’re patching inside your own visuals.

Separate Window, F5 pops a dedicated output window. Full resolution, its own surface, movable to a second monitor or projector. This is the performance mode. Editor on your laptop, output on the projector.

Under the hood

The interesting part is that Background mode doesn’t need a separate render pass. The output layer gets drawn first in the canvas render, then the editor draws on top with transparency. One Vello pass, two layers.

The other modes need a separate output_render_target texture. Vello renders the graph output to that texture, then it gets displayed wherever the mode needs it, as an egui image (Preview), as half the window (SplitView), or blitted to a second surface (SeparateWindow).

The mouse problem

Here’s something I didn’t think about until it was broken: when the output is visible (Preview or SplitView), mouse input from the output area needs to reach the graph. If you have a Mouse node, it should respond to cursor movement over the output, not just the editor canvas.

I track an output_rect in the input state. When the cursor is inside it, I flag pointer_in_output and transform the coordinates from window space to output space. Graph nodes that care about mouse input check this flag.

Better? Yes. But it was broken first. Lol.

What’s next

The output system works. But the editor itself needs love, there’s no way to undo a mistake, no quick search for nodes, and deleting a wire requires selecting it and pressing delete. Time for some UX work.

← Back to blog