Skip to main content

LineRenderer

Struct LineRenderer 

Source
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

Source

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.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

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.

Source

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.

Source

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 arcsArcInstances 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.

Source

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.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T
where T: WasmNotSend + WasmNotSync,

§

impl<T> WasmNotSync for T
where T: Sync,