From 285899e24168a9bcb63266dd02734063c6f32c94 Mon Sep 17 00:00:00 2001 From: Charlotte McElwain Date: Wed, 31 Jul 2024 15:44:45 -0500 Subject: [PATCH] Fix instancing example. --- .../wgpu/wgpu_instancing/wgpu_instancing.rs | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/examples/wgpu/wgpu_instancing/wgpu_instancing.rs b/examples/wgpu/wgpu_instancing/wgpu_instancing.rs index 1cd053031..5c05044f8 100644 --- a/examples/wgpu/wgpu_instancing/wgpu_instancing.rs +++ b/examples/wgpu/wgpu_instancing/wgpu_instancing.rs @@ -1,5 +1,6 @@ use nannou::prelude::*; use std::cell::RefCell; +use std::sync::{Arc, Mutex}; mod data; @@ -100,8 +101,9 @@ fn make_geodesic_isocahedron(subdivisions: usize) -> Vec { points } +#[derive(Clone)] struct Model { - graphics: RefCell, + graphics: Arc>, sphere: Vec, } @@ -147,18 +149,18 @@ pub struct Instance { const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; fn main() { - nannou::app(model).run(); + nannou::app(model).render(render).run(); } fn model(app: &App) -> Model { - let w_id = app.new_window().size(1024, 576).view(view).build().unwrap(); + let w_id = app.new_window::().hdr(true).size(1024, 576).build(); // The gpu device associated with the window's swapchain - let window = app.window(w_id).unwrap(); + let window = app.window(w_id); let device = window.device(); let format = Frame::TEXTURE_FORMAT; let msaa_samples = window.msaa_samples(); - let (win_w, win_h) = window.inner_size_pixels(); + let UVec2 { x: win_w, y: win_h } = window.size_pixels(); // Load shader modules. let vs_desc = wgpu::include_wgsl!("shaders/vs.wgsl"); @@ -192,7 +194,7 @@ fn model(app: &App) -> Model { println!("Number of points on the sphere: {}", sphere.len()); // Create the depth texture. - let depth_texture = create_depth_texture(device, [win_w, win_h], DEPTH_FORMAT, msaa_samples); + let depth_texture = create_depth_texture(&device, [win_w, win_h], DEPTH_FORMAT, msaa_samples); let depth_texture_view = depth_texture.view().build(); // Create the uniform buffer. @@ -206,11 +208,11 @@ fn model(app: &App) -> Model { }); // Create the render pipeline. - let bind_group_layout = create_bind_group_layout(device); - let bind_group = create_bind_group(device, &bind_group_layout, &uniform_buffer); - let pipeline_layout = create_pipeline_layout(device, &bind_group_layout); + let bind_group_layout = create_bind_group_layout(&device); + let bind_group = create_bind_group(&device, &bind_group_layout, &uniform_buffer); + let pipeline_layout = create_pipeline_layout(&device, &bind_group_layout); let render_pipeline = create_render_pipeline( - device, + &device, &pipeline_layout, &vs_mod, &fs_mod, @@ -219,7 +221,7 @@ fn model(app: &App) -> Model { msaa_samples, ); - let graphics = RefCell::new(Graphics { + let graphics = Arc::new(Mutex::new(Graphics { vertex_buffer, normal_buffer, index_buffer, @@ -228,7 +230,7 @@ fn model(app: &App) -> Model { depth_texture_view, bind_group, render_pipeline, - }); + })); Model { graphics, sphere } } @@ -276,22 +278,22 @@ fn special_color(index: usize) -> [f32; 3] { } } -fn view(app: &App, model: &Model, frame: Frame) { - let mut g = model.graphics.borrow_mut(); +fn render(app: &RenderApp, model: &Model, frame: Frame) { + let mut g = model.graphics.lock().unwrap(); // If the window has changed size, recreate our depth texture to match. let depth_size = g.depth_texture.size(); let frame_size = frame.texture_size(); - let device = frame.device_queue_pair().device(); + let device = frame.device(); if frame_size != depth_size { let depth_format = g.depth_texture.format(); - let sample_count = frame.texture_msaa_samples(); - g.depth_texture = create_depth_texture(device, frame_size, depth_format, sample_count); + let sample_count = frame.resolve_target_msaa_samples(); + g.depth_texture = create_depth_texture(&device, frame_size, depth_format, sample_count); g.depth_texture_view = g.depth_texture.view().build(); } - let inner_sphere_instance_rotation = app.time; - let outer_sphere_instance_rotation = 0.2f32 * app.time; + let inner_sphere_instance_rotation = app.time(); + let outer_sphere_instance_rotation = 0.2f32 * app.time(); let inner_sphere_radius = 35f32; let outer_sphere_radius = 50f32; let inner_sphere_scale = 0.04f32; @@ -312,7 +314,7 @@ fn view(app: &App, model: &Model, frame: Frame) { .chain(model.sphere.iter().enumerate().map(|(i, direction)| { make_instance( direction.clone(), - inner_sphere_radius + 2f32 * (i as f32 + app.time).sin().pow(4f32), + inner_sphere_radius + 2f32 * (i as f32 + app.time()).sin().pow(4f32), inner_sphere_instance_rotation, inner_sphere_scale, special_color(i), @@ -329,7 +331,7 @@ fn view(app: &App, model: &Model, frame: Frame) { }); // Update the uniforms (rotate around the teapot). - let world_rotation = 0.05f32 * app.time; + let world_rotation = 0.05f32 * app.time(); let uniforms = create_uniforms(world_rotation, frame_size); let uniforms_size = std::mem::size_of::() as wgpu::BufferAddress; let uniforms_bytes = uniforms_as_bytes(&uniforms); @@ -340,10 +342,13 @@ fn view(app: &App, model: &Model, frame: Frame) { usage, }); + // Drop the device to avoid borrowing issues + drop(device); + let mut encoder = frame.command_encoder(); encoder.copy_buffer_to_buffer(&new_uniform_buffer, 0, &g.uniform_buffer, 0, uniforms_size); let mut render_pass = wgpu::RenderPassBuilder::new() - .color_attachment(frame.texture_view(), |color| color) + .color_attachment(frame.resolve_target_view().unwrap(), |color| color) // We'll use a depth texture to assist with the order of rendering fragments based on depth. .depth_stencil_attachment(&g.depth_texture_view, |depth| depth) .begin(&mut encoder);