1- use bytemuck:: { Pod , Zeroable } ;
21use wgpu:: util:: DeviceExt ;
32use 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]
10317async 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- }
0 commit comments