RenderableWindow

Struct RenderableWindow 

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

A renderable window that combines a window with a rendering context.

Implementations§

Source§

impl RenderableWindow

Source

pub fn new(window: Window, context: &'static GraphicsContext) -> Self

Source

pub fn new_with_descriptor( window: Window, context: &'static GraphicsContext, descriptor: WindowContextDescriptor, ) -> Self

Examples found in repository?
examples/multi_window.rs (lines 67-74)
28fn main() {
29    logging::init();
30
31    run_app(|ctx| {
32        let graphics_ctx = GraphicsContext::new_sync();
33
34        let mut windows = HashMap::new();
35
36        // Create 3 windows with different colors
37        let colors = [
38            wgpu::Color {
39                r: 0.8,
40                g: 0.2,
41                b: 0.2,
42                a: 1.0,
43            },
44            wgpu::Color {
45                r: 0.2,
46                g: 0.8,
47                b: 0.2,
48                a: 1.0,
49            },
50            wgpu::Color {
51                r: 0.2,
52                g: 0.2,
53                b: 0.8,
54                a: 1.0,
55            },
56        ];
57
58        for (i, color) in colors.iter().enumerate() {
59            let window = ctx
60                .create_window(WindowDescriptor {
61                    title: format!("Window {} - Multi-Window Example", i + 1),
62                    size: Some(PhysicalSize::new(400.0, 300.0)),
63                    ..Default::default()
64                })
65                .expect("Failed to create window");
66
67            let renderable_window = RenderableWindow::new_with_descriptor(
68                window,
69                graphics_ctx,
70                WindowContextDescriptor {
71                    format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
72                    ..Default::default()
73                },
74            );
75
76            let window_id = renderable_window.id();
77            windows.insert(window_id, (renderable_window, *color));
78        }
79
80        Box::new(App {
81            context: graphics_ctx,
82            windows,
83        })
84    });
85}
More examples
Hide additional examples
examples/sprite_sheet.rs (lines 164-171)
148fn main() {
149    logging::init();
150
151    run_app(|ctx| {
152        let graphics_ctx = GraphicsContext::new_sync();
153        let mut windows = HashMap::new();
154
155        let scale = Window::platform_dpi() as f32;
156        let window = ctx
157            .create_window(WindowDescriptor {
158                title: "Sprite Sheet Animation Example".to_string(),
159                size: Some(PhysicalSize::new(400.0 * scale, 400.0 * scale)),
160                ..Default::default()
161            })
162            .expect("Failed to create window");
163
164        let renderable_window = RenderableWindow::new_with_descriptor(
165            window,
166            graphics_ctx,
167            WindowContextDescriptor {
168                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
169                ..Default::default()
170            },
171        );
172
173        let window_id = renderable_window.id();
174        windows.insert(window_id, renderable_window);
175
176        // Generate sprite sheet
177        let (sprite_data, tex_width, tex_height) = generate_sprite_sheet_data();
178        let sprite_sheet = SpriteSheet::from_data(
179            graphics_ctx,
180            &sprite_data,
181            tex_width,
182            tex_height,
183            SpriteSheetDescriptor {
184                sprite_width: 64,
185                sprite_height: 64,
186                columns: 4,
187                rows: 1,
188                ..Default::default()
189            },
190        );
191
192        // Create animation (4 frames at 8 fps)
193        let animation = SpriteAnimation::new(4, 8.0);
194
195        // Create shader module
196        let shader = graphics_ctx.device.create_shader_module(wgpu::ShaderModuleDescriptor {
197            label: Some("Sprite Shader"),
198            source: wgpu::ShaderSource::Wgsl(SHADER.into()),
199        });
200
201        // Create bind group layout
202        let bind_group_layout = graphics_ctx.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
203            label: Some("Sprite Bind Group Layout"),
204            entries: &[
205                wgpu::BindGroupLayoutEntry {
206                    binding: 0,
207                    visibility: wgpu::ShaderStages::VERTEX,
208                    ty: wgpu::BindingType::Buffer {
209                        ty: wgpu::BufferBindingType::Uniform,
210                        has_dynamic_offset: false,
211                        min_binding_size: None,
212                    },
213                    count: None,
214                },
215                wgpu::BindGroupLayoutEntry {
216                    binding: 1,
217                    visibility: wgpu::ShaderStages::FRAGMENT,
218                    ty: wgpu::BindingType::Texture {
219                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
220                        view_dimension: wgpu::TextureViewDimension::D2,
221                        multisampled: false,
222                    },
223                    count: None,
224                },
225                wgpu::BindGroupLayoutEntry {
226                    binding: 2,
227                    visibility: wgpu::ShaderStages::FRAGMENT,
228                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
229                    count: None,
230                },
231            ],
232        });
233
234        // Create pipeline layout
235        let pipeline_layout = graphics_ctx.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
236            label: Some("Sprite Pipeline Layout"),
237            bind_group_layouts: &[&bind_group_layout],
238            push_constant_ranges: &[],
239        });
240
241        // Create render pipeline
242        let pipeline = graphics_ctx.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
243            label: Some("Sprite Pipeline"),
244            layout: Some(&pipeline_layout),
245            vertex: wgpu::VertexState {
246                module: &shader,
247                entry_point: Some("vs_main"),
248                buffers: &[wgpu::VertexBufferLayout {
249                    array_stride: std::mem::size_of::<Vertex>() as u64,
250                    step_mode: wgpu::VertexStepMode::Vertex,
251                    attributes: &[
252                        wgpu::VertexAttribute {
253                            offset: 0,
254                            shader_location: 0,
255                            format: wgpu::VertexFormat::Float32x2,
256                        },
257                        wgpu::VertexAttribute {
258                            offset: 8,
259                            shader_location: 1,
260                            format: wgpu::VertexFormat::Float32x2,
261                        },
262                    ],
263                }],
264                compilation_options: wgpu::PipelineCompilationOptions::default(),
265            },
266            fragment: Some(wgpu::FragmentState {
267                module: &shader,
268                entry_point: Some("fs_main"),
269                targets: &[Some(wgpu::ColorTargetState {
270                    format: wgpu::TextureFormat::Bgra8UnormSrgb,
271                    blend: Some(wgpu::BlendState::ALPHA_BLENDING),
272                    write_mask: wgpu::ColorWrites::ALL,
273                })],
274                compilation_options: wgpu::PipelineCompilationOptions::default(),
275            }),
276            primitive: wgpu::PrimitiveState {
277                topology: wgpu::PrimitiveTopology::TriangleList,
278                ..Default::default()
279            },
280            depth_stencil: None,
281            multisample: wgpu::MultisampleState::default(),
282            multiview: None,
283            cache: None,
284        });
285
286        // Create uniform buffer
287        let uniforms = Uniforms {
288            mvp: [
289                [1.0, 0.0, 0.0, 0.0],
290                [0.0, 1.0, 0.0, 0.0],
291                [0.0, 0.0, 1.0, 0.0],
292                [0.0, 0.0, 0.0, 1.0],
293            ],
294        };
295        let uniform_buffer = graphics_ctx.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
296            label: Some("Uniform Buffer"),
297            contents: bytemuck::cast_slice(&[uniforms]),
298            usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
299        });
300
301        // Create sampler
302        let sampler = graphics_ctx.device.create_sampler(&wgpu::SamplerDescriptor {
303            label: Some("Sprite Sampler"),
304            mag_filter: wgpu::FilterMode::Linear,
305            min_filter: wgpu::FilterMode::Linear,
306            ..Default::default()
307        });
308
309        // Create bind group
310        let bind_group = graphics_ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
311            label: Some("Sprite Bind Group"),
312            layout: &bind_group_layout,
313            entries: &[
314                wgpu::BindGroupEntry {
315                    binding: 0,
316                    resource: uniform_buffer.as_entire_binding(),
317                },
318                wgpu::BindGroupEntry {
319                    binding: 1,
320                    resource: wgpu::BindingResource::TextureView(sprite_sheet.view()),
321                },
322                wgpu::BindGroupEntry {
323                    binding: 2,
324                    resource: wgpu::BindingResource::Sampler(&sampler),
325                },
326            ],
327        });
328
329        // Initial vertex buffer (will be updated each frame with new UVs)
330        let vertices = create_quad_vertices(0.0, 0.0, 1.0, 1.0);
331        let vertex_buffer = graphics_ctx.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
332            label: Some("Vertex Buffer"),
333            contents: bytemuck::cast_slice(&vertices),
334            usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
335        });
336
337        Box::new(App {
338            _context: graphics_ctx,
339            windows,
340            pipeline,
341            bind_group,
342            vertex_buffer,
343            uniform_buffer,
344            sprite_sheet,
345            animation,
346            last_update: Instant::now(),
347        })
348    });
349}
examples/textured_window.rs (lines 32-39)
19fn main() {
20    logging::init();
21
22    run_app(|ctx| {
23        let graphics_ctx = GraphicsContext::new_sync();
24
25        let window = ctx
26            .create_window(WindowDescriptor {
27                title: "Textured Window".to_string(),
28                ..Default::default()
29            })
30            .expect("Failed to create window");
31
32        let window = RenderableWindow::new_with_descriptor(
33            window,
34            graphics_ctx,
35            WindowContextDescriptor {
36                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
37                ..Default::default()
38            },
39        );
40
41        let shader = graphics_ctx
42            .device
43            .create_shader_module(wgpu::ShaderModuleDescriptor {
44                label: Some("Texture Shader"),
45                source: wgpu::ShaderSource::Wgsl(include_str!("textured_window.wgsl").into()),
46            });
47
48        let texture_size = wgpu::Extent3d {
49            width: 256,
50            height: 256,
51            depth_or_array_layers: 1,
52        };
53
54        let texture = graphics_ctx
55            .device
56            .create_texture(&wgpu::TextureDescriptor {
57                label: Some("Example Texture"),
58                size: texture_size,
59                mip_level_count: 1,
60                sample_count: 1,
61                dimension: wgpu::TextureDimension::D2,
62                format: wgpu::TextureFormat::Rgba8UnormSrgb,
63                usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
64                view_formats: &[],
65            });
66
67        let mut texture_data = vec![0u8; (256 * 256 * 4) as usize];
68        for y in 0..256 {
69            for x in 0..256 {
70                let idx = ((y * 256 + x) * 4) as usize;
71                texture_data[idx] = x as u8;
72                texture_data[idx + 1] = y as u8;
73                texture_data[idx + 2] = ((x + y) / 2) as u8;
74                texture_data[idx + 3] = 255;
75            }
76        }
77
78        graphics_ctx.queue.write_texture(
79            wgpu::TexelCopyTextureInfo {
80                texture: &texture,
81                mip_level: 0,
82                origin: wgpu::Origin3d::ZERO,
83                aspect: wgpu::TextureAspect::All,
84            },
85            &texture_data,
86            wgpu::TexelCopyBufferLayout {
87                offset: 0,
88                bytes_per_row: Some(256 * 4),
89                rows_per_image: Some(256),
90            },
91            texture_size,
92        );
93
94        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
95        let sampler = graphics_ctx
96            .device
97            .create_sampler(&wgpu::SamplerDescriptor {
98                address_mode_u: wgpu::AddressMode::ClampToEdge,
99                address_mode_v: wgpu::AddressMode::ClampToEdge,
100                address_mode_w: wgpu::AddressMode::ClampToEdge,
101                mag_filter: wgpu::FilterMode::Linear,
102                min_filter: wgpu::FilterMode::Nearest,
103                mipmap_filter: wgpu::FilterMode::Nearest,
104                ..Default::default()
105            });
106
107        let bind_group_layout =
108            graphics_ctx
109                .device
110                .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
111                    label: Some("Texture Bind Group Layout"),
112                    entries: &[
113                        wgpu::BindGroupLayoutEntry {
114                            binding: 0,
115                            visibility: wgpu::ShaderStages::FRAGMENT,
116                            ty: wgpu::BindingType::Texture {
117                                multisampled: false,
118                                view_dimension: wgpu::TextureViewDimension::D2,
119                                sample_type: wgpu::TextureSampleType::Float { filterable: true },
120                            },
121                            count: None,
122                        },
123                        wgpu::BindGroupLayoutEntry {
124                            binding: 1,
125                            visibility: wgpu::ShaderStages::FRAGMENT,
126                            ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
127                            count: None,
128                        },
129                    ],
130                });
131
132        let bind_group = graphics_ctx
133            .device
134            .create_bind_group(&wgpu::BindGroupDescriptor {
135                label: Some("Texture Bind Group"),
136                layout: &bind_group_layout,
137                entries: &[
138                    wgpu::BindGroupEntry {
139                        binding: 0,
140                        resource: wgpu::BindingResource::TextureView(&texture_view),
141                    },
142                    wgpu::BindGroupEntry {
143                        binding: 1,
144                        resource: wgpu::BindingResource::Sampler(&sampler),
145                    },
146                ],
147            });
148
149        let pipeline_layout =
150            graphics_ctx
151                .device
152                .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
153                    label: Some("Render Pipeline Layout"),
154                    bind_group_layouts: &[&bind_group_layout],
155                    push_constant_ranges: &[],
156                });
157
158        let pipeline =
159            graphics_ctx
160                .device
161                .create_render_pipeline(&wgpu::RenderPipelineDescriptor {
162                    label: Some("Render Pipeline"),
163                    layout: Some(&pipeline_layout),
164                    vertex: wgpu::VertexState {
165                        module: &shader,
166                        entry_point: Some("vs_main"),
167                        buffers: &[wgpu::VertexBufferLayout {
168                            array_stride: 4 * 4,
169                            step_mode: wgpu::VertexStepMode::Vertex,
170                            attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2],
171                        }],
172                        compilation_options: wgpu::PipelineCompilationOptions::default(),
173                    },
174                    fragment: Some(wgpu::FragmentState {
175                        module: &shader,
176                        entry_point: Some("fs_main"),
177                        targets: &[Some(wgpu::ColorTargetState {
178                            format: wgpu::TextureFormat::Bgra8UnormSrgb,
179                            blend: Some(wgpu::BlendState::REPLACE),
180                            write_mask: wgpu::ColorWrites::ALL,
181                        })],
182                        compilation_options: wgpu::PipelineCompilationOptions::default(),
183                    }),
184                    primitive: wgpu::PrimitiveState {
185                        topology: wgpu::PrimitiveTopology::TriangleList,
186                        strip_index_format: None,
187                        front_face: wgpu::FrontFace::Ccw,
188                        cull_mode: Some(wgpu::Face::Back),
189                        polygon_mode: wgpu::PolygonMode::Fill,
190                        unclipped_depth: false,
191                        conservative: false,
192                    },
193                    depth_stencil: None,
194                    multisample: wgpu::MultisampleState {
195                        count: 1,
196                        mask: !0,
197                        alpha_to_coverage_enabled: false,
198                    },
199                    multiview: None,
200                    cache: None,
201                });
202
203        #[rustfmt::skip]
204        let vertices: &[f32] = &[
205            -0.8, -0.8,  0.0, 1.0,
206             0.8, -0.8,  1.0, 1.0,
207             0.8,  0.8,  1.0, 0.0,
208            -0.8, -0.8,  0.0, 1.0,
209             0.8,  0.8,  1.0, 0.0,
210            -0.8,  0.8,  0.0, 0.0,
211        ];
212
213        let vertex_buffer = graphics_ctx.device.create_buffer(&wgpu::BufferDescriptor {
214            label: Some("Vertex Buffer"),
215            size: (vertices.len() * std::mem::size_of::<f32>()) as u64,
216            usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
217            mapped_at_creation: false,
218        });
219
220        graphics_ctx
221            .queue
222            .write_buffer(&vertex_buffer, 0, bytemuck::cast_slice(vertices));
223
224        let window_id = window.id();
225
226        Box::new(App {
227            window,
228            window_id,
229            pipeline,
230            bind_group,
231            vertex_buffer,
232        })
233    });
234}
examples/image_blitting.rs (lines 183-190)
167fn main() {
168    logging::init();
169
170    run_app(|ctx| {
171        let graphics_ctx = GraphicsContext::new_sync();
172        let mut windows = HashMap::new();
173
174        let scale = Window::platform_dpi() as f32;
175        let window = ctx
176            .create_window(WindowDescriptor {
177                title: "Image Blitting Example".to_string(),
178                size: Some(PhysicalSize::new(800.0 * scale, 600.0 * scale)),
179                ..Default::default()
180            })
181            .expect("Failed to create window");
182
183        let renderable_window = RenderableWindow::new_with_descriptor(
184            window,
185            graphics_ctx,
186            WindowContextDescriptor {
187                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
188                ..Default::default()
189            },
190        );
191
192        let window_id = renderable_window.id();
193        windows.insert(window_id, renderable_window);
194
195        // Create shader module
196        let shader = graphics_ctx.device.create_shader_module(wgpu::ShaderModuleDescriptor {
197            label: Some("Blit Shader"),
198            source: wgpu::ShaderSource::Wgsl(SHADER.into()),
199        });
200
201        // Create bind group layout
202        let bind_group_layout = graphics_ctx.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
203            label: Some("Blit Bind Group Layout"),
204            entries: &[
205                wgpu::BindGroupLayoutEntry {
206                    binding: 0,
207                    visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
208                    ty: wgpu::BindingType::Buffer {
209                        ty: wgpu::BufferBindingType::Uniform,
210                        has_dynamic_offset: false,
211                        min_binding_size: None,
212                    },
213                    count: None,
214                },
215                wgpu::BindGroupLayoutEntry {
216                    binding: 1,
217                    visibility: wgpu::ShaderStages::FRAGMENT,
218                    ty: wgpu::BindingType::Texture {
219                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
220                        view_dimension: wgpu::TextureViewDimension::D2,
221                        multisampled: false,
222                    },
223                    count: None,
224                },
225                wgpu::BindGroupLayoutEntry {
226                    binding: 2,
227                    visibility: wgpu::ShaderStages::FRAGMENT,
228                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
229                    count: None,
230                },
231            ],
232        });
233
234        // Create pipeline layout
235        let pipeline_layout = graphics_ctx.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
236            label: Some("Blit Pipeline Layout"),
237            bind_group_layouts: &[&bind_group_layout],
238            push_constant_ranges: &[],
239        });
240
241        // Create render pipeline
242        let pipeline = graphics_ctx.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
243            label: Some("Blit Pipeline"),
244            layout: Some(&pipeline_layout),
245            vertex: wgpu::VertexState {
246                module: &shader,
247                entry_point: Some("vs_main"),
248                buffers: &[wgpu::VertexBufferLayout {
249                    array_stride: std::mem::size_of::<Vertex>() as u64,
250                    step_mode: wgpu::VertexStepMode::Vertex,
251                    attributes: &[
252                        wgpu::VertexAttribute {
253                            offset: 0,
254                            shader_location: 0,
255                            format: wgpu::VertexFormat::Float32x2,
256                        },
257                        wgpu::VertexAttribute {
258                            offset: 8,
259                            shader_location: 1,
260                            format: wgpu::VertexFormat::Float32x2,
261                        },
262                    ],
263                }],
264                compilation_options: wgpu::PipelineCompilationOptions::default(),
265            },
266            fragment: Some(wgpu::FragmentState {
267                module: &shader,
268                entry_point: Some("fs_main"),
269                targets: &[Some(wgpu::ColorTargetState {
270                    format: wgpu::TextureFormat::Bgra8UnormSrgb,
271                    blend: Some(wgpu::BlendState::ALPHA_BLENDING),
272                    write_mask: wgpu::ColorWrites::ALL,
273                })],
274                compilation_options: wgpu::PipelineCompilationOptions::default(),
275            }),
276            primitive: wgpu::PrimitiveState {
277                topology: wgpu::PrimitiveTopology::TriangleList,
278                strip_index_format: None,
279                front_face: wgpu::FrontFace::Ccw,
280                cull_mode: None,
281                polygon_mode: wgpu::PolygonMode::Fill,
282                unclipped_depth: false,
283                conservative: false,
284            },
285            depth_stencil: None,
286            multisample: wgpu::MultisampleState::default(),
287            multiview: None,
288            cache: None,
289        });
290
291        // Create vertex buffer for a fullscreen quad
292        let vertices = [
293            Vertex { position: [-0.8, -0.8], uv: [0.0, 1.0] },
294            Vertex { position: [0.8, -0.8], uv: [1.0, 1.0] },
295            Vertex { position: [0.8, 0.8], uv: [1.0, 0.0] },
296            Vertex { position: [-0.8, -0.8], uv: [0.0, 1.0] },
297            Vertex { position: [0.8, 0.8], uv: [1.0, 0.0] },
298            Vertex { position: [-0.8, 0.8], uv: [0.0, 0.0] },
299        ];
300        let vertex_buffer = graphics_ctx.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
301            label: Some("Vertex Buffer"),
302            contents: bytemuck::cast_slice(&vertices),
303            usage: wgpu::BufferUsages::VERTEX,
304        });
305
306        // Create uniform buffer
307        let uniforms = Uniforms {
308            mvp: [
309                [1.0, 0.0, 0.0, 0.0],
310                [0.0, 1.0, 0.0, 0.0],
311                [0.0, 0.0, 1.0, 0.0],
312                [0.0, 0.0, 0.0, 1.0],
313            ],
314            tint: [1.0, 1.0, 1.0, 1.0],
315        };
316        let uniform_buffer = graphics_ctx.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
317            label: Some("Uniform Buffer"),
318            contents: bytemuck::cast_slice(&[uniforms]),
319            usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
320        });
321
322        // Create CPU-side image buffer
323        let mut image_buffer = ImageBuffer::new(256, 256);
324        image_buffer.clear(30, 30, 40, 255);
325
326        // Create GPU texture
327        let texture = graphics_ctx.device.create_texture(&wgpu::TextureDescriptor {
328            label: Some("Blit Texture"),
329            size: wgpu::Extent3d {
330                width: 256,
331                height: 256,
332                depth_or_array_layers: 1,
333            },
334            mip_level_count: 1,
335            sample_count: 1,
336            dimension: wgpu::TextureDimension::D2,
337            format: wgpu::TextureFormat::Rgba8UnormSrgb,
338            usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
339            view_formats: &[],
340        });
341
342        // Create texture view and sampler
343        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
344        let sampler = graphics_ctx.device.create_sampler(&wgpu::SamplerDescriptor {
345            label: Some("Blit Sampler"),
346            address_mode_u: wgpu::AddressMode::ClampToEdge,
347            address_mode_v: wgpu::AddressMode::ClampToEdge,
348            address_mode_w: wgpu::AddressMode::ClampToEdge,
349            mag_filter: wgpu::FilterMode::Nearest, // Pixel-perfect rendering
350            min_filter: wgpu::FilterMode::Nearest,
351            mipmap_filter: wgpu::FilterMode::Nearest,
352            ..Default::default()
353        });
354
355        // Create bind group
356        let bind_group = graphics_ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
357            label: Some("Blit Bind Group"),
358            layout: &bind_group_layout,
359            entries: &[
360                wgpu::BindGroupEntry {
361                    binding: 0,
362                    resource: uniform_buffer.as_entire_binding(),
363                },
364                wgpu::BindGroupEntry {
365                    binding: 1,
366                    resource: wgpu::BindingResource::TextureView(&texture_view),
367                },
368                wgpu::BindGroupEntry {
369                    binding: 2,
370                    resource: wgpu::BindingResource::Sampler(&sampler),
371                },
372            ],
373        });
374
375        Box::new(App {
376            context: graphics_ctx,
377            windows,
378            pipeline,
379            bind_group_layout,
380            vertex_buffer,
381            texture,
382            bind_group,
383            uniform_buffer,
384            image_buffer,
385            start_time: Instant::now(),
386        })
387    });
388}
examples/renderer_api.rs (lines 43-50)
28fn main() {
29    logging::init();
30
31    run_app(|ctx| {
32        let graphics_ctx = GraphicsContext::new_sync();
33        let renderer = Renderer::new(graphics_ctx);
34
35        let window = ctx
36            .create_window(WindowDescriptor {
37                title: "Renderer API Example".to_string(),
38                size: Some(PhysicalSize::new(800.0, 600.0)),
39                ..Default::default()
40            })
41            .expect("Failed to create window");
42
43        let window = RenderableWindow::new_with_descriptor(
44            window,
45            graphics_ctx,
46            WindowContextDescriptor {
47                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
48                ..Default::default()
49            },
50        );
51
52        let window_id = window.id();
53
54        // Create shader using Renderer API
55        let shader = renderer.create_shader(Some("Color Shader"), SHADER_SOURCE);
56
57        // Create texture using Renderer helper
58        let texture_data = create_gradient_texture();
59        let texture = renderer.create_texture_2d(
60            Some("Gradient Texture"),
61            256,
62            256,
63            wgpu::TextureFormat::Rgba8UnormSrgb,
64            wgpu::TextureUsages::TEXTURE_BINDING,
65            &texture_data,
66        );
67
68        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
69        let sampler = renderer.create_linear_sampler(Some("Linear Sampler"));
70
71        // Create bind group using Renderer API
72        let bind_group_layout = renderer.create_bind_group_layout(
73            Some("Texture Bind Group Layout"),
74            &[
75                wgpu::BindGroupLayoutEntry {
76                    binding: 0,
77                    visibility: wgpu::ShaderStages::FRAGMENT,
78                    ty: wgpu::BindingType::Texture {
79                        multisampled: false,
80                        view_dimension: wgpu::TextureViewDimension::D2,
81                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
82                    },
83                    count: None,
84                },
85                wgpu::BindGroupLayoutEntry {
86                    binding: 1,
87                    visibility: wgpu::ShaderStages::FRAGMENT,
88                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
89                    count: None,
90                },
91            ],
92        );
93
94        let bind_group = renderer.create_bind_group(
95            Some("Texture Bind Group"),
96            &bind_group_layout,
97            &[
98                wgpu::BindGroupEntry {
99                    binding: 0,
100                    resource: wgpu::BindingResource::TextureView(&texture_view),
101                },
102                wgpu::BindGroupEntry {
103                    binding: 1,
104                    resource: wgpu::BindingResource::Sampler(&sampler),
105                },
106            ],
107        );
108
109        let pipeline_layout = renderer.create_pipeline_layout(
110            Some("Render Pipeline Layout"),
111            &[&bind_group_layout],
112            &[],
113        );
114
115        // Create pipeline using Renderer API with BlendMode
116        let pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
117            label: Some("Render Pipeline"),
118            layout: Some(&pipeline_layout),
119            vertex: wgpu::VertexState {
120                module: &shader,
121                entry_point: Some("vs_main"),
122                buffers: &[wgpu::VertexBufferLayout {
123                    array_stride: 4 * 4,
124                    step_mode: wgpu::VertexStepMode::Vertex,
125                    attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2],
126                }],
127                compilation_options: wgpu::PipelineCompilationOptions::default(),
128            },
129            fragment: Some(wgpu::FragmentState {
130                module: &shader,
131                entry_point: Some("fs_main"),
132                // Use BlendMode for transparent rendering
133                targets: &[Some(
134                    BlendMode::Alpha.to_color_target_state(wgpu::TextureFormat::Rgba8UnormSrgb),
135                )],
136                compilation_options: wgpu::PipelineCompilationOptions::default(),
137            }),
138            primitive: wgpu::PrimitiveState {
139                topology: wgpu::PrimitiveTopology::TriangleList,
140                strip_index_format: None,
141                front_face: wgpu::FrontFace::Ccw,
142                cull_mode: Some(wgpu::Face::Back),
143                polygon_mode: wgpu::PolygonMode::Fill,
144                unclipped_depth: false,
145                conservative: false,
146            },
147            depth_stencil: None,
148            multisample: wgpu::MultisampleState {
149                count: 1,
150                mask: !0,
151                alpha_to_coverage_enabled: false,
152            },
153            multiview: None,
154            cache: None,
155        });
156
157        #[rustfmt::skip]
158        let vertices: &[f32] = &[
159            -0.8, -0.8,  0.0, 1.0,
160             0.8, -0.8,  1.0, 1.0,
161             0.8,  0.8,  1.0, 0.0,
162            -0.8, -0.8,  0.0, 1.0,
163             0.8,  0.8,  1.0, 0.0,
164            -0.8,  0.8,  0.0, 0.0,
165        ];
166
167        // Create vertex buffer using Renderer helper
168        let vertex_buffer = renderer.create_vertex_buffer(Some("Vertex Buffer"), vertices);
169
170        // Create offscreen framebuffer using the new Framebuffer abstraction
171        let offscreen_fb = Framebuffer::builder(400, 300)
172            .format(wgpu::TextureFormat::Rgba8UnormSrgb)
173            .label("Offscreen FB")
174            .build(graphics_ctx);
175
176        // Create blit shader and pipeline for rendering framebuffer to surface
177        let blit_shader = renderer.create_shader(Some("Blit Shader"), BLIT_SHADER_SOURCE);
178
179        let blit_bind_group_layout = renderer.create_bind_group_layout(
180            Some("Blit Bind Group Layout"),
181            &[
182                wgpu::BindGroupLayoutEntry {
183                    binding: 0,
184                    visibility: wgpu::ShaderStages::FRAGMENT,
185                    ty: wgpu::BindingType::Texture {
186                        multisampled: false,
187                        view_dimension: wgpu::TextureViewDimension::D2,
188                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
189                    },
190                    count: None,
191                },
192                wgpu::BindGroupLayoutEntry {
193                    binding: 1,
194                    visibility: wgpu::ShaderStages::FRAGMENT,
195                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
196                    count: None,
197                },
198            ],
199        );
200
201        let blit_bind_group = renderer.create_bind_group(
202            Some("Blit Bind Group"),
203            &blit_bind_group_layout,
204            &[
205                wgpu::BindGroupEntry {
206                    binding: 0,
207                    resource: wgpu::BindingResource::TextureView(offscreen_fb.color_view()),
208                },
209                wgpu::BindGroupEntry {
210                    binding: 1,
211                    resource: wgpu::BindingResource::Sampler(&sampler),
212                },
213            ],
214        );
215
216        let blit_pipeline_layout = renderer.create_pipeline_layout(
217            Some("Blit Pipeline Layout"),
218            &[&blit_bind_group_layout],
219            &[],
220        );
221
222        let blit_pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
223            label: Some("Blit Pipeline"),
224            layout: Some(&blit_pipeline_layout),
225            vertex: wgpu::VertexState {
226                module: &blit_shader,
227                entry_point: Some("vs_main"),
228                buffers: &[],
229                compilation_options: wgpu::PipelineCompilationOptions::default(),
230            },
231            fragment: Some(wgpu::FragmentState {
232                module: &blit_shader,
233                entry_point: Some("fs_main"),
234                // Use PremultipliedAlpha for framebuffer blitting
235                targets: &[Some(
236                    BlendMode::PremultipliedAlpha
237                        .to_color_target_state(wgpu::TextureFormat::Bgra8UnormSrgb),
238                )],
239                compilation_options: wgpu::PipelineCompilationOptions::default(),
240            }),
241            primitive: wgpu::PrimitiveState {
242                topology: wgpu::PrimitiveTopology::TriangleList,
243                ..Default::default()
244            },
245            depth_stencil: None,
246            multisample: wgpu::MultisampleState::default(),
247            multiview: None,
248            cache: None,
249        });
250
251        tracing::info!("Renderer initialized successfully");
252        tracing::info!("Device: {:?}", renderer.context().info());
253
254        Box::new(RendererApp {
255            context: graphics_ctx,
256            renderer,
257            window,
258            window_id,
259            pipeline,
260            bind_group,
261            vertex_buffer,
262            offscreen_fb,
263            blit_pipeline,
264            blit_bind_group,
265            time: 0.0,
266        })
267    });
268}
Source

pub fn id(&self) -> WindowId

Examples found in repository?
examples/multi_window.rs (line 76)
28fn main() {
29    logging::init();
30
31    run_app(|ctx| {
32        let graphics_ctx = GraphicsContext::new_sync();
33
34        let mut windows = HashMap::new();
35
36        // Create 3 windows with different colors
37        let colors = [
38            wgpu::Color {
39                r: 0.8,
40                g: 0.2,
41                b: 0.2,
42                a: 1.0,
43            },
44            wgpu::Color {
45                r: 0.2,
46                g: 0.8,
47                b: 0.2,
48                a: 1.0,
49            },
50            wgpu::Color {
51                r: 0.2,
52                g: 0.2,
53                b: 0.8,
54                a: 1.0,
55            },
56        ];
57
58        for (i, color) in colors.iter().enumerate() {
59            let window = ctx
60                .create_window(WindowDescriptor {
61                    title: format!("Window {} - Multi-Window Example", i + 1),
62                    size: Some(PhysicalSize::new(400.0, 300.0)),
63                    ..Default::default()
64                })
65                .expect("Failed to create window");
66
67            let renderable_window = RenderableWindow::new_with_descriptor(
68                window,
69                graphics_ctx,
70                WindowContextDescriptor {
71                    format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
72                    ..Default::default()
73                },
74            );
75
76            let window_id = renderable_window.id();
77            windows.insert(window_id, (renderable_window, *color));
78        }
79
80        Box::new(App {
81            context: graphics_ctx,
82            windows,
83        })
84    });
85}
More examples
Hide additional examples
examples/sprite_sheet.rs (line 173)
148fn main() {
149    logging::init();
150
151    run_app(|ctx| {
152        let graphics_ctx = GraphicsContext::new_sync();
153        let mut windows = HashMap::new();
154
155        let scale = Window::platform_dpi() as f32;
156        let window = ctx
157            .create_window(WindowDescriptor {
158                title: "Sprite Sheet Animation Example".to_string(),
159                size: Some(PhysicalSize::new(400.0 * scale, 400.0 * scale)),
160                ..Default::default()
161            })
162            .expect("Failed to create window");
163
164        let renderable_window = RenderableWindow::new_with_descriptor(
165            window,
166            graphics_ctx,
167            WindowContextDescriptor {
168                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
169                ..Default::default()
170            },
171        );
172
173        let window_id = renderable_window.id();
174        windows.insert(window_id, renderable_window);
175
176        // Generate sprite sheet
177        let (sprite_data, tex_width, tex_height) = generate_sprite_sheet_data();
178        let sprite_sheet = SpriteSheet::from_data(
179            graphics_ctx,
180            &sprite_data,
181            tex_width,
182            tex_height,
183            SpriteSheetDescriptor {
184                sprite_width: 64,
185                sprite_height: 64,
186                columns: 4,
187                rows: 1,
188                ..Default::default()
189            },
190        );
191
192        // Create animation (4 frames at 8 fps)
193        let animation = SpriteAnimation::new(4, 8.0);
194
195        // Create shader module
196        let shader = graphics_ctx.device.create_shader_module(wgpu::ShaderModuleDescriptor {
197            label: Some("Sprite Shader"),
198            source: wgpu::ShaderSource::Wgsl(SHADER.into()),
199        });
200
201        // Create bind group layout
202        let bind_group_layout = graphics_ctx.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
203            label: Some("Sprite Bind Group Layout"),
204            entries: &[
205                wgpu::BindGroupLayoutEntry {
206                    binding: 0,
207                    visibility: wgpu::ShaderStages::VERTEX,
208                    ty: wgpu::BindingType::Buffer {
209                        ty: wgpu::BufferBindingType::Uniform,
210                        has_dynamic_offset: false,
211                        min_binding_size: None,
212                    },
213                    count: None,
214                },
215                wgpu::BindGroupLayoutEntry {
216                    binding: 1,
217                    visibility: wgpu::ShaderStages::FRAGMENT,
218                    ty: wgpu::BindingType::Texture {
219                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
220                        view_dimension: wgpu::TextureViewDimension::D2,
221                        multisampled: false,
222                    },
223                    count: None,
224                },
225                wgpu::BindGroupLayoutEntry {
226                    binding: 2,
227                    visibility: wgpu::ShaderStages::FRAGMENT,
228                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
229                    count: None,
230                },
231            ],
232        });
233
234        // Create pipeline layout
235        let pipeline_layout = graphics_ctx.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
236            label: Some("Sprite Pipeline Layout"),
237            bind_group_layouts: &[&bind_group_layout],
238            push_constant_ranges: &[],
239        });
240
241        // Create render pipeline
242        let pipeline = graphics_ctx.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
243            label: Some("Sprite Pipeline"),
244            layout: Some(&pipeline_layout),
245            vertex: wgpu::VertexState {
246                module: &shader,
247                entry_point: Some("vs_main"),
248                buffers: &[wgpu::VertexBufferLayout {
249                    array_stride: std::mem::size_of::<Vertex>() as u64,
250                    step_mode: wgpu::VertexStepMode::Vertex,
251                    attributes: &[
252                        wgpu::VertexAttribute {
253                            offset: 0,
254                            shader_location: 0,
255                            format: wgpu::VertexFormat::Float32x2,
256                        },
257                        wgpu::VertexAttribute {
258                            offset: 8,
259                            shader_location: 1,
260                            format: wgpu::VertexFormat::Float32x2,
261                        },
262                    ],
263                }],
264                compilation_options: wgpu::PipelineCompilationOptions::default(),
265            },
266            fragment: Some(wgpu::FragmentState {
267                module: &shader,
268                entry_point: Some("fs_main"),
269                targets: &[Some(wgpu::ColorTargetState {
270                    format: wgpu::TextureFormat::Bgra8UnormSrgb,
271                    blend: Some(wgpu::BlendState::ALPHA_BLENDING),
272                    write_mask: wgpu::ColorWrites::ALL,
273                })],
274                compilation_options: wgpu::PipelineCompilationOptions::default(),
275            }),
276            primitive: wgpu::PrimitiveState {
277                topology: wgpu::PrimitiveTopology::TriangleList,
278                ..Default::default()
279            },
280            depth_stencil: None,
281            multisample: wgpu::MultisampleState::default(),
282            multiview: None,
283            cache: None,
284        });
285
286        // Create uniform buffer
287        let uniforms = Uniforms {
288            mvp: [
289                [1.0, 0.0, 0.0, 0.0],
290                [0.0, 1.0, 0.0, 0.0],
291                [0.0, 0.0, 1.0, 0.0],
292                [0.0, 0.0, 0.0, 1.0],
293            ],
294        };
295        let uniform_buffer = graphics_ctx.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
296            label: Some("Uniform Buffer"),
297            contents: bytemuck::cast_slice(&[uniforms]),
298            usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
299        });
300
301        // Create sampler
302        let sampler = graphics_ctx.device.create_sampler(&wgpu::SamplerDescriptor {
303            label: Some("Sprite Sampler"),
304            mag_filter: wgpu::FilterMode::Linear,
305            min_filter: wgpu::FilterMode::Linear,
306            ..Default::default()
307        });
308
309        // Create bind group
310        let bind_group = graphics_ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
311            label: Some("Sprite Bind Group"),
312            layout: &bind_group_layout,
313            entries: &[
314                wgpu::BindGroupEntry {
315                    binding: 0,
316                    resource: uniform_buffer.as_entire_binding(),
317                },
318                wgpu::BindGroupEntry {
319                    binding: 1,
320                    resource: wgpu::BindingResource::TextureView(sprite_sheet.view()),
321                },
322                wgpu::BindGroupEntry {
323                    binding: 2,
324                    resource: wgpu::BindingResource::Sampler(&sampler),
325                },
326            ],
327        });
328
329        // Initial vertex buffer (will be updated each frame with new UVs)
330        let vertices = create_quad_vertices(0.0, 0.0, 1.0, 1.0);
331        let vertex_buffer = graphics_ctx.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
332            label: Some("Vertex Buffer"),
333            contents: bytemuck::cast_slice(&vertices),
334            usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
335        });
336
337        Box::new(App {
338            _context: graphics_ctx,
339            windows,
340            pipeline,
341            bind_group,
342            vertex_buffer,
343            uniform_buffer,
344            sprite_sheet,
345            animation,
346            last_update: Instant::now(),
347        })
348    });
349}
examples/textured_window.rs (line 224)
19fn main() {
20    logging::init();
21
22    run_app(|ctx| {
23        let graphics_ctx = GraphicsContext::new_sync();
24
25        let window = ctx
26            .create_window(WindowDescriptor {
27                title: "Textured Window".to_string(),
28                ..Default::default()
29            })
30            .expect("Failed to create window");
31
32        let window = RenderableWindow::new_with_descriptor(
33            window,
34            graphics_ctx,
35            WindowContextDescriptor {
36                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
37                ..Default::default()
38            },
39        );
40
41        let shader = graphics_ctx
42            .device
43            .create_shader_module(wgpu::ShaderModuleDescriptor {
44                label: Some("Texture Shader"),
45                source: wgpu::ShaderSource::Wgsl(include_str!("textured_window.wgsl").into()),
46            });
47
48        let texture_size = wgpu::Extent3d {
49            width: 256,
50            height: 256,
51            depth_or_array_layers: 1,
52        };
53
54        let texture = graphics_ctx
55            .device
56            .create_texture(&wgpu::TextureDescriptor {
57                label: Some("Example Texture"),
58                size: texture_size,
59                mip_level_count: 1,
60                sample_count: 1,
61                dimension: wgpu::TextureDimension::D2,
62                format: wgpu::TextureFormat::Rgba8UnormSrgb,
63                usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
64                view_formats: &[],
65            });
66
67        let mut texture_data = vec![0u8; (256 * 256 * 4) as usize];
68        for y in 0..256 {
69            for x in 0..256 {
70                let idx = ((y * 256 + x) * 4) as usize;
71                texture_data[idx] = x as u8;
72                texture_data[idx + 1] = y as u8;
73                texture_data[idx + 2] = ((x + y) / 2) as u8;
74                texture_data[idx + 3] = 255;
75            }
76        }
77
78        graphics_ctx.queue.write_texture(
79            wgpu::TexelCopyTextureInfo {
80                texture: &texture,
81                mip_level: 0,
82                origin: wgpu::Origin3d::ZERO,
83                aspect: wgpu::TextureAspect::All,
84            },
85            &texture_data,
86            wgpu::TexelCopyBufferLayout {
87                offset: 0,
88                bytes_per_row: Some(256 * 4),
89                rows_per_image: Some(256),
90            },
91            texture_size,
92        );
93
94        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
95        let sampler = graphics_ctx
96            .device
97            .create_sampler(&wgpu::SamplerDescriptor {
98                address_mode_u: wgpu::AddressMode::ClampToEdge,
99                address_mode_v: wgpu::AddressMode::ClampToEdge,
100                address_mode_w: wgpu::AddressMode::ClampToEdge,
101                mag_filter: wgpu::FilterMode::Linear,
102                min_filter: wgpu::FilterMode::Nearest,
103                mipmap_filter: wgpu::FilterMode::Nearest,
104                ..Default::default()
105            });
106
107        let bind_group_layout =
108            graphics_ctx
109                .device
110                .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
111                    label: Some("Texture Bind Group Layout"),
112                    entries: &[
113                        wgpu::BindGroupLayoutEntry {
114                            binding: 0,
115                            visibility: wgpu::ShaderStages::FRAGMENT,
116                            ty: wgpu::BindingType::Texture {
117                                multisampled: false,
118                                view_dimension: wgpu::TextureViewDimension::D2,
119                                sample_type: wgpu::TextureSampleType::Float { filterable: true },
120                            },
121                            count: None,
122                        },
123                        wgpu::BindGroupLayoutEntry {
124                            binding: 1,
125                            visibility: wgpu::ShaderStages::FRAGMENT,
126                            ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
127                            count: None,
128                        },
129                    ],
130                });
131
132        let bind_group = graphics_ctx
133            .device
134            .create_bind_group(&wgpu::BindGroupDescriptor {
135                label: Some("Texture Bind Group"),
136                layout: &bind_group_layout,
137                entries: &[
138                    wgpu::BindGroupEntry {
139                        binding: 0,
140                        resource: wgpu::BindingResource::TextureView(&texture_view),
141                    },
142                    wgpu::BindGroupEntry {
143                        binding: 1,
144                        resource: wgpu::BindingResource::Sampler(&sampler),
145                    },
146                ],
147            });
148
149        let pipeline_layout =
150            graphics_ctx
151                .device
152                .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
153                    label: Some("Render Pipeline Layout"),
154                    bind_group_layouts: &[&bind_group_layout],
155                    push_constant_ranges: &[],
156                });
157
158        let pipeline =
159            graphics_ctx
160                .device
161                .create_render_pipeline(&wgpu::RenderPipelineDescriptor {
162                    label: Some("Render Pipeline"),
163                    layout: Some(&pipeline_layout),
164                    vertex: wgpu::VertexState {
165                        module: &shader,
166                        entry_point: Some("vs_main"),
167                        buffers: &[wgpu::VertexBufferLayout {
168                            array_stride: 4 * 4,
169                            step_mode: wgpu::VertexStepMode::Vertex,
170                            attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2],
171                        }],
172                        compilation_options: wgpu::PipelineCompilationOptions::default(),
173                    },
174                    fragment: Some(wgpu::FragmentState {
175                        module: &shader,
176                        entry_point: Some("fs_main"),
177                        targets: &[Some(wgpu::ColorTargetState {
178                            format: wgpu::TextureFormat::Bgra8UnormSrgb,
179                            blend: Some(wgpu::BlendState::REPLACE),
180                            write_mask: wgpu::ColorWrites::ALL,
181                        })],
182                        compilation_options: wgpu::PipelineCompilationOptions::default(),
183                    }),
184                    primitive: wgpu::PrimitiveState {
185                        topology: wgpu::PrimitiveTopology::TriangleList,
186                        strip_index_format: None,
187                        front_face: wgpu::FrontFace::Ccw,
188                        cull_mode: Some(wgpu::Face::Back),
189                        polygon_mode: wgpu::PolygonMode::Fill,
190                        unclipped_depth: false,
191                        conservative: false,
192                    },
193                    depth_stencil: None,
194                    multisample: wgpu::MultisampleState {
195                        count: 1,
196                        mask: !0,
197                        alpha_to_coverage_enabled: false,
198                    },
199                    multiview: None,
200                    cache: None,
201                });
202
203        #[rustfmt::skip]
204        let vertices: &[f32] = &[
205            -0.8, -0.8,  0.0, 1.0,
206             0.8, -0.8,  1.0, 1.0,
207             0.8,  0.8,  1.0, 0.0,
208            -0.8, -0.8,  0.0, 1.0,
209             0.8,  0.8,  1.0, 0.0,
210            -0.8,  0.8,  0.0, 0.0,
211        ];
212
213        let vertex_buffer = graphics_ctx.device.create_buffer(&wgpu::BufferDescriptor {
214            label: Some("Vertex Buffer"),
215            size: (vertices.len() * std::mem::size_of::<f32>()) as u64,
216            usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
217            mapped_at_creation: false,
218        });
219
220        graphics_ctx
221            .queue
222            .write_buffer(&vertex_buffer, 0, bytemuck::cast_slice(vertices));
223
224        let window_id = window.id();
225
226        Box::new(App {
227            window,
228            window_id,
229            pipeline,
230            bind_group,
231            vertex_buffer,
232        })
233    });
234}
examples/image_blitting.rs (line 192)
167fn main() {
168    logging::init();
169
170    run_app(|ctx| {
171        let graphics_ctx = GraphicsContext::new_sync();
172        let mut windows = HashMap::new();
173
174        let scale = Window::platform_dpi() as f32;
175        let window = ctx
176            .create_window(WindowDescriptor {
177                title: "Image Blitting Example".to_string(),
178                size: Some(PhysicalSize::new(800.0 * scale, 600.0 * scale)),
179                ..Default::default()
180            })
181            .expect("Failed to create window");
182
183        let renderable_window = RenderableWindow::new_with_descriptor(
184            window,
185            graphics_ctx,
186            WindowContextDescriptor {
187                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
188                ..Default::default()
189            },
190        );
191
192        let window_id = renderable_window.id();
193        windows.insert(window_id, renderable_window);
194
195        // Create shader module
196        let shader = graphics_ctx.device.create_shader_module(wgpu::ShaderModuleDescriptor {
197            label: Some("Blit Shader"),
198            source: wgpu::ShaderSource::Wgsl(SHADER.into()),
199        });
200
201        // Create bind group layout
202        let bind_group_layout = graphics_ctx.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
203            label: Some("Blit Bind Group Layout"),
204            entries: &[
205                wgpu::BindGroupLayoutEntry {
206                    binding: 0,
207                    visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
208                    ty: wgpu::BindingType::Buffer {
209                        ty: wgpu::BufferBindingType::Uniform,
210                        has_dynamic_offset: false,
211                        min_binding_size: None,
212                    },
213                    count: None,
214                },
215                wgpu::BindGroupLayoutEntry {
216                    binding: 1,
217                    visibility: wgpu::ShaderStages::FRAGMENT,
218                    ty: wgpu::BindingType::Texture {
219                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
220                        view_dimension: wgpu::TextureViewDimension::D2,
221                        multisampled: false,
222                    },
223                    count: None,
224                },
225                wgpu::BindGroupLayoutEntry {
226                    binding: 2,
227                    visibility: wgpu::ShaderStages::FRAGMENT,
228                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
229                    count: None,
230                },
231            ],
232        });
233
234        // Create pipeline layout
235        let pipeline_layout = graphics_ctx.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
236            label: Some("Blit Pipeline Layout"),
237            bind_group_layouts: &[&bind_group_layout],
238            push_constant_ranges: &[],
239        });
240
241        // Create render pipeline
242        let pipeline = graphics_ctx.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
243            label: Some("Blit Pipeline"),
244            layout: Some(&pipeline_layout),
245            vertex: wgpu::VertexState {
246                module: &shader,
247                entry_point: Some("vs_main"),
248                buffers: &[wgpu::VertexBufferLayout {
249                    array_stride: std::mem::size_of::<Vertex>() as u64,
250                    step_mode: wgpu::VertexStepMode::Vertex,
251                    attributes: &[
252                        wgpu::VertexAttribute {
253                            offset: 0,
254                            shader_location: 0,
255                            format: wgpu::VertexFormat::Float32x2,
256                        },
257                        wgpu::VertexAttribute {
258                            offset: 8,
259                            shader_location: 1,
260                            format: wgpu::VertexFormat::Float32x2,
261                        },
262                    ],
263                }],
264                compilation_options: wgpu::PipelineCompilationOptions::default(),
265            },
266            fragment: Some(wgpu::FragmentState {
267                module: &shader,
268                entry_point: Some("fs_main"),
269                targets: &[Some(wgpu::ColorTargetState {
270                    format: wgpu::TextureFormat::Bgra8UnormSrgb,
271                    blend: Some(wgpu::BlendState::ALPHA_BLENDING),
272                    write_mask: wgpu::ColorWrites::ALL,
273                })],
274                compilation_options: wgpu::PipelineCompilationOptions::default(),
275            }),
276            primitive: wgpu::PrimitiveState {
277                topology: wgpu::PrimitiveTopology::TriangleList,
278                strip_index_format: None,
279                front_face: wgpu::FrontFace::Ccw,
280                cull_mode: None,
281                polygon_mode: wgpu::PolygonMode::Fill,
282                unclipped_depth: false,
283                conservative: false,
284            },
285            depth_stencil: None,
286            multisample: wgpu::MultisampleState::default(),
287            multiview: None,
288            cache: None,
289        });
290
291        // Create vertex buffer for a fullscreen quad
292        let vertices = [
293            Vertex { position: [-0.8, -0.8], uv: [0.0, 1.0] },
294            Vertex { position: [0.8, -0.8], uv: [1.0, 1.0] },
295            Vertex { position: [0.8, 0.8], uv: [1.0, 0.0] },
296            Vertex { position: [-0.8, -0.8], uv: [0.0, 1.0] },
297            Vertex { position: [0.8, 0.8], uv: [1.0, 0.0] },
298            Vertex { position: [-0.8, 0.8], uv: [0.0, 0.0] },
299        ];
300        let vertex_buffer = graphics_ctx.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
301            label: Some("Vertex Buffer"),
302            contents: bytemuck::cast_slice(&vertices),
303            usage: wgpu::BufferUsages::VERTEX,
304        });
305
306        // Create uniform buffer
307        let uniforms = Uniforms {
308            mvp: [
309                [1.0, 0.0, 0.0, 0.0],
310                [0.0, 1.0, 0.0, 0.0],
311                [0.0, 0.0, 1.0, 0.0],
312                [0.0, 0.0, 0.0, 1.0],
313            ],
314            tint: [1.0, 1.0, 1.0, 1.0],
315        };
316        let uniform_buffer = graphics_ctx.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
317            label: Some("Uniform Buffer"),
318            contents: bytemuck::cast_slice(&[uniforms]),
319            usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
320        });
321
322        // Create CPU-side image buffer
323        let mut image_buffer = ImageBuffer::new(256, 256);
324        image_buffer.clear(30, 30, 40, 255);
325
326        // Create GPU texture
327        let texture = graphics_ctx.device.create_texture(&wgpu::TextureDescriptor {
328            label: Some("Blit Texture"),
329            size: wgpu::Extent3d {
330                width: 256,
331                height: 256,
332                depth_or_array_layers: 1,
333            },
334            mip_level_count: 1,
335            sample_count: 1,
336            dimension: wgpu::TextureDimension::D2,
337            format: wgpu::TextureFormat::Rgba8UnormSrgb,
338            usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
339            view_formats: &[],
340        });
341
342        // Create texture view and sampler
343        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
344        let sampler = graphics_ctx.device.create_sampler(&wgpu::SamplerDescriptor {
345            label: Some("Blit Sampler"),
346            address_mode_u: wgpu::AddressMode::ClampToEdge,
347            address_mode_v: wgpu::AddressMode::ClampToEdge,
348            address_mode_w: wgpu::AddressMode::ClampToEdge,
349            mag_filter: wgpu::FilterMode::Nearest, // Pixel-perfect rendering
350            min_filter: wgpu::FilterMode::Nearest,
351            mipmap_filter: wgpu::FilterMode::Nearest,
352            ..Default::default()
353        });
354
355        // Create bind group
356        let bind_group = graphics_ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
357            label: Some("Blit Bind Group"),
358            layout: &bind_group_layout,
359            entries: &[
360                wgpu::BindGroupEntry {
361                    binding: 0,
362                    resource: uniform_buffer.as_entire_binding(),
363                },
364                wgpu::BindGroupEntry {
365                    binding: 1,
366                    resource: wgpu::BindingResource::TextureView(&texture_view),
367                },
368                wgpu::BindGroupEntry {
369                    binding: 2,
370                    resource: wgpu::BindingResource::Sampler(&sampler),
371                },
372            ],
373        });
374
375        Box::new(App {
376            context: graphics_ctx,
377            windows,
378            pipeline,
379            bind_group_layout,
380            vertex_buffer,
381            texture,
382            bind_group,
383            uniform_buffer,
384            image_buffer,
385            start_time: Instant::now(),
386        })
387    });
388}
examples/renderer_api.rs (line 52)
28fn main() {
29    logging::init();
30
31    run_app(|ctx| {
32        let graphics_ctx = GraphicsContext::new_sync();
33        let renderer = Renderer::new(graphics_ctx);
34
35        let window = ctx
36            .create_window(WindowDescriptor {
37                title: "Renderer API Example".to_string(),
38                size: Some(PhysicalSize::new(800.0, 600.0)),
39                ..Default::default()
40            })
41            .expect("Failed to create window");
42
43        let window = RenderableWindow::new_with_descriptor(
44            window,
45            graphics_ctx,
46            WindowContextDescriptor {
47                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
48                ..Default::default()
49            },
50        );
51
52        let window_id = window.id();
53
54        // Create shader using Renderer API
55        let shader = renderer.create_shader(Some("Color Shader"), SHADER_SOURCE);
56
57        // Create texture using Renderer helper
58        let texture_data = create_gradient_texture();
59        let texture = renderer.create_texture_2d(
60            Some("Gradient Texture"),
61            256,
62            256,
63            wgpu::TextureFormat::Rgba8UnormSrgb,
64            wgpu::TextureUsages::TEXTURE_BINDING,
65            &texture_data,
66        );
67
68        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
69        let sampler = renderer.create_linear_sampler(Some("Linear Sampler"));
70
71        // Create bind group using Renderer API
72        let bind_group_layout = renderer.create_bind_group_layout(
73            Some("Texture Bind Group Layout"),
74            &[
75                wgpu::BindGroupLayoutEntry {
76                    binding: 0,
77                    visibility: wgpu::ShaderStages::FRAGMENT,
78                    ty: wgpu::BindingType::Texture {
79                        multisampled: false,
80                        view_dimension: wgpu::TextureViewDimension::D2,
81                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
82                    },
83                    count: None,
84                },
85                wgpu::BindGroupLayoutEntry {
86                    binding: 1,
87                    visibility: wgpu::ShaderStages::FRAGMENT,
88                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
89                    count: None,
90                },
91            ],
92        );
93
94        let bind_group = renderer.create_bind_group(
95            Some("Texture Bind Group"),
96            &bind_group_layout,
97            &[
98                wgpu::BindGroupEntry {
99                    binding: 0,
100                    resource: wgpu::BindingResource::TextureView(&texture_view),
101                },
102                wgpu::BindGroupEntry {
103                    binding: 1,
104                    resource: wgpu::BindingResource::Sampler(&sampler),
105                },
106            ],
107        );
108
109        let pipeline_layout = renderer.create_pipeline_layout(
110            Some("Render Pipeline Layout"),
111            &[&bind_group_layout],
112            &[],
113        );
114
115        // Create pipeline using Renderer API with BlendMode
116        let pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
117            label: Some("Render Pipeline"),
118            layout: Some(&pipeline_layout),
119            vertex: wgpu::VertexState {
120                module: &shader,
121                entry_point: Some("vs_main"),
122                buffers: &[wgpu::VertexBufferLayout {
123                    array_stride: 4 * 4,
124                    step_mode: wgpu::VertexStepMode::Vertex,
125                    attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2],
126                }],
127                compilation_options: wgpu::PipelineCompilationOptions::default(),
128            },
129            fragment: Some(wgpu::FragmentState {
130                module: &shader,
131                entry_point: Some("fs_main"),
132                // Use BlendMode for transparent rendering
133                targets: &[Some(
134                    BlendMode::Alpha.to_color_target_state(wgpu::TextureFormat::Rgba8UnormSrgb),
135                )],
136                compilation_options: wgpu::PipelineCompilationOptions::default(),
137            }),
138            primitive: wgpu::PrimitiveState {
139                topology: wgpu::PrimitiveTopology::TriangleList,
140                strip_index_format: None,
141                front_face: wgpu::FrontFace::Ccw,
142                cull_mode: Some(wgpu::Face::Back),
143                polygon_mode: wgpu::PolygonMode::Fill,
144                unclipped_depth: false,
145                conservative: false,
146            },
147            depth_stencil: None,
148            multisample: wgpu::MultisampleState {
149                count: 1,
150                mask: !0,
151                alpha_to_coverage_enabled: false,
152            },
153            multiview: None,
154            cache: None,
155        });
156
157        #[rustfmt::skip]
158        let vertices: &[f32] = &[
159            -0.8, -0.8,  0.0, 1.0,
160             0.8, -0.8,  1.0, 1.0,
161             0.8,  0.8,  1.0, 0.0,
162            -0.8, -0.8,  0.0, 1.0,
163             0.8,  0.8,  1.0, 0.0,
164            -0.8,  0.8,  0.0, 0.0,
165        ];
166
167        // Create vertex buffer using Renderer helper
168        let vertex_buffer = renderer.create_vertex_buffer(Some("Vertex Buffer"), vertices);
169
170        // Create offscreen framebuffer using the new Framebuffer abstraction
171        let offscreen_fb = Framebuffer::builder(400, 300)
172            .format(wgpu::TextureFormat::Rgba8UnormSrgb)
173            .label("Offscreen FB")
174            .build(graphics_ctx);
175
176        // Create blit shader and pipeline for rendering framebuffer to surface
177        let blit_shader = renderer.create_shader(Some("Blit Shader"), BLIT_SHADER_SOURCE);
178
179        let blit_bind_group_layout = renderer.create_bind_group_layout(
180            Some("Blit Bind Group Layout"),
181            &[
182                wgpu::BindGroupLayoutEntry {
183                    binding: 0,
184                    visibility: wgpu::ShaderStages::FRAGMENT,
185                    ty: wgpu::BindingType::Texture {
186                        multisampled: false,
187                        view_dimension: wgpu::TextureViewDimension::D2,
188                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
189                    },
190                    count: None,
191                },
192                wgpu::BindGroupLayoutEntry {
193                    binding: 1,
194                    visibility: wgpu::ShaderStages::FRAGMENT,
195                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
196                    count: None,
197                },
198            ],
199        );
200
201        let blit_bind_group = renderer.create_bind_group(
202            Some("Blit Bind Group"),
203            &blit_bind_group_layout,
204            &[
205                wgpu::BindGroupEntry {
206                    binding: 0,
207                    resource: wgpu::BindingResource::TextureView(offscreen_fb.color_view()),
208                },
209                wgpu::BindGroupEntry {
210                    binding: 1,
211                    resource: wgpu::BindingResource::Sampler(&sampler),
212                },
213            ],
214        );
215
216        let blit_pipeline_layout = renderer.create_pipeline_layout(
217            Some("Blit Pipeline Layout"),
218            &[&blit_bind_group_layout],
219            &[],
220        );
221
222        let blit_pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
223            label: Some("Blit Pipeline"),
224            layout: Some(&blit_pipeline_layout),
225            vertex: wgpu::VertexState {
226                module: &blit_shader,
227                entry_point: Some("vs_main"),
228                buffers: &[],
229                compilation_options: wgpu::PipelineCompilationOptions::default(),
230            },
231            fragment: Some(wgpu::FragmentState {
232                module: &blit_shader,
233                entry_point: Some("fs_main"),
234                // Use PremultipliedAlpha for framebuffer blitting
235                targets: &[Some(
236                    BlendMode::PremultipliedAlpha
237                        .to_color_target_state(wgpu::TextureFormat::Bgra8UnormSrgb),
238                )],
239                compilation_options: wgpu::PipelineCompilationOptions::default(),
240            }),
241            primitive: wgpu::PrimitiveState {
242                topology: wgpu::PrimitiveTopology::TriangleList,
243                ..Default::default()
244            },
245            depth_stencil: None,
246            multisample: wgpu::MultisampleState::default(),
247            multiview: None,
248            cache: None,
249        });
250
251        tracing::info!("Renderer initialized successfully");
252        tracing::info!("Device: {:?}", renderer.context().info());
253
254        Box::new(RendererApp {
255            context: graphics_ctx,
256            renderer,
257            window,
258            window_id,
259            pipeline,
260            bind_group,
261            vertex_buffer,
262            offscreen_fb,
263            blit_pipeline,
264            blit_bind_group,
265            time: 0.0,
266        })
267    });
268}
Source

pub fn window(&self) -> &Window

Source

pub fn context(&self) -> &WindowContext

Examples found in repository?
examples/sprite_sheet.rs (line 377)
363    fn update(&mut self, _ctx: &mut astrelis_winit::app::AppCtx) {
364        let now = Instant::now();
365        let dt = now.duration_since(self.last_update).as_secs_f32();
366        self.last_update = now;
367
368        // Update animation
369        if self.animation.update(dt) {
370            // Frame changed - update vertex buffer with new UVs
371            let frame = self.animation.current_frame();
372            let uv = self.sprite_sheet.sprite_uv(frame);
373            let vertices = create_quad_vertices(uv.u_min, uv.v_min, uv.u_max, uv.v_max);
374            
375            // Get context from first window
376            if let Some(window) = self.windows.values().next() {
377                window.context().graphics_context().queue.write_buffer(
378                    &self.vertex_buffer,
379                    0,
380                    bytemuck::cast_slice(&vertices),
381                );
382            }
383        }
384    }
Source

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

Source

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

Handle window resize event

Examples found in repository?
examples/multi_window.rs (line 107)
93    fn render(
94        &mut self,
95        _ctx: &mut astrelis_winit::app::AppCtx,
96        window_id: WindowId,
97        events: &mut astrelis_winit::event::EventBatch,
98    ) {
99        // Get the window and color for this specific window
100        let Some((window, color)) = self.windows.get_mut(&window_id) else {
101            return;
102        };
103
104        // Handle window-specific resize events
105        events.dispatch(|event| {
106            if let astrelis_winit::event::Event::WindowResized(size) = event {
107                window.resized(*size);
108                astrelis_winit::event::HandleStatus::consumed()
109            } else {
110                astrelis_winit::event::HandleStatus::ignored()
111            }
112        });
113
114        // Render this specific window
115        let mut frame = window.begin_drawing();
116
117        {
118            let _render_pass = RenderPassBuilder::new()
119                .label("Multi-Window Render Pass")
120                .target(RenderTarget::Surface)
121                .clear_color(*color)
122                .build(&mut frame);
123        }
124
125        frame.finish();
126    }
More examples
Hide additional examples
examples/image_blitting.rs (line 457)
444    fn render(
445        &mut self,
446        _ctx: &mut astrelis_winit::app::AppCtx,
447        window_id: WindowId,
448        events: &mut astrelis_winit::event::EventBatch,
449    ) {
450        let Some(window) = self.windows.get_mut(&window_id) else {
451            return;
452        };
453
454        // Handle resize
455        events.dispatch(|event| {
456            if let astrelis_winit::event::Event::WindowResized(size) = event {
457                window.resized(*size);
458                astrelis_winit::event::HandleStatus::consumed()
459            } else {
460                astrelis_winit::event::HandleStatus::ignored()
461            }
462        });
463
464        let mut frame = window.begin_drawing();
465
466        {
467            let mut render_pass = RenderPassBuilder::new()
468                .label("Blit Render Pass")
469                .target(RenderTarget::Surface)
470                .clear_color(wgpu::Color {
471                    r: 0.05,
472                    g: 0.05,
473                    b: 0.08,
474                    a: 1.0,
475                })
476                .build(&mut frame);
477
478            let pass = render_pass.descriptor();
479            pass.set_pipeline(&self.pipeline);
480            pass.set_bind_group(0, &self.bind_group, &[]);
481            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
482            pass.draw(0..6, 0..1);
483        }
484
485        frame.finish();
486    }
examples/sprite_sheet.rs (line 399)
386    fn render(
387        &mut self,
388        _ctx: &mut astrelis_winit::app::AppCtx,
389        window_id: WindowId,
390        events: &mut astrelis_winit::event::EventBatch,
391    ) {
392        let Some(window) = self.windows.get_mut(&window_id) else {
393            return;
394        };
395
396        // Handle resize
397        events.dispatch(|event| {
398            if let astrelis_winit::event::Event::WindowResized(size) = event {
399                window.resized(*size);
400                astrelis_winit::event::HandleStatus::consumed()
401            } else {
402                astrelis_winit::event::HandleStatus::ignored()
403            }
404        });
405
406        let mut frame = window.begin_drawing();
407
408        {
409            let mut render_pass = RenderPassBuilder::new()
410                .label("Sprite Render Pass")
411                .target(RenderTarget::Surface)
412                .clear_color(wgpu::Color {
413                    r: 0.1,
414                    g: 0.1,
415                    b: 0.15,
416                    a: 1.0,
417                })
418                .build(&mut frame);
419
420            let pass = render_pass.descriptor();
421            pass.set_pipeline(&self.pipeline);
422            pass.set_bind_group(0, &self.bind_group, &[]);
423            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
424            pass.draw(0..6, 0..1);
425        }
426
427        frame.finish();
428    }
examples/textured_window.rs (line 254)
241    fn render(
242        &mut self,
243        _ctx: &mut astrelis_winit::app::AppCtx,
244        window_id: WindowId,
245        events: &mut astrelis_winit::event::EventBatch,
246    ) {
247        if window_id != self.window_id {
248            return;
249        }
250
251        // Handle window resize events
252        events.dispatch(|event| {
253            if let astrelis_winit::event::Event::WindowResized(size) = event {
254                self.window.resized(*size);
255                astrelis_winit::event::HandleStatus::consumed()
256            } else {
257                astrelis_winit::event::HandleStatus::ignored()
258            }
259        });
260
261        let mut frame = self.window.begin_drawing();
262
263        // Using new simplified RenderPassBuilder API with RenderTarget
264        {
265            let mut render_pass = RenderPassBuilder::new()
266                .label("Render Pass")
267                .target(RenderTarget::Surface)
268                .clear_color(wgpu::Color {
269                    r: 0.1,
270                    g: 0.2,
271                    b: 0.3,
272                    a: 1.0,
273                })
274                .build(&mut frame);
275
276            let pass = render_pass.descriptor();
277            pass.set_pipeline(&self.pipeline);
278            pass.set_bind_group(0, &self.bind_group, &[]);
279            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
280            pass.draw(0..6, 0..1);
281        }
282
283        frame.finish();
284    }
examples/renderer_api.rs (line 284)
276    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
277        if window_id != self.window_id {
278            return;
279        }
280
281        // Handle window-specific resize events
282        events.dispatch(|event| {
283            if let astrelis_winit::event::Event::WindowResized(size) = event {
284                self.window.resized(*size);
285                astrelis_winit::event::HandleStatus::consumed()
286            } else {
287                astrelis_winit::event::HandleStatus::ignored()
288            }
289        });
290
291        let mut frame = self.window.begin_drawing();
292
293        // Pass 1: Render to offscreen framebuffer using new simplified API
294        {
295            let mut render_pass = RenderPassBuilder::new()
296                .label("Offscreen Pass")
297                .target(RenderTarget::Framebuffer(&self.offscreen_fb))
298                .clear_color(wgpu::Color {
299                    r: 0.2,
300                    g: 0.1,
301                    b: 0.3,
302                    a: 1.0,
303                })
304                .build(&mut frame);
305
306            let pass = render_pass.descriptor();
307            pass.set_pipeline(&self.pipeline);
308            pass.set_bind_group(0, &self.bind_group, &[]);
309            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
310            pass.draw(0..6, 0..1);
311        }
312
313        // Pass 2: Blit framebuffer to surface using new simplified API
314        {
315            let mut render_pass = RenderPassBuilder::new()
316                .label("Surface Pass")
317                .target(RenderTarget::Surface)
318                .clear_color(wgpu::Color {
319                    r: 0.1,
320                    g: 0.2,
321                    b: 0.3,
322                    a: 1.0,
323                })
324                .build(&mut frame);
325
326            let pass = render_pass.descriptor();
327            pass.set_pipeline(&self.blit_pipeline);
328            pass.set_bind_group(0, &self.blit_bind_group, &[]);
329            // Draw fullscreen triangle
330            pass.draw(0..3, 0..1);
331        }
332
333        frame.finish();
334    }
Source

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

Get the inner size of the window.

Source

pub fn scale_factor(&self) -> f64

Source

pub fn viewport(&self) -> Viewport

Methods from Deref<Target = WindowContext>§

Source

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

Handle window resize event

Source

pub fn window(&self) -> &Window

Source

pub fn graphics_context(&self) -> &GraphicsContext

Examples found in repository?
examples/sprite_sheet.rs (line 377)
363    fn update(&mut self, _ctx: &mut astrelis_winit::app::AppCtx) {
364        let now = Instant::now();
365        let dt = now.duration_since(self.last_update).as_secs_f32();
366        self.last_update = now;
367
368        // Update animation
369        if self.animation.update(dt) {
370            // Frame changed - update vertex buffer with new UVs
371            let frame = self.animation.current_frame();
372            let uv = self.sprite_sheet.sprite_uv(frame);
373            let vertices = create_quad_vertices(uv.u_min, uv.v_min, uv.u_max, uv.v_max);
374            
375            // Get context from first window
376            if let Some(window) = self.windows.values().next() {
377                window.context().graphics_context().queue.write_buffer(
378                    &self.vertex_buffer,
379                    0,
380                    bytemuck::cast_slice(&vertices),
381                );
382            }
383        }
384    }
Source

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

Source

pub fn surface_config(&self) -> &SurfaceConfiguration

Source

pub fn size(&self) -> Size<u32>

Get the size of the window.

Source

pub fn size_f32(&self) -> Size<f32>

Source

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

Get the inner size of the window.

Source

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

Reconfigure the surface with a new configuration.

Trait Implementations§

Source§

impl Deref for RenderableWindow

Source§

type Target = WindowContext

The resulting type after dereferencing.
Source§

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

Dereferences the value.
Source§

impl DerefMut for RenderableWindow

Source§

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

Mutably dereferences the value.
Source§

impl WindowBackend for RenderableWindow

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 + Send + Sync>

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,