Skip to main content

FramebufferBuilder

Struct FramebufferBuilder 

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

Builder for creating framebuffers with optional attachments.

Implementations§

Source§

impl FramebufferBuilder

Source

pub fn new(width: u32, height: u32) -> Self

Create a new framebuffer builder with the given dimensions.

Source

pub fn format(self, format: TextureFormat) -> Self

Set the color format.

Examples found in repository?
examples/renderer_api.rs (line 180)
37fn main() {
38    logging::init();
39
40    run_app(|ctx| {
41        let graphics_ctx =
42            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
43        let renderer = Renderer::new(graphics_ctx.clone());
44
45        let window = ctx
46            .create_window(WindowDescriptor {
47                title: "Renderer API Example".to_string(),
48                size: Some(WinitPhysicalSize::new(800.0, 600.0)),
49                ..Default::default()
50            })
51            .expect("Failed to create window");
52
53        let window = RenderWindowBuilder::new()
54            .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
55            .with_depth_default()
56            .build(window, graphics_ctx.clone())
57            .expect("Failed to create render window");
58
59        let window_id = window.id();
60
61        // Create shader using Renderer API
62        let shader = renderer.create_shader(Some("Color Shader"), SHADER_SOURCE);
63
64        // Create texture using Renderer helper
65        let texture_data = create_gradient_texture();
66        let texture = renderer.create_texture_2d(
67            Some("Gradient Texture"),
68            256,
69            256,
70            wgpu::TextureFormat::Rgba8UnormSrgb,
71            wgpu::TextureUsages::TEXTURE_BINDING,
72            &texture_data,
73        );
74
75        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
76        let sampler = renderer.create_linear_sampler(Some("Linear Sampler"));
77
78        // Create bind group using Renderer API
79        let bind_group_layout = renderer.create_bind_group_layout(
80            Some("Texture Bind Group Layout"),
81            &[
82                wgpu::BindGroupLayoutEntry {
83                    binding: 0,
84                    visibility: wgpu::ShaderStages::FRAGMENT,
85                    ty: wgpu::BindingType::Texture {
86                        multisampled: false,
87                        view_dimension: wgpu::TextureViewDimension::D2,
88                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
89                    },
90                    count: None,
91                },
92                wgpu::BindGroupLayoutEntry {
93                    binding: 1,
94                    visibility: wgpu::ShaderStages::FRAGMENT,
95                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
96                    count: None,
97                },
98            ],
99        );
100
101        let bind_group = renderer.create_bind_group(
102            Some("Texture Bind Group"),
103            &bind_group_layout,
104            &[
105                wgpu::BindGroupEntry {
106                    binding: 0,
107                    resource: wgpu::BindingResource::TextureView(&texture_view),
108                },
109                wgpu::BindGroupEntry {
110                    binding: 1,
111                    resource: wgpu::BindingResource::Sampler(&sampler),
112                },
113            ],
114        );
115
116        let pipeline_layout = renderer.create_pipeline_layout(
117            Some("Render Pipeline Layout"),
118            &[&bind_group_layout],
119            &[],
120        );
121
122        // Create pipeline using Renderer API with BlendMode
123        let pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
124            label: Some("Render Pipeline"),
125            layout: Some(&pipeline_layout),
126            vertex: wgpu::VertexState {
127                module: &shader,
128                entry_point: Some("vs_main"),
129                buffers: &[wgpu::VertexBufferLayout {
130                    // 4 floats × 4 bytes = 16 bytes per vertex (2×f32 pos + 2×f32 UV)
131                    array_stride: 4 * 4,
132                    step_mode: wgpu::VertexStepMode::Vertex,
133                    attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2],
134                }],
135                compilation_options: wgpu::PipelineCompilationOptions::default(),
136            },
137            fragment: Some(wgpu::FragmentState {
138                module: &shader,
139                entry_point: Some("fs_main"),
140                // Use BlendMode for transparent rendering
141                targets: &[Some(
142                    BlendMode::Alpha.to_color_target_state(wgpu::TextureFormat::Rgba8UnormSrgb),
143                )],
144                compilation_options: wgpu::PipelineCompilationOptions::default(),
145            }),
146            primitive: wgpu::PrimitiveState {
147                topology: wgpu::PrimitiveTopology::TriangleList,
148                strip_index_format: None,
149                front_face: wgpu::FrontFace::Ccw,
150                cull_mode: Some(wgpu::Face::Back),
151                polygon_mode: wgpu::PolygonMode::Fill,
152                unclipped_depth: false,
153                conservative: false,
154            },
155            depth_stencil: None,
156            multisample: wgpu::MultisampleState {
157                count: 1,
158                mask: !0,
159                alpha_to_coverage_enabled: false,
160            },
161            multiview: None,
162            cache: None,
163        });
164
165        #[rustfmt::skip]
166        let vertices: &[f32] = &[
167            -0.8, -0.8,  0.0, 1.0,
168             0.8, -0.8,  1.0, 1.0,
169             0.8,  0.8,  1.0, 0.0,
170            -0.8, -0.8,  0.0, 1.0,
171             0.8,  0.8,  1.0, 0.0,
172            -0.8,  0.8,  0.0, 0.0,
173        ];
174
175        // Create vertex buffer using Renderer helper
176        let vertex_buffer = renderer.create_vertex_buffer(Some("Vertex Buffer"), vertices);
177
178        // Create offscreen framebuffer using the new Framebuffer abstraction
179        let offscreen_fb = Framebuffer::builder(400, 300)
180            .format(wgpu::TextureFormat::Rgba8UnormSrgb)
181            .label("Offscreen FB")
182            .build(&graphics_ctx);
183
184        // Create blit shader and pipeline for rendering framebuffer to surface
185        let blit_shader = renderer.create_shader(Some("Blit Shader"), BLIT_SHADER_SOURCE);
186
187        let blit_bind_group_layout = renderer.create_bind_group_layout(
188            Some("Blit Bind Group Layout"),
189            &[
190                wgpu::BindGroupLayoutEntry {
191                    binding: 0,
192                    visibility: wgpu::ShaderStages::FRAGMENT,
193                    ty: wgpu::BindingType::Texture {
194                        multisampled: false,
195                        view_dimension: wgpu::TextureViewDimension::D2,
196                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
197                    },
198                    count: None,
199                },
200                wgpu::BindGroupLayoutEntry {
201                    binding: 1,
202                    visibility: wgpu::ShaderStages::FRAGMENT,
203                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
204                    count: None,
205                },
206            ],
207        );
208
209        let blit_bind_group = renderer.create_bind_group(
210            Some("Blit Bind Group"),
211            &blit_bind_group_layout,
212            &[
213                wgpu::BindGroupEntry {
214                    binding: 0,
215                    resource: wgpu::BindingResource::TextureView(offscreen_fb.color_view()),
216                },
217                wgpu::BindGroupEntry {
218                    binding: 1,
219                    resource: wgpu::BindingResource::Sampler(&sampler),
220                },
221            ],
222        );
223
224        let blit_pipeline_layout = renderer.create_pipeline_layout(
225            Some("Blit Pipeline Layout"),
226            &[&blit_bind_group_layout],
227            &[],
228        );
229
230        let blit_pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
231            label: Some("Blit Pipeline"),
232            layout: Some(&blit_pipeline_layout),
233            vertex: wgpu::VertexState {
234                module: &blit_shader,
235                entry_point: Some("vs_main"),
236                buffers: &[],
237                compilation_options: wgpu::PipelineCompilationOptions::default(),
238            },
239            fragment: Some(wgpu::FragmentState {
240                module: &blit_shader,
241                entry_point: Some("fs_main"),
242                // Use PremultipliedAlpha for framebuffer blitting
243                targets: &[Some(
244                    BlendMode::PremultipliedAlpha
245                        .to_color_target_state(wgpu::TextureFormat::Bgra8UnormSrgb),
246                )],
247                compilation_options: wgpu::PipelineCompilationOptions::default(),
248            }),
249            primitive: wgpu::PrimitiveState {
250                topology: wgpu::PrimitiveTopology::TriangleList,
251                ..Default::default()
252            },
253            depth_stencil: None,
254            multisample: wgpu::MultisampleState::default(),
255            multiview: None,
256            cache: None,
257        });
258
259        tracing::info!("Renderer initialized successfully");
260        tracing::info!("Device: {:?}", renderer.context().info());
261
262        Box::new(RendererApp {
263            _context: graphics_ctx,
264            _renderer: renderer,
265            window,
266            window_id,
267            pipeline,
268            bind_group,
269            vertex_buffer,
270            offscreen_fb,
271            blit_pipeline,
272            blit_bind_group,
273            time: 0.0,
274        })
275    });
276}
Source

pub fn with_msaa(self, sample_count: u32) -> Self

Enable MSAA with the given sample count (typically 4).

Source

pub fn sample_count_if(self, condition: bool, sample_count: u32) -> Self

Conditionally set sample count.

Source

pub fn with_depth(self) -> Self

Enable depth buffer.

Source

pub fn depth_if(self, condition: bool) -> Self

Conditionally enable depth buffer.

Source

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

Set a debug label for the framebuffer textures.

Examples found in repository?
examples/renderer_api.rs (line 181)
37fn main() {
38    logging::init();
39
40    run_app(|ctx| {
41        let graphics_ctx =
42            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
43        let renderer = Renderer::new(graphics_ctx.clone());
44
45        let window = ctx
46            .create_window(WindowDescriptor {
47                title: "Renderer API Example".to_string(),
48                size: Some(WinitPhysicalSize::new(800.0, 600.0)),
49                ..Default::default()
50            })
51            .expect("Failed to create window");
52
53        let window = RenderWindowBuilder::new()
54            .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
55            .with_depth_default()
56            .build(window, graphics_ctx.clone())
57            .expect("Failed to create render window");
58
59        let window_id = window.id();
60
61        // Create shader using Renderer API
62        let shader = renderer.create_shader(Some("Color Shader"), SHADER_SOURCE);
63
64        // Create texture using Renderer helper
65        let texture_data = create_gradient_texture();
66        let texture = renderer.create_texture_2d(
67            Some("Gradient Texture"),
68            256,
69            256,
70            wgpu::TextureFormat::Rgba8UnormSrgb,
71            wgpu::TextureUsages::TEXTURE_BINDING,
72            &texture_data,
73        );
74
75        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
76        let sampler = renderer.create_linear_sampler(Some("Linear Sampler"));
77
78        // Create bind group using Renderer API
79        let bind_group_layout = renderer.create_bind_group_layout(
80            Some("Texture Bind Group Layout"),
81            &[
82                wgpu::BindGroupLayoutEntry {
83                    binding: 0,
84                    visibility: wgpu::ShaderStages::FRAGMENT,
85                    ty: wgpu::BindingType::Texture {
86                        multisampled: false,
87                        view_dimension: wgpu::TextureViewDimension::D2,
88                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
89                    },
90                    count: None,
91                },
92                wgpu::BindGroupLayoutEntry {
93                    binding: 1,
94                    visibility: wgpu::ShaderStages::FRAGMENT,
95                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
96                    count: None,
97                },
98            ],
99        );
100
101        let bind_group = renderer.create_bind_group(
102            Some("Texture Bind Group"),
103            &bind_group_layout,
104            &[
105                wgpu::BindGroupEntry {
106                    binding: 0,
107                    resource: wgpu::BindingResource::TextureView(&texture_view),
108                },
109                wgpu::BindGroupEntry {
110                    binding: 1,
111                    resource: wgpu::BindingResource::Sampler(&sampler),
112                },
113            ],
114        );
115
116        let pipeline_layout = renderer.create_pipeline_layout(
117            Some("Render Pipeline Layout"),
118            &[&bind_group_layout],
119            &[],
120        );
121
122        // Create pipeline using Renderer API with BlendMode
123        let pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
124            label: Some("Render Pipeline"),
125            layout: Some(&pipeline_layout),
126            vertex: wgpu::VertexState {
127                module: &shader,
128                entry_point: Some("vs_main"),
129                buffers: &[wgpu::VertexBufferLayout {
130                    // 4 floats × 4 bytes = 16 bytes per vertex (2×f32 pos + 2×f32 UV)
131                    array_stride: 4 * 4,
132                    step_mode: wgpu::VertexStepMode::Vertex,
133                    attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2],
134                }],
135                compilation_options: wgpu::PipelineCompilationOptions::default(),
136            },
137            fragment: Some(wgpu::FragmentState {
138                module: &shader,
139                entry_point: Some("fs_main"),
140                // Use BlendMode for transparent rendering
141                targets: &[Some(
142                    BlendMode::Alpha.to_color_target_state(wgpu::TextureFormat::Rgba8UnormSrgb),
143                )],
144                compilation_options: wgpu::PipelineCompilationOptions::default(),
145            }),
146            primitive: wgpu::PrimitiveState {
147                topology: wgpu::PrimitiveTopology::TriangleList,
148                strip_index_format: None,
149                front_face: wgpu::FrontFace::Ccw,
150                cull_mode: Some(wgpu::Face::Back),
151                polygon_mode: wgpu::PolygonMode::Fill,
152                unclipped_depth: false,
153                conservative: false,
154            },
155            depth_stencil: None,
156            multisample: wgpu::MultisampleState {
157                count: 1,
158                mask: !0,
159                alpha_to_coverage_enabled: false,
160            },
161            multiview: None,
162            cache: None,
163        });
164
165        #[rustfmt::skip]
166        let vertices: &[f32] = &[
167            -0.8, -0.8,  0.0, 1.0,
168             0.8, -0.8,  1.0, 1.0,
169             0.8,  0.8,  1.0, 0.0,
170            -0.8, -0.8,  0.0, 1.0,
171             0.8,  0.8,  1.0, 0.0,
172            -0.8,  0.8,  0.0, 0.0,
173        ];
174
175        // Create vertex buffer using Renderer helper
176        let vertex_buffer = renderer.create_vertex_buffer(Some("Vertex Buffer"), vertices);
177
178        // Create offscreen framebuffer using the new Framebuffer abstraction
179        let offscreen_fb = Framebuffer::builder(400, 300)
180            .format(wgpu::TextureFormat::Rgba8UnormSrgb)
181            .label("Offscreen FB")
182            .build(&graphics_ctx);
183
184        // Create blit shader and pipeline for rendering framebuffer to surface
185        let blit_shader = renderer.create_shader(Some("Blit Shader"), BLIT_SHADER_SOURCE);
186
187        let blit_bind_group_layout = renderer.create_bind_group_layout(
188            Some("Blit Bind Group Layout"),
189            &[
190                wgpu::BindGroupLayoutEntry {
191                    binding: 0,
192                    visibility: wgpu::ShaderStages::FRAGMENT,
193                    ty: wgpu::BindingType::Texture {
194                        multisampled: false,
195                        view_dimension: wgpu::TextureViewDimension::D2,
196                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
197                    },
198                    count: None,
199                },
200                wgpu::BindGroupLayoutEntry {
201                    binding: 1,
202                    visibility: wgpu::ShaderStages::FRAGMENT,
203                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
204                    count: None,
205                },
206            ],
207        );
208
209        let blit_bind_group = renderer.create_bind_group(
210            Some("Blit Bind Group"),
211            &blit_bind_group_layout,
212            &[
213                wgpu::BindGroupEntry {
214                    binding: 0,
215                    resource: wgpu::BindingResource::TextureView(offscreen_fb.color_view()),
216                },
217                wgpu::BindGroupEntry {
218                    binding: 1,
219                    resource: wgpu::BindingResource::Sampler(&sampler),
220                },
221            ],
222        );
223
224        let blit_pipeline_layout = renderer.create_pipeline_layout(
225            Some("Blit Pipeline Layout"),
226            &[&blit_bind_group_layout],
227            &[],
228        );
229
230        let blit_pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
231            label: Some("Blit Pipeline"),
232            layout: Some(&blit_pipeline_layout),
233            vertex: wgpu::VertexState {
234                module: &blit_shader,
235                entry_point: Some("vs_main"),
236                buffers: &[],
237                compilation_options: wgpu::PipelineCompilationOptions::default(),
238            },
239            fragment: Some(wgpu::FragmentState {
240                module: &blit_shader,
241                entry_point: Some("fs_main"),
242                // Use PremultipliedAlpha for framebuffer blitting
243                targets: &[Some(
244                    BlendMode::PremultipliedAlpha
245                        .to_color_target_state(wgpu::TextureFormat::Bgra8UnormSrgb),
246                )],
247                compilation_options: wgpu::PipelineCompilationOptions::default(),
248            }),
249            primitive: wgpu::PrimitiveState {
250                topology: wgpu::PrimitiveTopology::TriangleList,
251                ..Default::default()
252            },
253            depth_stencil: None,
254            multisample: wgpu::MultisampleState::default(),
255            multiview: None,
256            cache: None,
257        });
258
259        tracing::info!("Renderer initialized successfully");
260        tracing::info!("Device: {:?}", renderer.context().info());
261
262        Box::new(RendererApp {
263            _context: graphics_ctx,
264            _renderer: renderer,
265            window,
266            window_id,
267            pipeline,
268            bind_group,
269            vertex_buffer,
270            offscreen_fb,
271            blit_pipeline,
272            blit_bind_group,
273            time: 0.0,
274        })
275    });
276}
Source

pub fn build(self, context: &GraphicsContext) -> Framebuffer

Build the framebuffer.

Examples found in repository?
examples/renderer_api.rs (line 182)
37fn main() {
38    logging::init();
39
40    run_app(|ctx| {
41        let graphics_ctx =
42            GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
43        let renderer = Renderer::new(graphics_ctx.clone());
44
45        let window = ctx
46            .create_window(WindowDescriptor {
47                title: "Renderer API Example".to_string(),
48                size: Some(WinitPhysicalSize::new(800.0, 600.0)),
49                ..Default::default()
50            })
51            .expect("Failed to create window");
52
53        let window = RenderWindowBuilder::new()
54            .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
55            .with_depth_default()
56            .build(window, graphics_ctx.clone())
57            .expect("Failed to create render window");
58
59        let window_id = window.id();
60
61        // Create shader using Renderer API
62        let shader = renderer.create_shader(Some("Color Shader"), SHADER_SOURCE);
63
64        // Create texture using Renderer helper
65        let texture_data = create_gradient_texture();
66        let texture = renderer.create_texture_2d(
67            Some("Gradient Texture"),
68            256,
69            256,
70            wgpu::TextureFormat::Rgba8UnormSrgb,
71            wgpu::TextureUsages::TEXTURE_BINDING,
72            &texture_data,
73        );
74
75        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
76        let sampler = renderer.create_linear_sampler(Some("Linear Sampler"));
77
78        // Create bind group using Renderer API
79        let bind_group_layout = renderer.create_bind_group_layout(
80            Some("Texture Bind Group Layout"),
81            &[
82                wgpu::BindGroupLayoutEntry {
83                    binding: 0,
84                    visibility: wgpu::ShaderStages::FRAGMENT,
85                    ty: wgpu::BindingType::Texture {
86                        multisampled: false,
87                        view_dimension: wgpu::TextureViewDimension::D2,
88                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
89                    },
90                    count: None,
91                },
92                wgpu::BindGroupLayoutEntry {
93                    binding: 1,
94                    visibility: wgpu::ShaderStages::FRAGMENT,
95                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
96                    count: None,
97                },
98            ],
99        );
100
101        let bind_group = renderer.create_bind_group(
102            Some("Texture Bind Group"),
103            &bind_group_layout,
104            &[
105                wgpu::BindGroupEntry {
106                    binding: 0,
107                    resource: wgpu::BindingResource::TextureView(&texture_view),
108                },
109                wgpu::BindGroupEntry {
110                    binding: 1,
111                    resource: wgpu::BindingResource::Sampler(&sampler),
112                },
113            ],
114        );
115
116        let pipeline_layout = renderer.create_pipeline_layout(
117            Some("Render Pipeline Layout"),
118            &[&bind_group_layout],
119            &[],
120        );
121
122        // Create pipeline using Renderer API with BlendMode
123        let pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
124            label: Some("Render Pipeline"),
125            layout: Some(&pipeline_layout),
126            vertex: wgpu::VertexState {
127                module: &shader,
128                entry_point: Some("vs_main"),
129                buffers: &[wgpu::VertexBufferLayout {
130                    // 4 floats × 4 bytes = 16 bytes per vertex (2×f32 pos + 2×f32 UV)
131                    array_stride: 4 * 4,
132                    step_mode: wgpu::VertexStepMode::Vertex,
133                    attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2],
134                }],
135                compilation_options: wgpu::PipelineCompilationOptions::default(),
136            },
137            fragment: Some(wgpu::FragmentState {
138                module: &shader,
139                entry_point: Some("fs_main"),
140                // Use BlendMode for transparent rendering
141                targets: &[Some(
142                    BlendMode::Alpha.to_color_target_state(wgpu::TextureFormat::Rgba8UnormSrgb),
143                )],
144                compilation_options: wgpu::PipelineCompilationOptions::default(),
145            }),
146            primitive: wgpu::PrimitiveState {
147                topology: wgpu::PrimitiveTopology::TriangleList,
148                strip_index_format: None,
149                front_face: wgpu::FrontFace::Ccw,
150                cull_mode: Some(wgpu::Face::Back),
151                polygon_mode: wgpu::PolygonMode::Fill,
152                unclipped_depth: false,
153                conservative: false,
154            },
155            depth_stencil: None,
156            multisample: wgpu::MultisampleState {
157                count: 1,
158                mask: !0,
159                alpha_to_coverage_enabled: false,
160            },
161            multiview: None,
162            cache: None,
163        });
164
165        #[rustfmt::skip]
166        let vertices: &[f32] = &[
167            -0.8, -0.8,  0.0, 1.0,
168             0.8, -0.8,  1.0, 1.0,
169             0.8,  0.8,  1.0, 0.0,
170            -0.8, -0.8,  0.0, 1.0,
171             0.8,  0.8,  1.0, 0.0,
172            -0.8,  0.8,  0.0, 0.0,
173        ];
174
175        // Create vertex buffer using Renderer helper
176        let vertex_buffer = renderer.create_vertex_buffer(Some("Vertex Buffer"), vertices);
177
178        // Create offscreen framebuffer using the new Framebuffer abstraction
179        let offscreen_fb = Framebuffer::builder(400, 300)
180            .format(wgpu::TextureFormat::Rgba8UnormSrgb)
181            .label("Offscreen FB")
182            .build(&graphics_ctx);
183
184        // Create blit shader and pipeline for rendering framebuffer to surface
185        let blit_shader = renderer.create_shader(Some("Blit Shader"), BLIT_SHADER_SOURCE);
186
187        let blit_bind_group_layout = renderer.create_bind_group_layout(
188            Some("Blit Bind Group Layout"),
189            &[
190                wgpu::BindGroupLayoutEntry {
191                    binding: 0,
192                    visibility: wgpu::ShaderStages::FRAGMENT,
193                    ty: wgpu::BindingType::Texture {
194                        multisampled: false,
195                        view_dimension: wgpu::TextureViewDimension::D2,
196                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
197                    },
198                    count: None,
199                },
200                wgpu::BindGroupLayoutEntry {
201                    binding: 1,
202                    visibility: wgpu::ShaderStages::FRAGMENT,
203                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
204                    count: None,
205                },
206            ],
207        );
208
209        let blit_bind_group = renderer.create_bind_group(
210            Some("Blit Bind Group"),
211            &blit_bind_group_layout,
212            &[
213                wgpu::BindGroupEntry {
214                    binding: 0,
215                    resource: wgpu::BindingResource::TextureView(offscreen_fb.color_view()),
216                },
217                wgpu::BindGroupEntry {
218                    binding: 1,
219                    resource: wgpu::BindingResource::Sampler(&sampler),
220                },
221            ],
222        );
223
224        let blit_pipeline_layout = renderer.create_pipeline_layout(
225            Some("Blit Pipeline Layout"),
226            &[&blit_bind_group_layout],
227            &[],
228        );
229
230        let blit_pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
231            label: Some("Blit Pipeline"),
232            layout: Some(&blit_pipeline_layout),
233            vertex: wgpu::VertexState {
234                module: &blit_shader,
235                entry_point: Some("vs_main"),
236                buffers: &[],
237                compilation_options: wgpu::PipelineCompilationOptions::default(),
238            },
239            fragment: Some(wgpu::FragmentState {
240                module: &blit_shader,
241                entry_point: Some("fs_main"),
242                // Use PremultipliedAlpha for framebuffer blitting
243                targets: &[Some(
244                    BlendMode::PremultipliedAlpha
245                        .to_color_target_state(wgpu::TextureFormat::Bgra8UnormSrgb),
246                )],
247                compilation_options: wgpu::PipelineCompilationOptions::default(),
248            }),
249            primitive: wgpu::PrimitiveState {
250                topology: wgpu::PrimitiveTopology::TriangleList,
251                ..Default::default()
252            },
253            depth_stencil: None,
254            multisample: wgpu::MultisampleState::default(),
255            multiview: None,
256            cache: None,
257        });
258
259        tracing::info!("Renderer initialized successfully");
260        tracing::info!("Device: {:?}", renderer.context().info());
261
262        Box::new(RendererApp {
263            _context: graphics_ctx,
264            _renderer: renderer,
265            window,
266            window_id,
267            pipeline,
268            bind_group,
269            vertex_buffer,
270            offscreen_fb,
271            blit_pipeline,
272            blit_bind_group,
273            time: 0.0,
274        })
275    });
276}

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

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

Source§

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

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

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

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

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

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

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

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

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

Source§

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

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

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

fn in_current_span(self) -> Instrumented<Self>

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

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> IntoEither for T

Source§

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

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

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

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

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