Skip to content

Commit c2b670d

Browse files
committed
refactor(modules): refactor code into modules
1 parent 66bc647 commit c2b670d

File tree

4 files changed

+158
-119
lines changed

4 files changed

+158
-119
lines changed

src/geometry.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
pub fn generate_circle_vertices(radius: f32, segments: usize) -> Vec<f32> {
2+
let mut vertices = Vec::with_capacity(segments * 3);
3+
let step = std::f32::consts::TAU / segments as f32;
4+
5+
for i in 0..segments {
6+
let angle = step * i as f32;
7+
let x = radius * angle.cos();
8+
let y = radius * angle.sin();
9+
vertices.push(x);
10+
vertices.push(y);
11+
vertices.push(0.0); // z
12+
}
13+
vertices
14+
}
15+
16+
pub fn generate_circle_indices(segments: usize) -> Vec<u32> {
17+
let mut indices = Vec::with_capacity(segments + 1);
18+
for i in 0..segments as u32 {
19+
indices.push(i);
20+
}
21+
// Close the loop by going back to the first vertex
22+
indices.push(0);
23+
indices
24+
}

src/main.rs

Lines changed: 31 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,17 @@
1-
use bytemuck::{Pod, Zeroable};
21
use wgpu::util::DeviceExt;
32
use winit::{
43
event::*,
54
event_loop::{ControlFlow, EventLoop},
65
window::WindowBuilder,
76
};
87

9-
#[repr(C)]
10-
#[derive(Copy, Clone, Pod, Zeroable)]
11-
struct Uniforms {
12-
aspect_ratio: f32,
13-
}
14-
15-
#[repr(C)]
16-
#[derive(Copy, Clone, Pod, Zeroable)]
17-
struct InstanceData {
18-
model_matrix: [[f32; 4]; 4],
19-
}
20-
21-
enum ShapeType {
22-
Circle,
23-
Triangle,
24-
}
25-
26-
struct Shape {
27-
shape_type: ShapeType,
28-
position: glam::Vec3,
29-
scale: f32,
30-
instance_buffer: wgpu::Buffer,
31-
bind_group: wgpu::BindGroup,
32-
}
33-
34-
impl Shape {
35-
fn new_circle(
36-
device: &wgpu::Device,
37-
bind_group_layout: &wgpu::BindGroupLayout,
38-
position: glam::Vec3,
39-
scale: f32,
40-
) -> Self {
41-
let instance_data = InstanceData {
42-
model_matrix: (glam::Mat4::from_translation(position)
43-
* glam::Mat4::from_scale(glam::Vec3::splat(scale)))
44-
.to_cols_array_2d(),
45-
};
46-
let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
47-
label: Some("Circle Instance Buffer"),
48-
contents: bytemuck::cast_slice(&[instance_data]),
49-
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
50-
});
51-
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
52-
layout: bind_group_layout,
53-
entries: &[wgpu::BindGroupEntry {
54-
binding: 0,
55-
resource: instance_buffer.as_entire_binding(),
56-
}],
57-
label: Some("Circle Bind Group"),
58-
});
59-
Self {
60-
shape_type: ShapeType::Circle,
61-
position,
62-
scale,
63-
instance_buffer,
64-
bind_group,
65-
}
66-
}
8+
mod geometry;
9+
mod shape;
10+
mod uniforms;
6711

68-
fn new_triangle(
69-
device: &wgpu::Device,
70-
bind_group_layout: &wgpu::BindGroupLayout,
71-
position: glam::Vec3,
72-
scale: f32,
73-
) -> Self {
74-
let instance_data = InstanceData {
75-
model_matrix: (glam::Mat4::from_translation(position)
76-
* glam::Mat4::from_scale(glam::Vec3::splat(scale)))
77-
.to_cols_array_2d(),
78-
};
79-
let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
80-
label: Some("Triangle Instance Buffer"),
81-
contents: bytemuck::cast_slice(&[instance_data]),
82-
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
83-
});
84-
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
85-
layout: bind_group_layout,
86-
entries: &[wgpu::BindGroupEntry {
87-
binding: 0,
88-
resource: instance_buffer.as_entire_binding(),
89-
}],
90-
label: Some("Triangle Bind Group"),
91-
});
92-
Self {
93-
shape_type: ShapeType::Triangle,
94-
position,
95-
scale,
96-
instance_buffer,
97-
bind_group,
98-
}
99-
}
100-
}
12+
use geometry::{generate_circle_indices, generate_circle_vertices};
13+
use shape::{Shape, ShapeType};
14+
use uniforms::Uniforms;
10115

10216
#[tokio::main]
10317
async fn main() {
@@ -153,7 +67,7 @@ async fn main() {
15367
surface.configure(&device, &surface_config);
15468

15569
// -------------------------------------
156-
// Uniform Buffer and Bind Group
70+
// Bind Group Layout for instances
15771
// -------------------------------------
15872
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
15973
label: Some("Instance Bind Group Layout"),
@@ -168,9 +82,14 @@ async fn main() {
16882
count: None,
16983
}],
17084
});
85+
86+
// -------------------------------------
87+
// Uniform Buffer and Bind Group
88+
// -------------------------------------
17189
let mut uniforms = Uniforms {
17290
aspect_ratio: size.width as f32 / size.height as f32,
17391
};
92+
17493
let uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
17594
label: Some("Uniform Buffer"),
17695
contents: bytemuck::bytes_of(&uniforms),
@@ -200,6 +119,10 @@ async fn main() {
200119
resource: uniform_buffer.as_entire_binding(),
201120
}],
202121
});
122+
123+
// -------------------------------------
124+
// Create Circle & Triangle Geometry
125+
// -------------------------------------
203126
let circle_segments = 64;
204127
let circle_vertex_data = generate_circle_vertices(0.5, circle_segments);
205128
let circle_index_data = generate_circle_indices(circle_segments);
@@ -217,7 +140,8 @@ async fn main() {
217140

218141
// Triangle
219142
let triangle_vertex_data: &[f32] = &[
220-
0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0, // x, y, z
143+
0.0, 0.5, 0.0, // x, y, z
144+
-0.5, -0.5, 0.0, 0.5, -0.5, 0.0,
221145
];
222146
let triangle_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
223147
label: Some("Triangle VB"),
@@ -233,6 +157,7 @@ async fn main() {
233157
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
234158
});
235159

160+
// Circle pipeline
236161
let circle_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
237162
label: Some("Circle Pipeline Layout"),
238163
bind_group_layouts: &[&uniform_bind_group_layout, &bind_group_layout],
@@ -278,6 +203,7 @@ async fn main() {
278203
multiview: None,
279204
});
280205

206+
// Triangle pipeline
281207
let triangle_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
282208
label: Some("Triangle Pipeline Layout"),
283209
bind_group_layouts: &[&uniform_bind_group_layout, &bind_group_layout],
@@ -323,13 +249,18 @@ async fn main() {
323249
multiview: None,
324250
});
325251

326-
// Event loop would go here for rendering shapes...
252+
// -------------------------------------
253+
// Create some shapes
254+
// -------------------------------------
327255
let mut shapes: Vec<Shape> = vec![
328256
Shape::new_circle(&device, &bind_group_layout, glam::vec3(-0.5, 0.0, 0.0), 1.3),
329257
Shape::new_triangle(&device, &bind_group_layout, glam::vec3(0.5, 0.5, 0.0), 0.2),
330258
Shape::new_triangle(&device, &bind_group_layout, glam::vec3(0.2, 0.2, 0.0), 0.4),
331259
];
332260

261+
// -------------------------------------
262+
// Event loop
263+
// -------------------------------------
333264
event_loop.run(move |event, _, control_flow| {
334265
*control_flow = ControlFlow::Poll;
335266

@@ -338,6 +269,7 @@ async fn main() {
338269
let frame = match surface.get_current_texture() {
339270
Ok(frame) => frame,
340271
Err(_) => {
272+
// Reconfigure the surface if lost
341273
surface.configure(&device, &surface_config);
342274
return;
343275
}
@@ -357,6 +289,7 @@ async fn main() {
357289
queue.write_buffer(&uniform_buffer, 0, bytemuck::bytes_of(&uniforms));
358290
}
359291

292+
// Start render pass
360293
{
361294
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
362295
label: Some("Render Pass"),
@@ -376,6 +309,7 @@ async fn main() {
376309
depth_stencil_attachment: None,
377310
});
378311

312+
// Draw all shapes
379313
for shape in &shapes {
380314
match shape.shape_type {
381315
ShapeType::Circle => {
@@ -398,6 +332,7 @@ async fn main() {
398332
}
399333
}
400334

335+
// Submit and present
401336
queue.submit(Some(encoder.finish()));
402337
frame.present();
403338
}
@@ -415,37 +350,14 @@ async fn main() {
415350
surface_config.height = new_size.height;
416351
surface.configure(&device, &surface_config);
417352

418-
// Update aspect ratio
419353
uniforms.aspect_ratio = new_size.width as f32 / new_size.height as f32;
420354
queue.write_buffer(&uniform_buffer, 0, bytemuck::bytes_of(&uniforms));
421355
}
422356
Event::MainEventsCleared => {
357+
// Request a redraw
423358
window.request_redraw();
424359
}
425360
_ => {}
426361
}
427362
});
428363
}
429-
fn generate_circle_vertices(radius: f32, segments: usize) -> Vec<f32> {
430-
let mut vertices = Vec::with_capacity(segments * 3);
431-
let step = std::f32::consts::TAU / segments as f32;
432-
433-
for i in 0..segments {
434-
let angle = step * i as f32;
435-
let x = radius * angle.cos();
436-
let y = radius * angle.sin();
437-
vertices.push(x);
438-
vertices.push(y);
439-
vertices.push(0.0); // z
440-
}
441-
vertices
442-
}
443-
444-
fn generate_circle_indices(segments: usize) -> Vec<u32> {
445-
let mut indices = Vec::with_capacity(segments + 1);
446-
for i in 0..segments as u32 {
447-
indices.push(i);
448-
}
449-
indices.push(0);
450-
indices
451-
}

src/shape.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use bytemuck::{Pod, Zeroable};
2+
use wgpu::util::DeviceExt;
3+
4+
#[repr(C)]
5+
#[derive(Copy, Clone, Pod, Zeroable)]
6+
pub struct InstanceData {
7+
pub model_matrix: [[f32; 4]; 4],
8+
}
9+
10+
pub enum ShapeType {
11+
Circle,
12+
Triangle,
13+
}
14+
15+
pub struct Shape {
16+
pub shape_type: ShapeType,
17+
pub position: glam::Vec3,
18+
pub scale: f32,
19+
pub instance_buffer: wgpu::Buffer,
20+
pub bind_group: wgpu::BindGroup,
21+
}
22+
23+
impl Shape {
24+
pub fn new_circle(
25+
device: &wgpu::Device,
26+
bind_group_layout: &wgpu::BindGroupLayout,
27+
position: glam::Vec3,
28+
scale: f32,
29+
) -> Self {
30+
// Construct the model matrix for the instance
31+
let instance_data = InstanceData {
32+
model_matrix: (glam::Mat4::from_translation(position)
33+
* glam::Mat4::from_scale(glam::Vec3::splat(scale)))
34+
.to_cols_array_2d(),
35+
};
36+
37+
let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
38+
label: Some("Circle Instance Buffer"),
39+
contents: bytemuck::cast_slice(&[instance_data]),
40+
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
41+
});
42+
43+
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
44+
layout: bind_group_layout,
45+
entries: &[wgpu::BindGroupEntry {
46+
binding: 0,
47+
resource: instance_buffer.as_entire_binding(),
48+
}],
49+
label: Some("Circle Bind Group"),
50+
});
51+
52+
Self {
53+
shape_type: ShapeType::Circle,
54+
position,
55+
scale,
56+
instance_buffer,
57+
bind_group,
58+
}
59+
}
60+
61+
pub fn new_triangle(
62+
device: &wgpu::Device,
63+
bind_group_layout: &wgpu::BindGroupLayout,
64+
position: glam::Vec3,
65+
scale: f32,
66+
) -> Self {
67+
let instance_data = InstanceData {
68+
model_matrix: (glam::Mat4::from_translation(position)
69+
* glam::Mat4::from_scale(glam::Vec3::splat(scale)))
70+
.to_cols_array_2d(),
71+
};
72+
73+
let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
74+
label: Some("Triangle Instance Buffer"),
75+
contents: bytemuck::cast_slice(&[instance_data]),
76+
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
77+
});
78+
79+
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
80+
layout: bind_group_layout,
81+
entries: &[wgpu::BindGroupEntry {
82+
binding: 0,
83+
resource: instance_buffer.as_entire_binding(),
84+
}],
85+
label: Some("Triangle Bind Group"),
86+
});
87+
88+
Self {
89+
shape_type: ShapeType::Triangle,
90+
position,
91+
scale,
92+
instance_buffer,
93+
bind_group,
94+
}
95+
}
96+
}

src/uniforms.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use bytemuck::{Pod, Zeroable};
2+
3+
#[repr(C)]
4+
#[derive(Copy, Clone, Pod, Zeroable)]
5+
pub struct Uniforms {
6+
pub aspect_ratio: f32,
7+
}

0 commit comments

Comments
 (0)