+71
-11
src/lib.rs
+71
-11
src/lib.rs
···
8
8
#[cfg(target_arch = "wasm32")]
9
9
use wasm_bindgen::prelude::*;
10
10
11
-
struct State<'a> {
12
-
surface: wgpu::Surface<'a>,
11
+
struct State<'srfc> {
12
+
surface: wgpu::Surface<'srfc>,
13
13
device: wgpu::Device,
14
14
queue: wgpu::Queue,
15
15
config: wgpu::SurfaceConfiguration,
16
16
size: winit::dpi::PhysicalSize<u32>,
17
+
render_pipeline: wgpu::RenderPipeline,
17
18
18
19
// Window must be declared after surface
19
20
// so it gets dropped after it
20
21
// The surface contains unsafe references to the
21
22
// window's resources.
22
23
// src: learn wgpu
23
-
window: &'a Window,
24
-
24
+
window: &'srfc Window,
25
+
25
26
clear_color: wgpu::Color
26
27
}
27
28
···
97
98
desired_maximum_frame_latency: 2,
98
99
};
99
100
101
+
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
102
+
label: Some("Shader"),
103
+
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into())
104
+
});
105
+
106
+
let render_pipeline_layout =
107
+
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
108
+
label: Some("Render Pipeline Layout"),
109
+
bind_group_layouts: &[],
110
+
push_constant_ranges: &[]
111
+
});
112
+
113
+
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
114
+
label: Some("Render Pipeline"),
115
+
layout: Some(&render_pipeline_layout),
116
+
vertex: wgpu::VertexState {
117
+
module: &shader,
118
+
entry_point: "vs_main",
119
+
buffers: &[],
120
+
compilation_options: wgpu::PipelineCompilationOptions::default(),
121
+
},
122
+
fragment: Some(wgpu::FragmentState {
123
+
module: &shader,
124
+
entry_point: "fs_main",
125
+
targets: &[Some(wgpu::ColorTargetState {
126
+
format: config.format,
127
+
blend: Some(wgpu::BlendState::REPLACE),
128
+
write_mask: wgpu::ColorWrites::ALL,
129
+
})],
130
+
compilation_options: wgpu::PipelineCompilationOptions::default(),
131
+
}),
132
+
primitive: wgpu::PrimitiveState {
133
+
topology: wgpu::PrimitiveTopology::TriangleList,
134
+
strip_index_format: None,
135
+
front_face: wgpu::FrontFace::Ccw,
136
+
cull_mode: Some(wgpu::Face::Back),
137
+
polygon_mode: wgpu::PolygonMode::Fill,
138
+
unclipped_depth: false,
139
+
conservative: false,
140
+
},
141
+
depth_stencil: None,
142
+
multisample: wgpu::MultisampleState {
143
+
count: 1,
144
+
mask: !0,
145
+
alpha_to_coverage_enabled: false
146
+
},
147
+
multiview: None,
148
+
cache: None,
149
+
});
150
+
100
151
Self {
101
152
window,
102
153
surface,
···
104
155
queue,
105
156
config,
106
157
size,
107
-
clear_color: wgpu::Color::RED
158
+
render_pipeline,
159
+
clear_color: wgpu::Color {
160
+
r: 0.1,
161
+
g: 0.2,
162
+
b: 0.3,
163
+
a: 1.0
164
+
}
108
165
}
109
166
}
110
167
···
131
188
r: position.x / (self.window.inner_size().width as f64),
132
189
g: 0.2,
133
190
b: position.y / (self.window.inner_size().height as f64),
134
-
a: 1.0
191
+
a: 0.1
135
192
};
136
193
return true;
137
194
},
138
195
_ => {}
139
196
}
140
-
197
+
141
198
false
142
199
}
143
200
···
153
210
label: Some("Render Encoder")
154
211
});
155
212
156
-
let render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
213
+
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
157
214
label: Some("Render Pass"),
158
215
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
159
216
view: &view,
···
167
224
occlusion_query_set: None,
168
225
timestamp_writes: None,
169
226
});
227
+
228
+
render_pass.set_pipeline(&self.render_pipeline);
229
+
render_pass.draw(0..3, 0..1);
170
230
171
231
// drop render pass before we submit to drop the mut borrow on encoder
172
232
drop(render_pass);
···
210
270
Some(())
211
271
})
212
272
.expect("Couldn't append canvas to document body.");
213
-
273
+
214
274
let _ = window.request_inner_size(PhysicalSize::new(450, 400));
215
275
}
216
276
···
239
299
}
240
300
WindowEvent::RedrawRequested => {
241
301
state.window().request_redraw();
242
-
302
+
243
303
if !surface_configured {
244
304
return;
245
305
}
246
-
306
+
247
307
state.update();
248
308
match state.render() {
249
309
Ok(_) => {}
+24
src/shader.wgsl
+24
src/shader.wgsl
···
1
+
// Vertex shader
2
+
3
+
struct VertexOutput {
4
+
@builtin(position) clip_position: vec4<f32>,
5
+
};
6
+
7
+
@vertex
8
+
fn vs_main(
9
+
@builtin(vertex_index) in_vertex_index: u32,
10
+
) -> VertexOutput {
11
+
var out: VertexOutput;
12
+
let x = f32(1 - i32(in_vertex_index)) * 0.5;
13
+
let y = f32(i32(in_vertex_index & 1u) * 2 - 1) * 0.5;
14
+
out.clip_position = vec4<f32>(x, y, 0.0, 1.0);
15
+
return out;
16
+
}
17
+
18
+
19
+
// Fragment shader
20
+
21
+
@fragment
22
+
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
23
+
return vec4<f32>(0.3, 0.2, 0.1, 1.0);
24
+
}