Skip to main content

Renderer

Struct Renderer 

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

Low-level extensible renderer that simplifies WGPU resource management.

This provides a foundation for higher-level renderers like TextRenderer, SceneRenderer, etc. It manages common rendering state and provides utilities for resource creation.

Implementations§

Source§

impl Renderer

Source

pub fn new(context: Arc<GraphicsContext>) -> Self

Create a new renderer with the given graphics context.

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

pub fn context(&self) -> &GraphicsContext

Get the graphics context.

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

pub fn device(&self) -> &Device

Get the device.

Source

pub fn queue(&self) -> &Queue

Get the queue.

Source

pub fn create_shader(&self, label: Option<&str>, source: &str) -> ShaderModule

Create a shader module from WGSL source.

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

pub fn create_vertex_buffer<T: Pod>( &self, label: Option<&str>, data: &[T], ) -> Buffer

Create a vertex buffer with data.

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

pub fn create_index_buffer<T: Pod>( &self, label: Option<&str>, data: &[T], ) -> Buffer

Create an index buffer with data.

Source

pub fn create_uniform_buffer<T: Pod>( &self, label: Option<&str>, data: &T, ) -> Buffer

Create a uniform buffer with data.

Source

pub fn update_uniform_buffer<T: Pod>(&self, buffer: &Buffer, data: &T)

Update a uniform buffer with new data.

Source

pub fn create_storage_buffer( &self, label: Option<&str>, size: u64, read_only: bool, ) -> Buffer

Create an empty storage buffer.

§Arguments
  • label - Optional debug label
  • size - Size in bytes
  • read_only - If true, creates a read-only storage buffer (STORAGE), otherwise creates a read-write storage buffer (STORAGE | COPY_DST)
Source

pub fn create_storage_buffer_init<T: Pod>( &self, label: Option<&str>, data: &[T], read_only: bool, ) -> Buffer

Create a storage buffer initialized with data.

§Arguments
  • label - Optional debug label
  • data - Initial data to write to the buffer
  • read_only - If true, creates a read-only storage buffer, otherwise creates a read-write storage buffer
Source

pub fn update_storage_buffer<T: Pod>( &self, buffer: &Buffer, offset: u64, data: &[T], )

Update a storage buffer with new data at the specified offset.

§Arguments
  • buffer - The buffer to update
  • offset - Byte offset into the buffer
  • data - Data to write
Source

pub fn create_texture(&self, descriptor: &TextureDescriptor<'_>) -> Texture

Create a texture with descriptor.

Source

pub fn create_texture_2d( &self, label: Option<&str>, width: u32, height: u32, format: TextureFormat, usage: TextureUsages, data: &[u8], ) -> Texture

Create a 2D texture with data.

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

pub fn create_sampler(&self, descriptor: &SamplerDescriptor<'_>) -> Sampler

Create a sampler with descriptor.

Source

pub fn create_linear_sampler(&self, label: Option<&str>) -> Sampler

Create a simple linear sampler.

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

pub fn create_nearest_sampler(&self, label: Option<&str>) -> Sampler

Create a simple nearest sampler.

Source

pub fn create_bind_group_layout( &self, label: Option<&str>, entries: &[BindGroupLayoutEntry], ) -> BindGroupLayout

Create a bind group layout.

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

pub fn create_bind_group( &self, label: Option<&str>, layout: &BindGroupLayout, entries: &[BindGroupEntry<'_>], ) -> BindGroup

Create a bind group.

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

pub fn create_pipeline_layout( &self, label: Option<&str>, bind_group_layouts: &[&BindGroupLayout], push_constant_ranges: &[PushConstantRange], ) -> PipelineLayout

Create a pipeline layout.

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

pub fn create_render_pipeline( &self, descriptor: &RenderPipelineDescriptor<'_>, ) -> RenderPipeline

Create a render pipeline.

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

pub fn create_compute_pipeline( &self, descriptor: &ComputePipelineDescriptor<'_>, ) -> ComputePipeline

Create a compute pipeline.

Source

pub fn create_command_encoder(&self, label: Option<&str>) -> CommandEncoder

Create a command encoder.

Source

pub fn submit<I>(&self, command_buffers: I)
where I: IntoIterator<Item = CommandBuffer>,

Submit command buffers to the queue.

Source

pub fn create_typed_vertex_buffer<T: Pod>( &self, label: Option<&str>, data: &[T], ) -> TypedBuffer<T>

Create a typed vertex buffer with data.

Returns a TypedBuffer<T> that tracks element count and provides type-safe operations.

Source

pub fn create_typed_index_buffer<T: Pod>( &self, label: Option<&str>, data: &[T], ) -> TypedBuffer<T>

Create a typed index buffer with data.

Returns a TypedBuffer<T> that tracks element count and provides type-safe operations.

Source

pub fn create_typed_uniform<T: Pod>( &self, label: Option<&str>, data: &T, ) -> UniformBuffer<T>

Create a typed uniform buffer with data.

Returns a UniformBuffer<T> that provides type-safe uniform operations.

Source

pub fn create_gpu_texture_2d( &self, label: Option<&str>, width: u32, height: u32, format: TextureFormat, usage: TextureUsages, ) -> GpuTexture

Create a GPU texture with cached view and metadata.

Returns a GpuTexture that provides convenient access to the texture, view, and metadata.

Source

pub fn create_gpu_texture_from_data( &self, label: Option<&str>, width: u32, height: u32, format: TextureFormat, data: &[u8], ) -> GpuTexture

Create a GPU texture from raw data.

Returns a GpuTexture with data uploaded to the GPU.

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,