Skip to main content

RenderPass

Struct RenderPass 

Source
pub struct RenderPass<'f> { /* private fields */ }
Expand description

A render pass that owns its encoder.

When dropped, the render pass:

  1. Ends the wgpu render pass
  2. Finishes the command encoder
  3. Pushes the command buffer to the frame

This design eliminates encoder movement and borrow conflicts.

Implementations§

Source§

impl<'f> RenderPass<'f>

Source

pub fn wgpu_pass(&mut self) -> &mut RenderPass<'static>

Get the underlying wgpu RenderPass (mutable).

§Panics

Panics if the render pass has already been consumed.

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

pub fn wgpu_pass_ref(&self) -> &RenderPass<'static>

Get the underlying wgpu RenderPass (immutable).

§Panics

Panics if the render pass has already been consumed.

Source

pub fn try_wgpu_pass(&mut self) -> Option<&mut RenderPass<'static>>

Try to get the underlying wgpu RenderPass.

Source

pub fn is_valid(&self) -> bool

Check if the render pass is still valid.

Source

pub fn raw_pass(&mut self) -> &mut RenderPass<'static>

Get raw access to the pass (alias for wgpu_pass).

Source

pub fn encoder(&self) -> Option<&CommandEncoder>

Get the command encoder.

Source

pub fn encoder_mut(&mut self) -> Option<&mut CommandEncoder>

Get mutable access to the command encoder.

Source

pub fn graphics(&self) -> &GraphicsContext

Get the graphics context.

Source

pub fn record_draw_call(&self)

Record a draw call for statistics.

Source

pub fn into_encoder(self) -> CommandEncoder

Consume the pass early and return the encoder for further use.

This ends the render pass but allows the encoder to be used for additional commands before submission.

Source

pub fn finish(self)

Finish the render pass (called automatically on drop).

Source

pub fn set_viewport_physical( &mut self, rect: PhysicalRect<f32>, min_depth: f32, max_depth: f32, )

Set the viewport using physical coordinates.

Source

pub fn set_viewport_logical( &mut self, rect: LogicalRect<f32>, min_depth: f32, max_depth: f32, scale: ScaleFactor, )

Set the viewport using logical coordinates.

Source

pub fn set_viewport(&mut self, viewport: &Viewport)

Set the viewport from a Viewport struct.

Source

pub fn set_scissor_physical(&mut self, rect: PhysicalRect<u32>)

Set the scissor rectangle using physical coordinates.

Source

pub fn set_scissor_logical( &mut self, rect: LogicalRect<f32>, scale: ScaleFactor, )

Set the scissor rectangle using logical coordinates.

Source

pub fn set_pipeline(&mut self, pipeline: &RenderPipeline)

Set the pipeline.

Examples found in repository?
examples/sprite_sheet.rs (line 460)
431    fn render(
432        &mut self,
433        _ctx: &mut astrelis_winit::app::AppCtx,
434        window_id: WindowId,
435        events: &mut astrelis_winit::event::EventBatch,
436    ) {
437        let Some(window) = self.windows.get_mut(&window_id) else {
438            return;
439        };
440
441        // Handle resize
442        events.dispatch(|event| {
443            if let astrelis_winit::event::Event::WindowResized(size) = event {
444                window.resized(*size);
445                astrelis_winit::event::HandleStatus::consumed()
446            } else {
447                astrelis_winit::event::HandleStatus::ignored()
448            }
449        });
450
451        let Some(frame) = window.begin_frame() else {
452            return; // Surface not available
453        };
454        {
455            let mut pass = frame
456                .render_pass()
457                .clear_color(Color::rgb(0.1, 0.1, 0.15))
458                .label("sprite_sheet_pass")
459                .build();
460            pass.set_pipeline(&self.pipeline);
461            pass.set_bind_group(0, &self.bind_group, &[]);
462            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
463            pass.draw(0..6, 0..1);
464        }
465        // Frame auto-submits on drop
466    }
More examples
Hide additional examples
examples/image_blitting.rs (line 516)
486    fn render(
487        &mut self,
488        _ctx: &mut astrelis_winit::app::AppCtx,
489        window_id: WindowId,
490        events: &mut astrelis_winit::event::EventBatch,
491    ) {
492        let Some(window) = self.windows.get_mut(&window_id) else {
493            return;
494        };
495
496        // Handle resize
497        events.dispatch(|event| {
498            if let astrelis_winit::event::Event::WindowResized(size) = event {
499                window.resized(*size);
500                astrelis_winit::event::HandleStatus::consumed()
501            } else {
502                astrelis_winit::event::HandleStatus::ignored()
503            }
504        });
505
506        let Some(frame) = window.begin_frame() else {
507            return; // Surface not available
508        };
509
510        {
511            let mut pass = frame
512                .render_pass()
513                .clear_color(Color::rgb(0.05, 0.05, 0.08))
514                .label("image_blitting_pass")
515                .build();
516            pass.set_pipeline(&self.pipeline);
517            pass.set_bind_group(0, &self.bind_group, &[]);
518            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
519            pass.draw(0..6, 0..1);
520        }
521        // Frame auto-submits on drop
522    }
examples/textured_window.rs (line 291)
260    fn render(
261        &mut self,
262        _ctx: &mut astrelis_winit::app::AppCtx,
263        window_id: WindowId,
264        events: &mut astrelis_winit::event::EventBatch,
265    ) {
266        if window_id != self.window_id {
267            return;
268        }
269
270        // Handle window resize events
271        events.dispatch(|event| {
272            if let astrelis_winit::event::Event::WindowResized(size) = event {
273                self.window.resized(*size);
274                astrelis_winit::event::HandleStatus::consumed()
275            } else {
276                astrelis_winit::event::HandleStatus::ignored()
277            }
278        });
279
280        // --- Render Loop ---
281        let Some(frame) = self.window.begin_frame() else {
282            return; // Surface not available
283        };
284
285        {
286            let mut pass = frame
287                .render_pass()
288                .clear_color(Color::rgb(0.1, 0.2, 0.3))
289                .label("textured_window_pass")
290                .build();
291            pass.set_pipeline(&self.pipeline);
292            pass.set_bind_group(0, &self.bind_group, &[]);
293            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
294            pass.draw(0..6, 0..1);
295        }
296        // Frame auto-submits on drop
297    }
examples/renderer_api.rs (line 311)
284    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
285        if window_id != self.window_id {
286            return;
287        }
288
289        // Handle window-specific resize events
290        events.dispatch(|event| {
291            if let astrelis_winit::event::Event::WindowResized(size) = event {
292                self.window.resized(*size);
293                astrelis_winit::event::HandleStatus::consumed()
294            } else {
295                astrelis_winit::event::HandleStatus::ignored()
296            }
297        });
298
299        let Some(frame) = self.window.begin_frame() else {
300            return; // Surface not available
301        };
302
303        // Pass 1: Render to offscreen framebuffer
304        {
305            let mut pass = frame
306                .render_pass()
307                .target(RenderTarget::Framebuffer(&self.offscreen_fb))
308                .clear_color(Color::rgb(0.2, 0.1, 0.3))
309                .label("offscreen_pass")
310                .build();
311            pass.set_pipeline(&self.pipeline);
312            pass.set_bind_group(0, &self.bind_group, &[]);
313            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
314            pass.draw(0..6, 0..1);
315        }
316
317        // Pass 2: Blit framebuffer to surface
318        {
319            let mut pass = frame
320                .render_pass()
321                .clear_color(Color::rgb(0.1, 0.2, 0.3))
322                .label("blit_pass")
323                .build();
324            pass.set_pipeline(&self.blit_pipeline);
325            pass.set_bind_group(0, &self.blit_bind_group, &[]);
326            // Draw fullscreen triangle
327            pass.draw(0..3, 0..1);
328        }
329        // Frame auto-submits on drop
330    }
Source

pub fn set_bind_group( &mut self, index: u32, bind_group: &BindGroup, offsets: &[u32], )

Set a bind group.

Examples found in repository?
examples/sprite_sheet.rs (line 461)
431    fn render(
432        &mut self,
433        _ctx: &mut astrelis_winit::app::AppCtx,
434        window_id: WindowId,
435        events: &mut astrelis_winit::event::EventBatch,
436    ) {
437        let Some(window) = self.windows.get_mut(&window_id) else {
438            return;
439        };
440
441        // Handle resize
442        events.dispatch(|event| {
443            if let astrelis_winit::event::Event::WindowResized(size) = event {
444                window.resized(*size);
445                astrelis_winit::event::HandleStatus::consumed()
446            } else {
447                astrelis_winit::event::HandleStatus::ignored()
448            }
449        });
450
451        let Some(frame) = window.begin_frame() else {
452            return; // Surface not available
453        };
454        {
455            let mut pass = frame
456                .render_pass()
457                .clear_color(Color::rgb(0.1, 0.1, 0.15))
458                .label("sprite_sheet_pass")
459                .build();
460            pass.set_pipeline(&self.pipeline);
461            pass.set_bind_group(0, &self.bind_group, &[]);
462            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
463            pass.draw(0..6, 0..1);
464        }
465        // Frame auto-submits on drop
466    }
More examples
Hide additional examples
examples/image_blitting.rs (line 517)
486    fn render(
487        &mut self,
488        _ctx: &mut astrelis_winit::app::AppCtx,
489        window_id: WindowId,
490        events: &mut astrelis_winit::event::EventBatch,
491    ) {
492        let Some(window) = self.windows.get_mut(&window_id) else {
493            return;
494        };
495
496        // Handle resize
497        events.dispatch(|event| {
498            if let astrelis_winit::event::Event::WindowResized(size) = event {
499                window.resized(*size);
500                astrelis_winit::event::HandleStatus::consumed()
501            } else {
502                astrelis_winit::event::HandleStatus::ignored()
503            }
504        });
505
506        let Some(frame) = window.begin_frame() else {
507            return; // Surface not available
508        };
509
510        {
511            let mut pass = frame
512                .render_pass()
513                .clear_color(Color::rgb(0.05, 0.05, 0.08))
514                .label("image_blitting_pass")
515                .build();
516            pass.set_pipeline(&self.pipeline);
517            pass.set_bind_group(0, &self.bind_group, &[]);
518            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
519            pass.draw(0..6, 0..1);
520        }
521        // Frame auto-submits on drop
522    }
examples/textured_window.rs (line 292)
260    fn render(
261        &mut self,
262        _ctx: &mut astrelis_winit::app::AppCtx,
263        window_id: WindowId,
264        events: &mut astrelis_winit::event::EventBatch,
265    ) {
266        if window_id != self.window_id {
267            return;
268        }
269
270        // Handle window resize events
271        events.dispatch(|event| {
272            if let astrelis_winit::event::Event::WindowResized(size) = event {
273                self.window.resized(*size);
274                astrelis_winit::event::HandleStatus::consumed()
275            } else {
276                astrelis_winit::event::HandleStatus::ignored()
277            }
278        });
279
280        // --- Render Loop ---
281        let Some(frame) = self.window.begin_frame() else {
282            return; // Surface not available
283        };
284
285        {
286            let mut pass = frame
287                .render_pass()
288                .clear_color(Color::rgb(0.1, 0.2, 0.3))
289                .label("textured_window_pass")
290                .build();
291            pass.set_pipeline(&self.pipeline);
292            pass.set_bind_group(0, &self.bind_group, &[]);
293            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
294            pass.draw(0..6, 0..1);
295        }
296        // Frame auto-submits on drop
297    }
examples/renderer_api.rs (line 312)
284    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
285        if window_id != self.window_id {
286            return;
287        }
288
289        // Handle window-specific resize events
290        events.dispatch(|event| {
291            if let astrelis_winit::event::Event::WindowResized(size) = event {
292                self.window.resized(*size);
293                astrelis_winit::event::HandleStatus::consumed()
294            } else {
295                astrelis_winit::event::HandleStatus::ignored()
296            }
297        });
298
299        let Some(frame) = self.window.begin_frame() else {
300            return; // Surface not available
301        };
302
303        // Pass 1: Render to offscreen framebuffer
304        {
305            let mut pass = frame
306                .render_pass()
307                .target(RenderTarget::Framebuffer(&self.offscreen_fb))
308                .clear_color(Color::rgb(0.2, 0.1, 0.3))
309                .label("offscreen_pass")
310                .build();
311            pass.set_pipeline(&self.pipeline);
312            pass.set_bind_group(0, &self.bind_group, &[]);
313            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
314            pass.draw(0..6, 0..1);
315        }
316
317        // Pass 2: Blit framebuffer to surface
318        {
319            let mut pass = frame
320                .render_pass()
321                .clear_color(Color::rgb(0.1, 0.2, 0.3))
322                .label("blit_pass")
323                .build();
324            pass.set_pipeline(&self.blit_pipeline);
325            pass.set_bind_group(0, &self.blit_bind_group, &[]);
326            // Draw fullscreen triangle
327            pass.draw(0..3, 0..1);
328        }
329        // Frame auto-submits on drop
330    }
Source

pub fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'_>)

Set a vertex buffer.

Examples found in repository?
examples/sprite_sheet.rs (line 462)
431    fn render(
432        &mut self,
433        _ctx: &mut astrelis_winit::app::AppCtx,
434        window_id: WindowId,
435        events: &mut astrelis_winit::event::EventBatch,
436    ) {
437        let Some(window) = self.windows.get_mut(&window_id) else {
438            return;
439        };
440
441        // Handle resize
442        events.dispatch(|event| {
443            if let astrelis_winit::event::Event::WindowResized(size) = event {
444                window.resized(*size);
445                astrelis_winit::event::HandleStatus::consumed()
446            } else {
447                astrelis_winit::event::HandleStatus::ignored()
448            }
449        });
450
451        let Some(frame) = window.begin_frame() else {
452            return; // Surface not available
453        };
454        {
455            let mut pass = frame
456                .render_pass()
457                .clear_color(Color::rgb(0.1, 0.1, 0.15))
458                .label("sprite_sheet_pass")
459                .build();
460            pass.set_pipeline(&self.pipeline);
461            pass.set_bind_group(0, &self.bind_group, &[]);
462            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
463            pass.draw(0..6, 0..1);
464        }
465        // Frame auto-submits on drop
466    }
More examples
Hide additional examples
examples/image_blitting.rs (line 518)
486    fn render(
487        &mut self,
488        _ctx: &mut astrelis_winit::app::AppCtx,
489        window_id: WindowId,
490        events: &mut astrelis_winit::event::EventBatch,
491    ) {
492        let Some(window) = self.windows.get_mut(&window_id) else {
493            return;
494        };
495
496        // Handle resize
497        events.dispatch(|event| {
498            if let astrelis_winit::event::Event::WindowResized(size) = event {
499                window.resized(*size);
500                astrelis_winit::event::HandleStatus::consumed()
501            } else {
502                astrelis_winit::event::HandleStatus::ignored()
503            }
504        });
505
506        let Some(frame) = window.begin_frame() else {
507            return; // Surface not available
508        };
509
510        {
511            let mut pass = frame
512                .render_pass()
513                .clear_color(Color::rgb(0.05, 0.05, 0.08))
514                .label("image_blitting_pass")
515                .build();
516            pass.set_pipeline(&self.pipeline);
517            pass.set_bind_group(0, &self.bind_group, &[]);
518            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
519            pass.draw(0..6, 0..1);
520        }
521        // Frame auto-submits on drop
522    }
examples/textured_window.rs (line 293)
260    fn render(
261        &mut self,
262        _ctx: &mut astrelis_winit::app::AppCtx,
263        window_id: WindowId,
264        events: &mut astrelis_winit::event::EventBatch,
265    ) {
266        if window_id != self.window_id {
267            return;
268        }
269
270        // Handle window resize events
271        events.dispatch(|event| {
272            if let astrelis_winit::event::Event::WindowResized(size) = event {
273                self.window.resized(*size);
274                astrelis_winit::event::HandleStatus::consumed()
275            } else {
276                astrelis_winit::event::HandleStatus::ignored()
277            }
278        });
279
280        // --- Render Loop ---
281        let Some(frame) = self.window.begin_frame() else {
282            return; // Surface not available
283        };
284
285        {
286            let mut pass = frame
287                .render_pass()
288                .clear_color(Color::rgb(0.1, 0.2, 0.3))
289                .label("textured_window_pass")
290                .build();
291            pass.set_pipeline(&self.pipeline);
292            pass.set_bind_group(0, &self.bind_group, &[]);
293            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
294            pass.draw(0..6, 0..1);
295        }
296        // Frame auto-submits on drop
297    }
examples/renderer_api.rs (line 313)
284    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
285        if window_id != self.window_id {
286            return;
287        }
288
289        // Handle window-specific resize events
290        events.dispatch(|event| {
291            if let astrelis_winit::event::Event::WindowResized(size) = event {
292                self.window.resized(*size);
293                astrelis_winit::event::HandleStatus::consumed()
294            } else {
295                astrelis_winit::event::HandleStatus::ignored()
296            }
297        });
298
299        let Some(frame) = self.window.begin_frame() else {
300            return; // Surface not available
301        };
302
303        // Pass 1: Render to offscreen framebuffer
304        {
305            let mut pass = frame
306                .render_pass()
307                .target(RenderTarget::Framebuffer(&self.offscreen_fb))
308                .clear_color(Color::rgb(0.2, 0.1, 0.3))
309                .label("offscreen_pass")
310                .build();
311            pass.set_pipeline(&self.pipeline);
312            pass.set_bind_group(0, &self.bind_group, &[]);
313            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
314            pass.draw(0..6, 0..1);
315        }
316
317        // Pass 2: Blit framebuffer to surface
318        {
319            let mut pass = frame
320                .render_pass()
321                .clear_color(Color::rgb(0.1, 0.2, 0.3))
322                .label("blit_pass")
323                .build();
324            pass.set_pipeline(&self.blit_pipeline);
325            pass.set_bind_group(0, &self.blit_bind_group, &[]);
326            // Draw fullscreen triangle
327            pass.draw(0..3, 0..1);
328        }
329        // Frame auto-submits on drop
330    }
Source

pub fn set_index_buffer( &mut self, buffer_slice: BufferSlice<'_>, format: IndexFormat, )

Set the index buffer.

Source

pub fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>)

Draw primitives.

Examples found in repository?
examples/sprite_sheet.rs (line 463)
431    fn render(
432        &mut self,
433        _ctx: &mut astrelis_winit::app::AppCtx,
434        window_id: WindowId,
435        events: &mut astrelis_winit::event::EventBatch,
436    ) {
437        let Some(window) = self.windows.get_mut(&window_id) else {
438            return;
439        };
440
441        // Handle resize
442        events.dispatch(|event| {
443            if let astrelis_winit::event::Event::WindowResized(size) = event {
444                window.resized(*size);
445                astrelis_winit::event::HandleStatus::consumed()
446            } else {
447                astrelis_winit::event::HandleStatus::ignored()
448            }
449        });
450
451        let Some(frame) = window.begin_frame() else {
452            return; // Surface not available
453        };
454        {
455            let mut pass = frame
456                .render_pass()
457                .clear_color(Color::rgb(0.1, 0.1, 0.15))
458                .label("sprite_sheet_pass")
459                .build();
460            pass.set_pipeline(&self.pipeline);
461            pass.set_bind_group(0, &self.bind_group, &[]);
462            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
463            pass.draw(0..6, 0..1);
464        }
465        // Frame auto-submits on drop
466    }
More examples
Hide additional examples
examples/image_blitting.rs (line 519)
486    fn render(
487        &mut self,
488        _ctx: &mut astrelis_winit::app::AppCtx,
489        window_id: WindowId,
490        events: &mut astrelis_winit::event::EventBatch,
491    ) {
492        let Some(window) = self.windows.get_mut(&window_id) else {
493            return;
494        };
495
496        // Handle resize
497        events.dispatch(|event| {
498            if let astrelis_winit::event::Event::WindowResized(size) = event {
499                window.resized(*size);
500                astrelis_winit::event::HandleStatus::consumed()
501            } else {
502                astrelis_winit::event::HandleStatus::ignored()
503            }
504        });
505
506        let Some(frame) = window.begin_frame() else {
507            return; // Surface not available
508        };
509
510        {
511            let mut pass = frame
512                .render_pass()
513                .clear_color(Color::rgb(0.05, 0.05, 0.08))
514                .label("image_blitting_pass")
515                .build();
516            pass.set_pipeline(&self.pipeline);
517            pass.set_bind_group(0, &self.bind_group, &[]);
518            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
519            pass.draw(0..6, 0..1);
520        }
521        // Frame auto-submits on drop
522    }
examples/textured_window.rs (line 294)
260    fn render(
261        &mut self,
262        _ctx: &mut astrelis_winit::app::AppCtx,
263        window_id: WindowId,
264        events: &mut astrelis_winit::event::EventBatch,
265    ) {
266        if window_id != self.window_id {
267            return;
268        }
269
270        // Handle window resize events
271        events.dispatch(|event| {
272            if let astrelis_winit::event::Event::WindowResized(size) = event {
273                self.window.resized(*size);
274                astrelis_winit::event::HandleStatus::consumed()
275            } else {
276                astrelis_winit::event::HandleStatus::ignored()
277            }
278        });
279
280        // --- Render Loop ---
281        let Some(frame) = self.window.begin_frame() else {
282            return; // Surface not available
283        };
284
285        {
286            let mut pass = frame
287                .render_pass()
288                .clear_color(Color::rgb(0.1, 0.2, 0.3))
289                .label("textured_window_pass")
290                .build();
291            pass.set_pipeline(&self.pipeline);
292            pass.set_bind_group(0, &self.bind_group, &[]);
293            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
294            pass.draw(0..6, 0..1);
295        }
296        // Frame auto-submits on drop
297    }
examples/renderer_api.rs (line 314)
284    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
285        if window_id != self.window_id {
286            return;
287        }
288
289        // Handle window-specific resize events
290        events.dispatch(|event| {
291            if let astrelis_winit::event::Event::WindowResized(size) = event {
292                self.window.resized(*size);
293                astrelis_winit::event::HandleStatus::consumed()
294            } else {
295                astrelis_winit::event::HandleStatus::ignored()
296            }
297        });
298
299        let Some(frame) = self.window.begin_frame() else {
300            return; // Surface not available
301        };
302
303        // Pass 1: Render to offscreen framebuffer
304        {
305            let mut pass = frame
306                .render_pass()
307                .target(RenderTarget::Framebuffer(&self.offscreen_fb))
308                .clear_color(Color::rgb(0.2, 0.1, 0.3))
309                .label("offscreen_pass")
310                .build();
311            pass.set_pipeline(&self.pipeline);
312            pass.set_bind_group(0, &self.bind_group, &[]);
313            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
314            pass.draw(0..6, 0..1);
315        }
316
317        // Pass 2: Blit framebuffer to surface
318        {
319            let mut pass = frame
320                .render_pass()
321                .clear_color(Color::rgb(0.1, 0.2, 0.3))
322                .label("blit_pass")
323                .build();
324            pass.set_pipeline(&self.blit_pipeline);
325            pass.set_bind_group(0, &self.blit_bind_group, &[]);
326            // Draw fullscreen triangle
327            pass.draw(0..3, 0..1);
328        }
329        // Frame auto-submits on drop
330    }
Source

pub fn draw_indexed( &mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>, )

Draw indexed primitives.

Source

pub fn insert_debug_marker(&mut self, label: &str)

Insert a debug marker.

Source

pub fn push_debug_group(&mut self, label: &str)

Push a debug group.

Source

pub fn pop_debug_group(&mut self)

Pop a debug group.

Source

pub fn set_push_constants<T: Pod>( &mut self, stages: ShaderStages, offset: u32, data: &T, )

Set push constants.

Source

pub fn set_push_constants_raw( &mut self, stages: ShaderStages, offset: u32, data: &[u8], )

Set push constants from raw bytes.

Trait Implementations§

Source§

impl<'a> AsWgpu for RenderPass<'a>

Source§

type WgpuType = RenderPass<'static>

The underlying wgpu type.
Source§

fn as_wgpu(&self) -> &Self::WgpuType

Get a reference to the underlying wgpu type.
Source§

impl<'a> AsWgpuMut for RenderPass<'a>

Source§

fn as_wgpu_mut(&mut self) -> &mut Self::WgpuType

Get a mutable reference to the underlying wgpu type.
Source§

impl Drop for RenderPass<'_>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'f> Freeze for RenderPass<'f>

§

impl<'f> !RefUnwindSafe for RenderPass<'f>

§

impl<'f> !Send for RenderPass<'f>

§

impl<'f> !Sync for RenderPass<'f>

§

impl<'f> Unpin for RenderPass<'f>

§

impl<'f> UnsafeUnpin for RenderPass<'f>

§

impl<'f> !UnwindSafe for RenderPass<'f>

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