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