Skip to main content

RenderPassBuilder

Struct RenderPassBuilder 

Source
pub struct RenderPassBuilder<'a> { /* private fields */ }
Expand description

Builder for creating render passes.

Implementations§

Source§

impl<'a> RenderPassBuilder<'a>

Source

pub fn new() -> Self

Examples found in repository?
examples/batched_renderer.rs (line 434)
372    fn render(
373        &mut self,
374        _ctx: &mut astrelis_winit::app::AppCtx,
375        window_id: WindowId,
376        events: &mut astrelis_winit::event::EventBatch,
377    ) {
378        // Handle resize and get dimensions (scoped to release window borrow)
379        let (phys_width, phys_height) = {
380            let Some(window) = self.windows.get_mut(&window_id) else {
381                return;
382            };
383
384            events.dispatch(|event| {
385                if let astrelis_winit::event::Event::WindowResized(size) = event {
386                    window.resized(*size);
387                    astrelis_winit::event::HandleStatus::consumed()
388                } else {
389                    astrelis_winit::event::HandleStatus::ignored()
390                }
391            });
392
393            let phys = window.physical_size();
394            (phys.width, phys.height)
395        };
396
397        let width = phys_width as f32;
398        let height = phys_height as f32;
399
400        if width < 1.0 || height < 1.0 {
401            return;
402        }
403
404        // Ensure depth buffer matches viewport
405        self.ensure_depth_buffer(phys_width, phys_height);
406
407        // Build instances and prepare GPU data
408        let instances = self.build_instances(width, height);
409        let batch = DrawBatch2D {
410            instances,
411            textures: vec![],
412            projection: Self::ortho_projection(width, height),
413        };
414        self.renderer.prepare(&batch);
415
416        let stats = self.renderer.stats();
417        if self.frame_count % 120 == 0 {
418            tracing::info!(
419                "Frame {}: {} instances ({} opaque, {} transparent), {} draw calls",
420                self.frame_count,
421                stats.instance_count,
422                stats.opaque_count,
423                stats.transparent_count,
424                stats.draw_calls,
425            );
426        }
427
428        // Re-borrow window for rendering
429        let window = self.windows.get_mut(&window_id).unwrap();
430        let mut frame = window.begin_drawing();
431
432        // Use RenderPassBuilder with depth stencil attachment
433        frame.with_pass(
434            astrelis_render::RenderPassBuilder::new()
435                .label("batched_example_pass")
436                .target(astrelis_render::RenderTarget::Surface)
437                .clear_color(astrelis_render::Color::rgba(0.08, 0.08, 0.1, 1.0))
438                .clear_depth(0.0) // 0.0 = far with GreaterEqual
439                .depth_stencil_attachment(
440                    &self.depth_view,
441                    Some(wgpu::Operations {
442                        load: wgpu::LoadOp::Clear(0.0),
443                        store: wgpu::StoreOp::Store,
444                    }),
445                    None,
446                ),
447            |pass| {
448                self.renderer.render(pass.wgpu_pass());
449            },
450        );
451
452        frame.finish();
453    }
Source

pub fn label(self, label: &'a str) -> Self

Set a debug label for the render pass.

Examples found in repository?
examples/batched_renderer.rs (line 435)
372    fn render(
373        &mut self,
374        _ctx: &mut astrelis_winit::app::AppCtx,
375        window_id: WindowId,
376        events: &mut astrelis_winit::event::EventBatch,
377    ) {
378        // Handle resize and get dimensions (scoped to release window borrow)
379        let (phys_width, phys_height) = {
380            let Some(window) = self.windows.get_mut(&window_id) else {
381                return;
382            };
383
384            events.dispatch(|event| {
385                if let astrelis_winit::event::Event::WindowResized(size) = event {
386                    window.resized(*size);
387                    astrelis_winit::event::HandleStatus::consumed()
388                } else {
389                    astrelis_winit::event::HandleStatus::ignored()
390                }
391            });
392
393            let phys = window.physical_size();
394            (phys.width, phys.height)
395        };
396
397        let width = phys_width as f32;
398        let height = phys_height as f32;
399
400        if width < 1.0 || height < 1.0 {
401            return;
402        }
403
404        // Ensure depth buffer matches viewport
405        self.ensure_depth_buffer(phys_width, phys_height);
406
407        // Build instances and prepare GPU data
408        let instances = self.build_instances(width, height);
409        let batch = DrawBatch2D {
410            instances,
411            textures: vec![],
412            projection: Self::ortho_projection(width, height),
413        };
414        self.renderer.prepare(&batch);
415
416        let stats = self.renderer.stats();
417        if self.frame_count % 120 == 0 {
418            tracing::info!(
419                "Frame {}: {} instances ({} opaque, {} transparent), {} draw calls",
420                self.frame_count,
421                stats.instance_count,
422                stats.opaque_count,
423                stats.transparent_count,
424                stats.draw_calls,
425            );
426        }
427
428        // Re-borrow window for rendering
429        let window = self.windows.get_mut(&window_id).unwrap();
430        let mut frame = window.begin_drawing();
431
432        // Use RenderPassBuilder with depth stencil attachment
433        frame.with_pass(
434            astrelis_render::RenderPassBuilder::new()
435                .label("batched_example_pass")
436                .target(astrelis_render::RenderTarget::Surface)
437                .clear_color(astrelis_render::Color::rgba(0.08, 0.08, 0.1, 1.0))
438                .clear_depth(0.0) // 0.0 = far with GreaterEqual
439                .depth_stencil_attachment(
440                    &self.depth_view,
441                    Some(wgpu::Operations {
442                        load: wgpu::LoadOp::Clear(0.0),
443                        store: wgpu::StoreOp::Store,
444                    }),
445                    None,
446                ),
447            |pass| {
448                self.renderer.render(pass.wgpu_pass());
449            },
450        );
451
452        frame.finish();
453    }
Source

pub fn target(self, target: RenderTarget<'a>) -> Self

Set the render target (Surface or Framebuffer).

This is the simplified API - use this instead of manual color_attachment calls.

Examples found in repository?
examples/batched_renderer.rs (line 436)
372    fn render(
373        &mut self,
374        _ctx: &mut astrelis_winit::app::AppCtx,
375        window_id: WindowId,
376        events: &mut astrelis_winit::event::EventBatch,
377    ) {
378        // Handle resize and get dimensions (scoped to release window borrow)
379        let (phys_width, phys_height) = {
380            let Some(window) = self.windows.get_mut(&window_id) else {
381                return;
382            };
383
384            events.dispatch(|event| {
385                if let astrelis_winit::event::Event::WindowResized(size) = event {
386                    window.resized(*size);
387                    astrelis_winit::event::HandleStatus::consumed()
388                } else {
389                    astrelis_winit::event::HandleStatus::ignored()
390                }
391            });
392
393            let phys = window.physical_size();
394            (phys.width, phys.height)
395        };
396
397        let width = phys_width as f32;
398        let height = phys_height as f32;
399
400        if width < 1.0 || height < 1.0 {
401            return;
402        }
403
404        // Ensure depth buffer matches viewport
405        self.ensure_depth_buffer(phys_width, phys_height);
406
407        // Build instances and prepare GPU data
408        let instances = self.build_instances(width, height);
409        let batch = DrawBatch2D {
410            instances,
411            textures: vec![],
412            projection: Self::ortho_projection(width, height),
413        };
414        self.renderer.prepare(&batch);
415
416        let stats = self.renderer.stats();
417        if self.frame_count % 120 == 0 {
418            tracing::info!(
419                "Frame {}: {} instances ({} opaque, {} transparent), {} draw calls",
420                self.frame_count,
421                stats.instance_count,
422                stats.opaque_count,
423                stats.transparent_count,
424                stats.draw_calls,
425            );
426        }
427
428        // Re-borrow window for rendering
429        let window = self.windows.get_mut(&window_id).unwrap();
430        let mut frame = window.begin_drawing();
431
432        // Use RenderPassBuilder with depth stencil attachment
433        frame.with_pass(
434            astrelis_render::RenderPassBuilder::new()
435                .label("batched_example_pass")
436                .target(astrelis_render::RenderTarget::Surface)
437                .clear_color(astrelis_render::Color::rgba(0.08, 0.08, 0.1, 1.0))
438                .clear_depth(0.0) // 0.0 = far with GreaterEqual
439                .depth_stencil_attachment(
440                    &self.depth_view,
441                    Some(wgpu::Operations {
442                        load: wgpu::LoadOp::Clear(0.0),
443                        store: wgpu::StoreOp::Store,
444                    }),
445                    None,
446                ),
447            |pass| {
448                self.renderer.render(pass.wgpu_pass());
449            },
450        );
451
452        frame.finish();
453    }
Source

pub fn clear_color(self, color: impl Into<ClearOp>) -> Self

Set clear color for the render target.

Pass a wgpu::Color or use ClearOp::Load to preserve existing contents.

Examples found in repository?
examples/batched_renderer.rs (line 437)
372    fn render(
373        &mut self,
374        _ctx: &mut astrelis_winit::app::AppCtx,
375        window_id: WindowId,
376        events: &mut astrelis_winit::event::EventBatch,
377    ) {
378        // Handle resize and get dimensions (scoped to release window borrow)
379        let (phys_width, phys_height) = {
380            let Some(window) = self.windows.get_mut(&window_id) else {
381                return;
382            };
383
384            events.dispatch(|event| {
385                if let astrelis_winit::event::Event::WindowResized(size) = event {
386                    window.resized(*size);
387                    astrelis_winit::event::HandleStatus::consumed()
388                } else {
389                    astrelis_winit::event::HandleStatus::ignored()
390                }
391            });
392
393            let phys = window.physical_size();
394            (phys.width, phys.height)
395        };
396
397        let width = phys_width as f32;
398        let height = phys_height as f32;
399
400        if width < 1.0 || height < 1.0 {
401            return;
402        }
403
404        // Ensure depth buffer matches viewport
405        self.ensure_depth_buffer(phys_width, phys_height);
406
407        // Build instances and prepare GPU data
408        let instances = self.build_instances(width, height);
409        let batch = DrawBatch2D {
410            instances,
411            textures: vec![],
412            projection: Self::ortho_projection(width, height),
413        };
414        self.renderer.prepare(&batch);
415
416        let stats = self.renderer.stats();
417        if self.frame_count % 120 == 0 {
418            tracing::info!(
419                "Frame {}: {} instances ({} opaque, {} transparent), {} draw calls",
420                self.frame_count,
421                stats.instance_count,
422                stats.opaque_count,
423                stats.transparent_count,
424                stats.draw_calls,
425            );
426        }
427
428        // Re-borrow window for rendering
429        let window = self.windows.get_mut(&window_id).unwrap();
430        let mut frame = window.begin_drawing();
431
432        // Use RenderPassBuilder with depth stencil attachment
433        frame.with_pass(
434            astrelis_render::RenderPassBuilder::new()
435                .label("batched_example_pass")
436                .target(astrelis_render::RenderTarget::Surface)
437                .clear_color(astrelis_render::Color::rgba(0.08, 0.08, 0.1, 1.0))
438                .clear_depth(0.0) // 0.0 = far with GreaterEqual
439                .depth_stencil_attachment(
440                    &self.depth_view,
441                    Some(wgpu::Operations {
442                        load: wgpu::LoadOp::Clear(0.0),
443                        store: wgpu::StoreOp::Store,
444                    }),
445                    None,
446                ),
447            |pass| {
448                self.renderer.render(pass.wgpu_pass());
449            },
450        );
451
452        frame.finish();
453    }
Source

pub fn clear_depth(self, depth: f32) -> Self

Set depth clear operation.

Examples found in repository?
examples/batched_renderer.rs (line 438)
372    fn render(
373        &mut self,
374        _ctx: &mut astrelis_winit::app::AppCtx,
375        window_id: WindowId,
376        events: &mut astrelis_winit::event::EventBatch,
377    ) {
378        // Handle resize and get dimensions (scoped to release window borrow)
379        let (phys_width, phys_height) = {
380            let Some(window) = self.windows.get_mut(&window_id) else {
381                return;
382            };
383
384            events.dispatch(|event| {
385                if let astrelis_winit::event::Event::WindowResized(size) = event {
386                    window.resized(*size);
387                    astrelis_winit::event::HandleStatus::consumed()
388                } else {
389                    astrelis_winit::event::HandleStatus::ignored()
390                }
391            });
392
393            let phys = window.physical_size();
394            (phys.width, phys.height)
395        };
396
397        let width = phys_width as f32;
398        let height = phys_height as f32;
399
400        if width < 1.0 || height < 1.0 {
401            return;
402        }
403
404        // Ensure depth buffer matches viewport
405        self.ensure_depth_buffer(phys_width, phys_height);
406
407        // Build instances and prepare GPU data
408        let instances = self.build_instances(width, height);
409        let batch = DrawBatch2D {
410            instances,
411            textures: vec![],
412            projection: Self::ortho_projection(width, height),
413        };
414        self.renderer.prepare(&batch);
415
416        let stats = self.renderer.stats();
417        if self.frame_count % 120 == 0 {
418            tracing::info!(
419                "Frame {}: {} instances ({} opaque, {} transparent), {} draw calls",
420                self.frame_count,
421                stats.instance_count,
422                stats.opaque_count,
423                stats.transparent_count,
424                stats.draw_calls,
425            );
426        }
427
428        // Re-borrow window for rendering
429        let window = self.windows.get_mut(&window_id).unwrap();
430        let mut frame = window.begin_drawing();
431
432        // Use RenderPassBuilder with depth stencil attachment
433        frame.with_pass(
434            astrelis_render::RenderPassBuilder::new()
435                .label("batched_example_pass")
436                .target(astrelis_render::RenderTarget::Surface)
437                .clear_color(astrelis_render::Color::rgba(0.08, 0.08, 0.1, 1.0))
438                .clear_depth(0.0) // 0.0 = far with GreaterEqual
439                .depth_stencil_attachment(
440                    &self.depth_view,
441                    Some(wgpu::Operations {
442                        load: wgpu::LoadOp::Clear(0.0),
443                        store: wgpu::StoreOp::Store,
444                    }),
445                    None,
446                ),
447            |pass| {
448                self.renderer.render(pass.wgpu_pass());
449            },
450        );
451
452        frame.finish();
453    }
Source

pub fn load_depth(self) -> Self

Load existing depth values instead of clearing.

Source

pub fn color_attachment( self, view: Option<&'a TextureView>, resolve_target: Option<&'a TextureView>, ops: Operations<Color>, ) -> Self

Add a color attachment manually (advanced API).

For most cases, use .target() instead.

Source

pub fn depth_stencil_attachment( self, view: &'a TextureView, depth_ops: Option<Operations<f32>>, stencil_ops: Option<Operations<u32>>, ) -> Self

Add a depth-stencil attachment manually (advanced API).

For framebuffers with depth, the depth attachment is handled automatically when using .target().

Examples found in repository?
examples/batched_renderer.rs (lines 439-446)
372    fn render(
373        &mut self,
374        _ctx: &mut astrelis_winit::app::AppCtx,
375        window_id: WindowId,
376        events: &mut astrelis_winit::event::EventBatch,
377    ) {
378        // Handle resize and get dimensions (scoped to release window borrow)
379        let (phys_width, phys_height) = {
380            let Some(window) = self.windows.get_mut(&window_id) else {
381                return;
382            };
383
384            events.dispatch(|event| {
385                if let astrelis_winit::event::Event::WindowResized(size) = event {
386                    window.resized(*size);
387                    astrelis_winit::event::HandleStatus::consumed()
388                } else {
389                    astrelis_winit::event::HandleStatus::ignored()
390                }
391            });
392
393            let phys = window.physical_size();
394            (phys.width, phys.height)
395        };
396
397        let width = phys_width as f32;
398        let height = phys_height as f32;
399
400        if width < 1.0 || height < 1.0 {
401            return;
402        }
403
404        // Ensure depth buffer matches viewport
405        self.ensure_depth_buffer(phys_width, phys_height);
406
407        // Build instances and prepare GPU data
408        let instances = self.build_instances(width, height);
409        let batch = DrawBatch2D {
410            instances,
411            textures: vec![],
412            projection: Self::ortho_projection(width, height),
413        };
414        self.renderer.prepare(&batch);
415
416        let stats = self.renderer.stats();
417        if self.frame_count % 120 == 0 {
418            tracing::info!(
419                "Frame {}: {} instances ({} opaque, {} transparent), {} draw calls",
420                self.frame_count,
421                stats.instance_count,
422                stats.opaque_count,
423                stats.transparent_count,
424                stats.draw_calls,
425            );
426        }
427
428        // Re-borrow window for rendering
429        let window = self.windows.get_mut(&window_id).unwrap();
430        let mut frame = window.begin_drawing();
431
432        // Use RenderPassBuilder with depth stencil attachment
433        frame.with_pass(
434            astrelis_render::RenderPassBuilder::new()
435                .label("batched_example_pass")
436                .target(astrelis_render::RenderTarget::Surface)
437                .clear_color(astrelis_render::Color::rgba(0.08, 0.08, 0.1, 1.0))
438                .clear_depth(0.0) // 0.0 = far with GreaterEqual
439                .depth_stencil_attachment(
440                    &self.depth_view,
441                    Some(wgpu::Operations {
442                        load: wgpu::LoadOp::Clear(0.0),
443                        store: wgpu::StoreOp::Store,
444                    }),
445                    None,
446                ),
447            |pass| {
448                self.renderer.render(pass.wgpu_pass());
449            },
450        );
451
452        frame.finish();
453    }
Source

pub fn build(self, frame_context: &'a mut FrameContext) -> RenderPass<'a>

Builds the render pass and begins it on the provided frame context.

This takes ownership of the CommandEncoder from the FrameContext, and releases it back to the FrameContext when the RenderPass is dropped or finish is called.

Trait Implementations§

Source§

impl Default for RenderPassBuilder<'_>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for RenderPassBuilder<'a>

§

impl<'a> !RefUnwindSafe for RenderPassBuilder<'a>

§

impl<'a> Send for RenderPassBuilder<'a>

§

impl<'a> Sync for RenderPassBuilder<'a>

§

impl<'a> Unpin for RenderPassBuilder<'a>

§

impl<'a> !UnwindSafe for RenderPassBuilder<'a>

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> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
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.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

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

Source§

impl<T> WasmNotSendSync for T

Source§

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