Skip to main content

RenderWindow

Struct RenderWindow 

Source
pub struct RenderWindow { /* private fields */ }
Expand description

A renderable window that combines a winit Window with a WindowContext.

This is the primary type for rendering to a window. It implements Deref<Target = WindowContext>, so all WindowContext methods are available directly.

§GPU Profiling

Attach a GpuFrameProfiler via set_gpu_profiler to automatically profile render passes. Once attached, all frames created via begin_frame will include GPU profiling.

§Example

let mut render_window = RenderWindow::builder()
    .with_depth_default()
    .build(window, graphics)
    .expect("Failed to create window");

// In render loop:
let frame = render_window.begin_frame().expect("Surface available");
{
    let mut pass = frame.render_pass()
        .clear_color(Color::BLACK)
        .with_window_depth()
        .clear_depth(0.0)
        .build();
    // Render commands...
}
// Frame auto-submits on drop

Implementations§

Source§

impl RenderWindow

Source

pub fn builder() -> RenderWindowBuilder

Create a new builder for configuring a render window.

Source

pub fn new( window: Window, context: Arc<GraphicsContext>, ) -> Result<Self, GraphicsError>

Create a new renderable window with default settings.

Source

pub fn new_with_depth( window: Window, context: Arc<GraphicsContext>, ) -> Result<Self, GraphicsError>

Create a new renderable window with an auto-resizing depth texture.

This is equivalent to using builder() with with_depth_default().

Source

pub fn new_with_descriptor( window: Window, context: Arc<GraphicsContext>, descriptor: WindowContextDescriptor, ) -> Result<Self, GraphicsError>

Create a new renderable window with a descriptor.

Source

pub fn begin_frame(&mut self) -> Option<Frame<'_>>

Begin a new frame for rendering.

Returns Some(Frame) if the surface is available, or None if the surface is temporarily unavailable (e.g., window minimized).

§Example
if let Some(frame) = window.begin_frame() {
    let mut pass = frame.render_pass()
        .clear_color(Color::BLACK)
        .build();
    // Render commands...
}
Examples found in repository?
examples/camera_demo.rs (line 103)
89    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
90        if window_id != self.window_id {
91            return;
92        }
93
94        events.dispatch(|event| {
95            if let astrelis_winit::event::Event::WindowResized(size) = event {
96                self.window.resized(*size);
97                astrelis_winit::event::HandleStatus::consumed()
98            } else {
99                astrelis_winit::event::HandleStatus::ignored()
100            }
101        });
102
103        let Some(frame) = self.window.begin_frame() else {
104            return; // Surface not available
105        };
106        {
107            let _pass = frame
108                .render_pass()
109                .clear_color(Color::from_rgb_u8(20, 30, 40))
110                .label("camera_demo_pass")
111                .build();
112        }
113        // Frame auto-submits on drop
114    }
More examples
Hide additional examples
examples/mesh_primitives.rs (line 105)
91    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
92        if window_id != self.window_id {
93            return;
94        }
95
96        events.dispatch(|event| {
97            if let astrelis_winit::event::Event::WindowResized(size) = event {
98                self.window.resized(*size);
99                astrelis_winit::event::HandleStatus::consumed()
100            } else {
101                astrelis_winit::event::HandleStatus::ignored()
102            }
103        });
104
105        let Some(frame) = self.window.begin_frame() else {
106            return; // Surface not available
107        };
108        {
109            let _pass = frame
110                .render_pass()
111                .clear_color(Color::from_rgb_u8(20, 30, 40))
112                .label("mesh_primitives_pass")
113                .build();
114        }
115        // Frame auto-submits on drop
116    }
examples/render_graph_demo.rs (line 103)
89    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
90        if window_id != self.window_id {
91            return;
92        }
93
94        events.dispatch(|event| {
95            if let astrelis_winit::event::Event::WindowResized(size) = event {
96                self.window.resized(*size);
97                astrelis_winit::event::HandleStatus::consumed()
98            } else {
99                astrelis_winit::event::HandleStatus::ignored()
100            }
101        });
102
103        let Some(frame) = self.window.begin_frame() else {
104            return; // Surface not available
105        };
106        {
107            let _pass = frame
108                .render_pass()
109                .clear_color(Color::from_rgb_u8(20, 30, 40))
110                .label("render_graph_demo_pass")
111                .build();
112        }
113        // Frame auto-submits on drop
114    }
examples/window_manager_demo.rs (line 102)
86    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
87        // Get the color for this window
88        let Some(&color) = self.window_colors.get(&window_id) else {
89            return;
90        };
91
92        // WindowManager automatically handles:
93        // 1. Window lookup (no manual HashMap.get_mut)
94        // 2. Resize events (automatic)
95        // 3. Event dispatching
96        self.window_manager
97            .render_window(window_id, events, |window, _events| {
98                // No need to manually handle resize events!
99                // WindowManager already did that for us
100
101                // Just render!
102                let Some(frame) = window.begin_frame() else {
103                    return; // Surface not available
104                };
105
106                {
107                    let _pass = frame
108                        .render_pass()
109                        .clear_color(color)
110                        .label("window_manager_pass")
111                        .build();
112                    // Additional rendering would go here
113                }
114                // Frame auto-submits on drop
115            });
116    }
examples/material_system.rs (line 125)
105    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
106        if window_id != self.window_id {
107            return;
108        }
109
110        // Handle resize
111        events.dispatch(|event| {
112            if let astrelis_winit::event::Event::WindowResized(size) = event {
113                self.window.resized(*size);
114                astrelis_winit::event::HandleStatus::consumed()
115            } else {
116                astrelis_winit::event::HandleStatus::ignored()
117            }
118        });
119
120        // In a real application, materials would be bound during rendering:
121        // material.bind(&mut render_pass);
122        // draw_mesh(&mesh);
123
124        // Begin frame
125        let Some(frame) = self.window.begin_frame() else {
126            return; // Surface not available
127        };
128
129        {
130            let _pass = frame
131                .render_pass()
132                .clear_color(Color::from_rgb_u8(20, 30, 40))
133                .label("material_system_pass")
134                .build();
135            // Materials would be applied here in actual rendering
136            // This is a conceptual demonstration
137        }
138        // Frame auto-submits on drop
139    }
examples/sprite_sheet.rs (line 451)
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    }
Source

pub fn try_begin_frame(&mut self) -> Result<Frame<'_>, GraphicsError>

Try to begin a new frame, returning an error on failure.

Unlike begin_frame, this returns the actual error for debugging or error handling.

Source

pub fn id(&self) -> WindowId

Get the window ID.

Examples found in repository?
examples/multi_window.rs (line 71)
25fn main() {
26    logging::init();
27
28    run_app(|ctx| {
29        let graphics_ctx =
30            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
31
32        let mut windows = HashMap::new();
33
34        // Create 3 windows with different colors
35        let colors = [
36            wgpu::Color {
37                r: 0.8,
38                g: 0.2,
39                b: 0.2,
40                a: 1.0,
41            },
42            wgpu::Color {
43                r: 0.2,
44                g: 0.8,
45                b: 0.2,
46                a: 1.0,
47            },
48            wgpu::Color {
49                r: 0.2,
50                g: 0.2,
51                b: 0.8,
52                a: 1.0,
53            },
54        ];
55
56        for (i, color) in colors.iter().enumerate() {
57            let window = ctx
58                .create_window(WindowDescriptor {
59                    title: format!("Window {} - Multi-Window Example", i + 1),
60                    size: Some(WinitPhysicalSize::new(400.0, 300.0)),
61                    ..Default::default()
62                })
63                .expect("Failed to create window");
64
65            let renderable_window = RenderWindowBuilder::new()
66                .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
67                .with_depth_default()
68                .build(window, graphics_ctx.clone())
69                .expect("Failed to create render window");
70
71            let window_id = renderable_window.id();
72            windows.insert(window_id, (renderable_window, *color));
73        }
74
75        Box::new(App { windows })
76    });
77}
More examples
Hide additional examples
examples/performance_benchmark.rs (line 57)
36fn main() {
37    logging::init();
38
39    run_app(|ctx| {
40        let graphics_ctx =
41            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
42
43        let window = ctx
44            .create_window(WindowDescriptor {
45                title: "Performance Benchmark - Render Stress Test".to_string(),
46                size: Some(WinitPhysicalSize::new(1280.0, 720.0)),
47                ..Default::default()
48            })
49            .expect("Failed to create window");
50
51        let window = RenderWindowBuilder::new()
52            .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
53            .with_depth_default()
54            .build(window, graphics_ctx.clone())
55            .expect("Failed to create render window");
56
57        let window_id = window.id();
58
59        println!("\n═══════════════════════════════════════════════════════");
60        println!("  ⚡ PERFORMANCE BENCHMARK - Render Stress Test");
61        println!("═══════════════════════════════════════════════════════");
62        println!("  CONTROLS:");
63        println!("    [Space]  Toggle rendering on/off");
64        println!("    [+/-]    Increase/decrease object count");
65        println!("  Starting with 1000 objects");
66        println!("═══════════════════════════════════════════════════════\n");
67
68        Box::new(PerformanceBenchmark {
69            _context: graphics_ctx,
70            window,
71            window_id,
72            object_count: 1000,
73            rendering: true,
74            frame_count: 0,
75            last_fps_time: Instant::now(),
76            fps: 0.0,
77            last_frame_time: 0.0,
78        })
79    });
80}
examples/camera_demo.rs (line 51)
30fn main() {
31    logging::init();
32
33    run_app(|ctx| {
34        let graphics_ctx =
35            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
36
37        let window = ctx
38            .create_window(WindowDescriptor {
39                title: "Camera Demo - View & Projection".to_string(),
40                size: Some(WinitPhysicalSize::new(1024.0, 768.0)),
41                ..Default::default()
42            })
43            .expect("Failed to create window");
44
45        let window = RenderWindowBuilder::new()
46            .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
47            .with_depth_default()
48            .build(window, graphics_ctx.clone())
49            .expect("Failed to create render window");
50
51        let window_id = window.id();
52
53        println!("\n═══════════════════════════════════════════════════════");
54        println!("  📹 CAMERA DEMO - View & Projection");
55        println!("═══════════════════════════════════════════════════════");
56        println!("\n  CAMERA API FEATURES:");
57        println!("    • Orthographic cameras (2D, UI, isometric)");
58        println!("    • Perspective cameras (3D scenes)");
59        println!("    • View matrix (position, rotation, look-at)");
60        println!("    • Projection matrix (FOV, aspect, near/far planes)");
61        println!("    • Screen-to-world coordinate conversion");
62        println!("    • Camera movement helpers");
63        println!("\n  CAMERA TYPES:");
64        println!("    • OrthographicCamera - 2D games, UI overlays");
65        println!("      camera.orthographic(left, right, bottom, top, near, far)");
66        println!("    • PerspectiveCamera - 3D scenes");
67        println!("      camera.perspective(fov, aspect, near, far)");
68        println!("\n  Camera API Usage:");
69        println!("    let camera = Camera::new()");
70        println!("        .position(Vec3::new(0.0, 5.0, 10.0))");
71        println!("        .look_at(Vec3::ZERO)");
72        println!("        .perspective(60.0, aspect, 0.1, 100.0);");
73        println!("    let view_proj = camera.view_projection_matrix();");
74        println!("═══════════════════════════════════════════════════════\n");
75
76        tracing::info!("Camera demo initialized");
77
78        Box::new(CameraDemo {
79            _context: graphics_ctx,
80            window,
81            window_id,
82        })
83    });
84}
examples/render_graph_demo.rs (line 50)
29fn main() {
30    logging::init();
31
32    run_app(|ctx| {
33        let graphics_ctx =
34            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
35
36        let window = ctx
37            .create_window(WindowDescriptor {
38                title: "Render Graph Demo - Multi-Pass Rendering".to_string(),
39                size: Some(WinitPhysicalSize::new(1024.0, 768.0)),
40                ..Default::default()
41            })
42            .expect("Failed to create window");
43
44        let window = RenderWindowBuilder::new()
45            .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
46            .with_depth_default()
47            .build(window, graphics_ctx.clone())
48            .expect("Failed to create render window");
49
50        let window_id = window.id();
51
52        println!("\n═══════════════════════════════════════════════════════");
53        println!("  🔀 RENDER GRAPH DEMO - Multi-Pass Rendering");
54        println!("═══════════════════════════════════════════════════════");
55        println!("\n  RENDER GRAPH FEATURES:");
56        println!("    • Declarative pass definition");
57        println!("    • Automatic dependency resolution");
58        println!("    • Resource lifetime management");
59        println!("    • Parallel pass execution");
60        println!("    • Automatic optimization");
61        println!("\n  EXAMPLE PIPELINE:");
62        println!("    1. Shadow Pass → depth texture");
63        println!("    2. Geometry Pass → color + normal + depth");
64        println!("    3. Lighting Pass → lit scene");
65        println!("    4. Post-Processing → bloom, tone mapping");
66        println!("    5. UI Pass → final composite");
67        println!("\n  Render Graph API Usage:");
68        println!("    let mut graph = RenderGraph::new();");
69        println!("    graph.add_pass(\"shadow\", shadow_pass_descriptor);");
70        println!("    graph.add_pass(\"geometry\", geometry_pass_descriptor);");
71        println!("    graph.add_dependency(\"lighting\", \"geometry\");");
72        println!("    graph.compile();");
73        println!("    graph.execute(&mut encoder);");
74        println!("═══════════════════════════════════════════════════════\n");
75
76        tracing::info!("Render graph demo initialized");
77
78        Box::new(RenderGraphDemo {
79            _context: graphics_ctx,
80            window,
81            window_id,
82        })
83    });
84}
examples/mesh_primitives.rs (line 50)
29fn main() {
30    logging::init();
31
32    run_app(|ctx| {
33        let graphics_ctx =
34            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
35
36        let window = ctx
37            .create_window(WindowDescriptor {
38                title: "Mesh Primitives Demo - Geometry API".to_string(),
39                size: Some(WinitPhysicalSize::new(1024.0, 768.0)),
40                ..Default::default()
41            })
42            .expect("Failed to create window");
43
44        let window = RenderWindowBuilder::new()
45            .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
46            .with_depth_default()
47            .build(window, graphics_ctx.clone())
48            .expect("Failed to create render window");
49
50        let window_id = window.id();
51
52        println!("\n═══════════════════════════════════════════════════════");
53        println!("  📐 MESH PRIMITIVES DEMO - Geometry API");
54        println!("═══════════════════════════════════════════════════════");
55        println!("\n  MESH API FEATURES:");
56        println!("    • MeshBuilder for custom geometry");
57        println!("    • Primitive generation (cube, sphere, plane, etc.)");
58        println!("    • Flexible vertex formats (Position, Normal, UV, Color)");
59        println!("    • Index buffer optimization");
60        println!("    • Instanced rendering support");
61        println!("\n  EXAMPLE PRIMITIVES:");
62        println!("    • Cube - box with 24 vertices (6 faces × 4 vertices)");
63        println!("    • Sphere - tessellated sphere with UV mapping");
64        println!("    • Plane - quad with optional subdivisions");
65        println!("    • Cylinder - sides + caps");
66        println!("    • Custom - arbitrary vertex/index data");
67        println!("\n  Mesh API Usage:");
68        println!("    let mesh = MeshBuilder::new()");
69        println!("        .with_positions(vertices)");
70        println!("        .with_normals(normals)");
71        println!("        .with_uvs(uvs)");
72        println!("        .with_indices(indices)");
73        println!("        .build(&ctx);");
74        println!("    mesh.draw(&mut pass);");
75        println!("    mesh.draw_instanced(&mut pass, instance_count);");
76        println!("═══════════════════════════════════════════════════════\n");
77
78        tracing::info!("Mesh primitives demo initialized");
79
80        Box::new(MeshPrimitivesDemo {
81            _context: graphics_ctx,
82            window,
83            window_id,
84        })
85    });
86}
examples/batched_renderer.rs (line 319)
278fn main() {
279    logging::init();
280
281    run_app(|ctx| {
282        let tier_override = parse_tier();
283
284        // Use the capability API to configure GPU requirements.
285        // For auto-detect, request the best capability (graceful degradation).
286        // For a specific tier, require that tier's capability.
287        let descriptor = match tier_override {
288            None => GraphicsContextDescriptor::new().request_capability::<BestBatchCapability2D>(),
289            Some(RenderTier::Direct) => {
290                GraphicsContextDescriptor::new().require_capability::<DirectBatchCapability2D>()
291            }
292            Some(RenderTier::Indirect) => {
293                GraphicsContextDescriptor::new().require_capability::<IndirectBatchCapability2D>()
294            }
295            Some(RenderTier::Bindless) => {
296                GraphicsContextDescriptor::new().require_capability::<BindlessBatchCapability2D>()
297            }
298        };
299        let graphics_ctx =
300            pollster::block_on(GraphicsContext::new_owned_with_descriptor(descriptor))
301                .expect("Failed to create graphics context");
302
303        let window = ctx
304            .create_window(WindowDescriptor {
305                title: "Batched Renderer Example".to_string(),
306                size: Some(WinitPhysicalSize::new(800.0, 600.0)),
307                ..Default::default()
308            })
309            .expect("Failed to create window");
310
311        let surface_format = wgpu::TextureFormat::Bgra8UnormSrgb;
312
313        let renderable_window = RenderWindowBuilder::new()
314            .color_format(surface_format)
315            .with_depth_default()
316            .build(window, graphics_ctx.clone())
317            .expect("Failed to create render window");
318
319        let window_id = renderable_window.id();
320
321        let renderer =
322            create_batch_renderer_2d(graphics_ctx.clone(), surface_format, tier_override);
323
324        tracing::info!("Using render tier: {}", renderer.tier());
325
326        // Create initial depth buffer
327        let depth_texture = graphics_ctx
328            .device()
329            .create_texture(&wgpu::TextureDescriptor {
330                label: Some("example_depth"),
331                size: wgpu::Extent3d {
332                    width: 1,
333                    height: 1,
334                    depth_or_array_layers: 1,
335                },
336                mip_level_count: 1,
337                sample_count: 1,
338                dimension: wgpu::TextureDimension::D2,
339                format: DEPTH_FORMAT,
340                usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
341                view_formats: &[],
342            });
343        let depth_view = depth_texture.create_view(&wgpu::TextureViewDescriptor::default());
344
345        let mut windows = HashMap::new();
346        windows.insert(window_id, renderable_window);
347
348        Box::new(App {
349            context: graphics_ctx,
350            windows,
351            renderer,
352            depth_texture,
353            depth_view,
354            depth_width: 1,
355            depth_height: 1,
356            frame_count: 0,
357        })
358    });
359}
Source

pub fn window(&self) -> &Window

Get the underlying window.

Source

pub fn context(&self) -> &WindowContext

Get the window context.

Examples found in repository?
examples/sprite_sheet.rs (line 422)
404    fn update(
405        &mut self,
406        _ctx: &mut astrelis_winit::app::AppCtx,
407        _time: &astrelis_winit::FrameTime,
408    ) {
409        let now = Instant::now();
410        let dt = now.duration_since(self.last_update).as_secs_f32();
411        self.last_update = now;
412
413        // Update animation
414        if self.animation.update(dt) {
415            // Frame changed - update vertex buffer with new UVs
416            let frame = self.animation.current_frame();
417            let uv = self.sprite_sheet.sprite_uv(frame);
418            let vertices = create_quad_vertices(uv.u_min, uv.v_min, uv.u_max, uv.v_max);
419
420            // Get context from first window
421            if let Some(window) = self.windows.values().next() {
422                window.context().graphics_context().queue().write_buffer(
423                    &self.vertex_buffer,
424                    0,
425                    bytemuck::cast_slice(&vertices),
426                );
427            }
428        }
429    }
Source

pub fn context_mut(&mut self) -> &mut WindowContext

Get mutable access to the window context.

Source

pub fn graphics(&self) -> &GraphicsContext

Get the graphics context.

Source

pub fn graphics_arc(&self) -> &Arc<GraphicsContext>

Get the Arc-wrapped graphics context.

Source

pub fn surface_format(&self) -> TextureFormat

Get the surface texture format.

Source

pub fn resized(&mut self, new_size: LogicalSize<u32>)

Handle window resize event (logical size).

Examples found in repository?
examples/camera_demo.rs (line 96)
89    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
90        if window_id != self.window_id {
91            return;
92        }
93
94        events.dispatch(|event| {
95            if let astrelis_winit::event::Event::WindowResized(size) = event {
96                self.window.resized(*size);
97                astrelis_winit::event::HandleStatus::consumed()
98            } else {
99                astrelis_winit::event::HandleStatus::ignored()
100            }
101        });
102
103        let Some(frame) = self.window.begin_frame() else {
104            return; // Surface not available
105        };
106        {
107            let _pass = frame
108                .render_pass()
109                .clear_color(Color::from_rgb_u8(20, 30, 40))
110                .label("camera_demo_pass")
111                .build();
112        }
113        // Frame auto-submits on drop
114    }
More examples
Hide additional examples
examples/mesh_primitives.rs (line 98)
91    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
92        if window_id != self.window_id {
93            return;
94        }
95
96        events.dispatch(|event| {
97            if let astrelis_winit::event::Event::WindowResized(size) = event {
98                self.window.resized(*size);
99                astrelis_winit::event::HandleStatus::consumed()
100            } else {
101                astrelis_winit::event::HandleStatus::ignored()
102            }
103        });
104
105        let Some(frame) = self.window.begin_frame() else {
106            return; // Surface not available
107        };
108        {
109            let _pass = frame
110                .render_pass()
111                .clear_color(Color::from_rgb_u8(20, 30, 40))
112                .label("mesh_primitives_pass")
113                .build();
114        }
115        // Frame auto-submits on drop
116    }
examples/render_graph_demo.rs (line 96)
89    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
90        if window_id != self.window_id {
91            return;
92        }
93
94        events.dispatch(|event| {
95            if let astrelis_winit::event::Event::WindowResized(size) = event {
96                self.window.resized(*size);
97                astrelis_winit::event::HandleStatus::consumed()
98            } else {
99                astrelis_winit::event::HandleStatus::ignored()
100            }
101        });
102
103        let Some(frame) = self.window.begin_frame() else {
104            return; // Surface not available
105        };
106        {
107            let _pass = frame
108                .render_pass()
109                .clear_color(Color::from_rgb_u8(20, 30, 40))
110                .label("render_graph_demo_pass")
111                .build();
112        }
113        // Frame auto-submits on drop
114    }
examples/material_system.rs (line 113)
105    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
106        if window_id != self.window_id {
107            return;
108        }
109
110        // Handle resize
111        events.dispatch(|event| {
112            if let astrelis_winit::event::Event::WindowResized(size) = event {
113                self.window.resized(*size);
114                astrelis_winit::event::HandleStatus::consumed()
115            } else {
116                astrelis_winit::event::HandleStatus::ignored()
117            }
118        });
119
120        // In a real application, materials would be bound during rendering:
121        // material.bind(&mut render_pass);
122        // draw_mesh(&mesh);
123
124        // Begin frame
125        let Some(frame) = self.window.begin_frame() else {
126            return; // Surface not available
127        };
128
129        {
130            let _pass = frame
131                .render_pass()
132                .clear_color(Color::from_rgb_u8(20, 30, 40))
133                .label("material_system_pass")
134                .build();
135            // Materials would be applied here in actual rendering
136            // This is a conceptual demonstration
137        }
138        // Frame auto-submits on drop
139    }
examples/sprite_sheet.rs (line 444)
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    }
examples/image_blitting.rs (line 499)
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    }
Source

pub fn resized_physical(&mut self, new_size: PhysicalSize<u32>)

Handle window resize event (physical size).

Source

pub fn physical_size(&self) -> PhysicalSize<u32>

Get the physical size of the window.

Examples found in repository?
examples/batched_renderer.rs (line 391)
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 size(&self) -> (u32, u32)

Get the surface size in pixels.

Source

pub fn scale_factor(&self) -> ScaleFactor

Get the scale factor.

Source

pub fn viewport(&self) -> Viewport

Get the viewport for this window.

Source

pub fn set_gpu_profiler(&mut self, profiler: Arc<GpuFrameProfiler>)

Attach a GPU profiler to this window.

Source

pub fn remove_gpu_profiler(&mut self) -> Option<Arc<GpuFrameProfiler>>

Remove the GPU profiler from this window.

Source

pub fn gpu_profiler(&self) -> Option<&Arc<GpuFrameProfiler>>

Get a reference to the GPU profiler, if attached.

Source

pub fn has_depth(&self) -> bool

Check if this window has a depth texture.

Source

pub fn depth_view(&self) -> Option<Arc<TextureView>>

Get the depth texture view if available (Arc-wrapped).

Source

pub fn depth_view_ref(&self) -> Option<&TextureView>

Get a reference to the depth texture view (without Arc).

Source

pub fn depth_format(&self) -> Option<TextureFormat>

Get the depth texture format, if depth is enabled.

Returns the format used for the depth texture, or None if depth is not enabled. Use this to configure renderers that need to match the depth format.

Source

pub fn ensure_depth(&mut self, format: TextureFormat)

Ensure a depth texture exists for this window.

Methods from Deref<Target = WindowContext>§

Source

pub fn resized(&mut self, new_size: LogicalSize<u32>)

Handle window resize event (logical size).

Source

pub fn resized_physical(&mut self, new_size: PhysicalSize<u32>)

Handle window resize event (physical size).

Source

pub fn window(&self) -> &Window

Source

pub fn graphics_context(&self) -> &GraphicsContext

Examples found in repository?
examples/sprite_sheet.rs (line 422)
404    fn update(
405        &mut self,
406        _ctx: &mut astrelis_winit::app::AppCtx,
407        _time: &astrelis_winit::FrameTime,
408    ) {
409        let now = Instant::now();
410        let dt = now.duration_since(self.last_update).as_secs_f32();
411        self.last_update = now;
412
413        // Update animation
414        if self.animation.update(dt) {
415            // Frame changed - update vertex buffer with new UVs
416            let frame = self.animation.current_frame();
417            let uv = self.sprite_sheet.sprite_uv(frame);
418            let vertices = create_quad_vertices(uv.u_min, uv.v_min, uv.u_max, uv.v_max);
419
420            // Get context from first window
421            if let Some(window) = self.windows.values().next() {
422                window.context().graphics_context().queue().write_buffer(
423                    &self.vertex_buffer,
424                    0,
425                    bytemuck::cast_slice(&vertices),
426                );
427            }
428        }
429    }
Source

pub fn surface(&self) -> &Surface<'static>

Source

pub fn surface_config(&self) -> &SurfaceConfiguration

Source

pub fn surface_format(&self) -> TextureFormat

Get the surface texture format.

This is the format that render pipelines must use when rendering to this window’s surface. Pass this to renderer constructors like LineRenderer::new.

Source

pub fn logical_size(&self) -> LogicalSize<u32>

Get the logical size of the window.

Source

pub fn physical_size(&self) -> PhysicalSize<u32>

Get the physical size of the window.

Source

pub fn logical_size_f32(&self) -> LogicalSize<f32>

Get the logical size as f32.

Source

pub fn physical_size_f32(&self) -> PhysicalSize<f32>

Get the physical size as f32.

Source

pub fn reconfigure_surface(&mut self, config: SurfaceConfiguration)

Reconfigure the surface with a new configuration.

Source

pub fn has_depth(&self) -> bool

Check if this window has a depth texture.

Source

pub fn depth_view(&self) -> Option<Arc<TextureView>>

Get the depth texture view if available.

Returns an Arc-wrapped view for cheap, lifetime-free sharing.

Source

pub fn depth_format(&self) -> Option<TextureFormat>

Get the depth texture format, if depth is enabled.

Returns the format used for the depth texture, or None if depth is not enabled. Use this to configure renderers that need to match the depth format.

Source

pub fn ensure_depth(&mut self, format: TextureFormat)

Ensure a depth texture exists for this window.

If no depth texture exists, creates one with the given format. If a depth texture already exists, this is a no-op.

Trait Implementations§

Source§

impl Deref for RenderWindow

Source§

type Target = WindowContext

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl DerefMut for RenderWindow

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl WindowBackend for RenderWindow

Source§

type FrameContext = Frame<'static>

Source§

type Error = GraphicsError

Source§

fn try_begin_drawing(&mut self) -> Result<Self::FrameContext, Self::Error>

Begin drawing a new frame. Read more
Source§

fn begin_drawing(&mut self) -> Self::FrameContext
where Self::Error: Debug,

Begin drawing a new frame, panicking on error. Read more

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> 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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
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,