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
impl Renderer
Sourcepub fn new(context: Arc<GraphicsContext>) -> Self
pub fn new(context: Arc<GraphicsContext>) -> Self
Create a new renderer with the given graphics context.
Examples found in repository?
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}Sourcepub fn context(&self) -> &GraphicsContext
pub fn context(&self) -> &GraphicsContext
Get the graphics context.
Examples found in repository?
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}Sourcepub fn create_shader(&self, label: Option<&str>, source: &str) -> ShaderModule
pub fn create_shader(&self, label: Option<&str>, source: &str) -> ShaderModule
Create a shader module from WGSL source.
Examples found in repository?
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}Sourcepub fn create_vertex_buffer<T: Pod>(
&self,
label: Option<&str>,
data: &[T],
) -> Buffer
pub fn create_vertex_buffer<T: Pod>( &self, label: Option<&str>, data: &[T], ) -> Buffer
Create a vertex buffer with data.
Examples found in repository?
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}Sourcepub fn create_index_buffer<T: Pod>(
&self,
label: Option<&str>,
data: &[T],
) -> Buffer
pub fn create_index_buffer<T: Pod>( &self, label: Option<&str>, data: &[T], ) -> Buffer
Create an index buffer with data.
Sourcepub fn create_uniform_buffer<T: Pod>(
&self,
label: Option<&str>,
data: &T,
) -> Buffer
pub fn create_uniform_buffer<T: Pod>( &self, label: Option<&str>, data: &T, ) -> Buffer
Create a uniform buffer with data.
Sourcepub fn update_uniform_buffer<T: Pod>(&self, buffer: &Buffer, data: &T)
pub fn update_uniform_buffer<T: Pod>(&self, buffer: &Buffer, data: &T)
Update a uniform buffer with new data.
Sourcepub fn create_storage_buffer(
&self,
label: Option<&str>,
size: u64,
read_only: bool,
) -> Buffer
pub fn create_storage_buffer( &self, label: Option<&str>, size: u64, read_only: bool, ) -> Buffer
Create an empty storage buffer.
§Arguments
label- Optional debug labelsize- Size in bytesread_only- If true, creates a read-only storage buffer (STORAGE), otherwise creates a read-write storage buffer (STORAGE | COPY_DST)
Sourcepub fn create_storage_buffer_init<T: Pod>(
&self,
label: Option<&str>,
data: &[T],
read_only: bool,
) -> Buffer
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 labeldata- Initial data to write to the bufferread_only- If true, creates a read-only storage buffer, otherwise creates a read-write storage buffer
Sourcepub fn update_storage_buffer<T: Pod>(
&self,
buffer: &Buffer,
offset: u64,
data: &[T],
)
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 updateoffset- Byte offset into the bufferdata- Data to write
Sourcepub fn create_texture(&self, descriptor: &TextureDescriptor<'_>) -> Texture
pub fn create_texture(&self, descriptor: &TextureDescriptor<'_>) -> Texture
Create a texture with descriptor.
Sourcepub fn create_texture_2d(
&self,
label: Option<&str>,
width: u32,
height: u32,
format: TextureFormat,
usage: TextureUsages,
data: &[u8],
) -> Texture
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?
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}Sourcepub fn create_sampler(&self, descriptor: &SamplerDescriptor<'_>) -> Sampler
pub fn create_sampler(&self, descriptor: &SamplerDescriptor<'_>) -> Sampler
Create a sampler with descriptor.
Sourcepub fn create_linear_sampler(&self, label: Option<&str>) -> Sampler
pub fn create_linear_sampler(&self, label: Option<&str>) -> Sampler
Create a simple linear sampler.
Examples found in repository?
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}Sourcepub fn create_nearest_sampler(&self, label: Option<&str>) -> Sampler
pub fn create_nearest_sampler(&self, label: Option<&str>) -> Sampler
Create a simple nearest sampler.
Sourcepub fn create_bind_group_layout(
&self,
label: Option<&str>,
entries: &[BindGroupLayoutEntry],
) -> BindGroupLayout
pub fn create_bind_group_layout( &self, label: Option<&str>, entries: &[BindGroupLayoutEntry], ) -> BindGroupLayout
Create a bind group layout.
Examples found in repository?
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}Sourcepub fn create_bind_group(
&self,
label: Option<&str>,
layout: &BindGroupLayout,
entries: &[BindGroupEntry<'_>],
) -> BindGroup
pub fn create_bind_group( &self, label: Option<&str>, layout: &BindGroupLayout, entries: &[BindGroupEntry<'_>], ) -> BindGroup
Create a bind group.
Examples found in repository?
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}Sourcepub fn create_pipeline_layout(
&self,
label: Option<&str>,
bind_group_layouts: &[&BindGroupLayout],
push_constant_ranges: &[PushConstantRange],
) -> PipelineLayout
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?
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}Sourcepub fn create_render_pipeline(
&self,
descriptor: &RenderPipelineDescriptor<'_>,
) -> RenderPipeline
pub fn create_render_pipeline( &self, descriptor: &RenderPipelineDescriptor<'_>, ) -> RenderPipeline
Create a render pipeline.
Examples found in repository?
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}Sourcepub fn create_compute_pipeline(
&self,
descriptor: &ComputePipelineDescriptor<'_>,
) -> ComputePipeline
pub fn create_compute_pipeline( &self, descriptor: &ComputePipelineDescriptor<'_>, ) -> ComputePipeline
Create a compute pipeline.
Sourcepub fn create_command_encoder(&self, label: Option<&str>) -> CommandEncoder
pub fn create_command_encoder(&self, label: Option<&str>) -> CommandEncoder
Create a command encoder.
Sourcepub fn submit<I>(&self, command_buffers: I)where
I: IntoIterator<Item = CommandBuffer>,
pub fn submit<I>(&self, command_buffers: I)where
I: IntoIterator<Item = CommandBuffer>,
Submit command buffers to the queue.
Sourcepub fn create_typed_vertex_buffer<T: Pod>(
&self,
label: Option<&str>,
data: &[T],
) -> TypedBuffer<T>
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.
Sourcepub fn create_typed_index_buffer<T: Pod>(
&self,
label: Option<&str>,
data: &[T],
) -> TypedBuffer<T>
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.
Sourcepub fn create_typed_uniform<T: Pod>(
&self,
label: Option<&str>,
data: &T,
) -> UniformBuffer<T>
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.
Sourcepub fn create_gpu_texture_2d(
&self,
label: Option<&str>,
width: u32,
height: u32,
format: TextureFormat,
usage: TextureUsages,
) -> GpuTexture
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.
Sourcepub fn create_gpu_texture_from_data(
&self,
label: Option<&str>,
width: u32,
height: u32,
format: TextureFormat,
data: &[u8],
) -> GpuTexture
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§
impl Freeze for Renderer
impl !RefUnwindSafe for Renderer
impl Send for Renderer
impl Sync for Renderer
impl Unpin for Renderer
impl !UnwindSafe for Renderer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&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
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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