pub struct LineRenderer { /* private fields */ }Expand description
Draws segment buffers as thick glowing quads. Owns its pipeline, a fixed-capacity instance buffer, and the aspect/glow uniform.
Implementations§
Source§impl LineRenderer
impl LineRenderer
Sourcepub fn new(
device: &Device,
surface_format: TextureFormat,
capacity: usize,
label: &str,
) -> Self
pub fn new( device: &Device, surface_format: TextureFormat, capacity: usize, label: &str, ) -> Self
Build the pipeline and a capacity-segment instance buffer on device.
label names this instance’s GPU resources; it must be unique per
LineRenderer — two line scenes coexist (parametric + generator), and
distinct labels keep their pipelines/buffers unambiguous in tooling and
captures.
Sourcepub fn new_split(
device: &Device,
surface_format: TextureFormat,
capacity: usize,
label: &str,
) -> Self
pub fn new_split( device: &Device, surface_format: TextureFormat, capacity: usize, label: &str, ) -> Self
new, plus the second pipeline
draw_split needs. Only a scene that actually splits
its batch by blend mode should call this — see
over_pipeline for why building it unconditionally
is not free.
Sourcepub fn new_split_with_arcs(
device: &Device,
surface_format: TextureFormat,
capacity: usize,
arc_capacity: usize,
label: &str,
) -> Self
pub fn new_split_with_arcs( device: &Device, surface_format: TextureFormat, capacity: usize, arc_capacity: usize, label: &str, ) -> Self
new_with_arcs, plus the OVER pipelines
draw_opaque needs — the constructor the shared line
renderer takes, because any of the four line systems may ask for the
opacity-preserving seam (ADR-0138).
The pipelines are built here rather than on the first preset that asks, deliberately: building a GPU resource mid-run changes what a later pass resolves to on the DX12 software adapter, which would make the seam’s arrival visible in scenes that never selected it.
Sourcepub fn new_with_arcs(
device: &Device,
surface_format: TextureFormat,
capacity: usize,
arc_capacity: usize,
label: &str,
) -> Self
pub fn new_with_arcs( device: &Device, surface_format: TextureFormat, capacity: usize, arc_capacity: usize, label: &str, ) -> Self
new, plus the arc pipeline and an arc_capacity-instance
arc buffer (ArcInstance, ADR-0098).
Only a scene that actually draws arcs should call this — see
arc_pipeline for why building it unconditionally
is not free. arc_capacity is its own budget rather than a share of
capacity: an arc replaces many segments, so the two counts are not the
same order and sizing one from the other would waste most of it.
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Segments the instance buffer can hold — the scene clamps its geometry to this and surfaces any drop at load (ADR-0007 cap must never be silent).
Sourcepub fn arc_capacity(&self) -> usize
pub fn arc_capacity(&self) -> usize
Arcs the arc buffer can hold — 0 when this renderer was not built with
new_with_arcs, in which case
draw_arcs draws none.
Sourcepub fn draw(
&mut self,
queue: &Queue,
encoder: &mut CommandEncoder,
view: &TextureView,
aspect: f32,
glow: f32,
softness: f32,
metric: StrokeMetric,
xform: ViewTransform,
segments: &[SegmentInstance],
)
pub fn draw( &mut self, queue: &Queue, encoder: &mut CommandEncoder, view: &TextureView, aspect: f32, glow: f32, softness: f32, metric: StrokeMetric, xform: ViewTransform, segments: &[SegmentInstance], )
Draw segments as thick glowing quads at the given aspect and glow
multiplier, under the shared xform camera transform (zoom/pan, ADR-0018),
loading over the engine backdrop rather than clearing (Plan 0018 Phase
3 — the background pass owns the clear). Segments beyond capacity are
dropped defensively (the scene is responsible for capping at load).
softness is the across-the-stroke profile (PROFILE_WGSL, ADR-0124):
1.0 is the pre-Plan-0114 quadratic falloff, 0 a solid stroke with a
one-pixel edge. There is no default here — one uniform serves every
entry point, so each caller names the constant it answers to:
lines::DEFAULT_SOFTNESS for the four line
families, warp_mesh::MILKDROP_SOFTNESS
for the MilkDrop surface.
metric is the space the stroke is measured in (ADR-0160) and has no
default either, for the same reason: StrokeMetric::World for the four
line families, StrokeMetric::Clip for warp_mesh.
Sourcepub fn draw_split(
&mut self,
queue: &Queue,
encoder: &mut CommandEncoder,
view: &TextureView,
aspect: f32,
glow: f32,
softness: f32,
metric: StrokeMetric,
xform: ViewTransform,
segments: &[SegmentInstance],
n_additive: usize,
)
pub fn draw_split( &mut self, queue: &Queue, encoder: &mut CommandEncoder, view: &TextureView, aspect: f32, glow: f32, softness: f32, metric: StrokeMetric, xform: ViewTransform, segments: &[SegmentInstance], n_additive: usize, )
draw, with the batch split by blend mode: the first
n_additive segments are added (ADR-0056’s seam, what every line scene
uses), and the rest are composited over using each segment’s own
alpha.
§Why a split range rather than two calls
One instance buffer, one upload, one render pass, two draw calls that
differ only in the pipeline bound. Two calls would mean two passes over
the same attachment and a second buffer, and the order would stop being
expressible: an over-blended stroke has to land on top of the additive
light it covers, which a single ordered batch gives for free.
The caller partitions — it is the only thing that knows which producer
each segment came from. Passing n_additive >= segments.len() is exactly
draw.
Sourcepub fn draw_arcs(
&mut self,
queue: &Queue,
encoder: &mut CommandEncoder,
view: &TextureView,
aspect: f32,
glow: f32,
softness: f32,
metric: StrokeMetric,
xform: ViewTransform,
segments: &[SegmentInstance],
arcs: &[ArcInstance],
)
pub fn draw_arcs( &mut self, queue: &Queue, encoder: &mut CommandEncoder, view: &TextureView, aspect: f32, glow: f32, softness: f32, metric: StrokeMetric, xform: ViewTransform, segments: &[SegmentInstance], arcs: &[ArcInstance], )
draw, plus arcs — ArcInstances stroked by the
per-pixel distance field (ADR-0098) in the same additive pass, from
the same uniform, after the segments.
One pass rather than two for the reason draw_split
gives: a second pass would mean a second load of the attachment and a
second set of uniforms to keep in step. Additive blending is
order-independent, so “after the segments” is a statement about the
command stream and not about the picture.
Arcs beyond arc_capacity are dropped defensively,
exactly as segments beyond capacity are; a renderer built without the
arc pipeline has a capacity of zero and draws none.
Sourcepub fn draw_opaque(
&mut self,
queue: &Queue,
encoder: &mut CommandEncoder,
view: &TextureView,
aspect: f32,
glow: f32,
softness: f32,
metric: StrokeMetric,
xform: ViewTransform,
segments: &[SegmentInstance],
arcs: &[ArcInstance],
)
pub fn draw_opaque( &mut self, queue: &Queue, encoder: &mut CommandEncoder, view: &TextureView, aspect: f32, glow: f32, softness: f32, metric: StrokeMetric, xform: ViewTransform, segments: &[SegmentInstance], arcs: &[ArcInstance], )
draw_arcs, with the whole batch composited over
rather than added — the opacity-preserving seam of ADR-0138’s limited-ink
class, reached by the four line systems through stroke_blend.
Segments and arcs both take the OVER pipeline, so a scene whose figure is
part strokes and part circles draws one substance rather than two. Order
inside the batch becomes the order on screen: a later stroke replaces the
interior of what it covers instead of summing with it, which is the whole
property. Pass an empty arcs from a scene that draws none.
A renderer built without the OVER pipelines falls back to the additive
ones, exactly as draw_split does — the wrong blend
rather than a panic, and unreachable in the shipped path, where the shared
line renderer is built with them.