diff options
author | 2021-08-13 20:01:28 +0700 | |
---|---|---|
committer | 2021-08-13 20:12:07 +0700 | |
commit | 77a0b68aa176782e95048795aec15c20a3e60ec6 (patch) | |
tree | e4e7c2a34995a91b99a657539f92c8637f52c513 /examples/integration_wgpu/src/main.rs | |
parent | a646b11109aa451614d3fdf688e600aa48b87a56 (diff) | |
download | iced-77a0b68aa176782e95048795aec15c20a3e60ec6.tar.gz iced-77a0b68aa176782e95048795aec15c20a3e60ec6.tar.bz2 iced-77a0b68aa176782e95048795aec15c20a3e60ec6.zip |
Rename `integration` examples
Diffstat (limited to 'examples/integration_wgpu/src/main.rs')
-rw-r--r-- | examples/integration_wgpu/src/main.rs | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/examples/integration_wgpu/src/main.rs b/examples/integration_wgpu/src/main.rs new file mode 100644 index 00000000..6f319466 --- /dev/null +++ b/examples/integration_wgpu/src/main.rs @@ -0,0 +1,239 @@ +mod controls; +mod scene; + +use controls::Controls; +use scene::Scene; + +use iced_wgpu::{wgpu, Backend, Renderer, Settings, Viewport}; +use iced_winit::{conversion, futures, program, winit, Clipboard, Debug, Size}; + +use futures::task::SpawnExt; +use winit::{ + dpi::PhysicalPosition, + event::{Event, ModifiersState, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, +}; + +pub fn main() { + env_logger::init(); + + // Initialize winit + let event_loop = EventLoop::new(); + let window = winit::window::Window::new(&event_loop).unwrap(); + + let physical_size = window.inner_size(); + let mut viewport = Viewport::with_physical_size( + Size::new(physical_size.width, physical_size.height), + window.scale_factor(), + ); + let mut cursor_position = PhysicalPosition::new(-1.0, -1.0); + let mut modifiers = ModifiersState::default(); + let mut clipboard = Clipboard::connect(&window); + + // Initialize wgpu + let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY); + let surface = unsafe { instance.create_surface(&window) }; + + let (format, (mut device, queue)) = futures::executor::block_on(async { + let adapter = instance + .request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::HighPerformance, + compatible_surface: Some(&surface), + }) + .await + .expect("Request adapter"); + + ( + adapter + .get_swap_chain_preferred_format(&surface) + .expect("Get preferred format"), + adapter + .request_device( + &wgpu::DeviceDescriptor { + label: None, + features: wgpu::Features::empty(), + limits: wgpu::Limits::default(), + }, + None, + ) + .await + .expect("Request device"), + ) + }); + + let mut swap_chain = { + let size = window.inner_size(); + + device.create_swap_chain( + &surface, + &wgpu::SwapChainDescriptor { + usage: wgpu::TextureUsage::RENDER_ATTACHMENT, + format, + width: size.width, + height: size.height, + present_mode: wgpu::PresentMode::Mailbox, + }, + ) + }; + let mut resized = false; + + // Initialize staging belt and local pool + let mut staging_belt = wgpu::util::StagingBelt::new(5 * 1024); + let mut local_pool = futures::executor::LocalPool::new(); + + // Initialize scene and GUI controls + let scene = Scene::new(&mut device); + let controls = Controls::new(); + + // Initialize iced + let mut debug = Debug::new(); + let mut renderer = + Renderer::new(Backend::new(&mut device, Settings::default(), format)); + + let mut state = program::State::new( + controls, + viewport.logical_size(), + conversion::cursor_position(cursor_position, viewport.scale_factor()), + &mut renderer, + &mut debug, + ); + + // Run event loop + event_loop.run(move |event, _, control_flow| { + // You should change this if you want to render continuosly + *control_flow = ControlFlow::Wait; + + match event { + Event::WindowEvent { event, .. } => { + match event { + WindowEvent::CursorMoved { position, .. } => { + cursor_position = position; + } + WindowEvent::ModifiersChanged(new_modifiers) => { + modifiers = new_modifiers; + } + WindowEvent::Resized(new_size) => { + viewport = Viewport::with_physical_size( + Size::new(new_size.width, new_size.height), + window.scale_factor(), + ); + + resized = true; + } + WindowEvent::CloseRequested => { + *control_flow = ControlFlow::Exit; + } + _ => {} + } + + // Map window event to iced event + if let Some(event) = iced_winit::conversion::window_event( + &event, + window.scale_factor(), + modifiers, + ) { + state.queue_event(event); + } + } + Event::MainEventsCleared => { + // If there are events pending + if !state.is_queue_empty() { + // We update iced + let _ = state.update( + viewport.logical_size(), + conversion::cursor_position( + cursor_position, + viewport.scale_factor(), + ), + &mut renderer, + &mut clipboard, + &mut debug, + ); + + // and request a redraw + window.request_redraw(); + } + } + Event::RedrawRequested(_) => { + if resized { + let size = window.inner_size(); + + swap_chain = device.create_swap_chain( + &surface, + &wgpu::SwapChainDescriptor { + usage: wgpu::TextureUsage::RENDER_ATTACHMENT, + format: format, + width: size.width, + height: size.height, + present_mode: wgpu::PresentMode::Mailbox, + }, + ); + + resized = false; + } + + match swap_chain.get_current_frame() { + Ok(frame) => { + let mut encoder = device.create_command_encoder( + &wgpu::CommandEncoderDescriptor { label: None }, + ); + + let program = state.program(); + + { + // We clear the frame + let mut render_pass = scene.clear( + &frame.output.view, + &mut encoder, + program.background_color(), + ); + + // Draw the scene + scene.draw(&mut render_pass); + } + + // And then iced on top + let mouse_interaction = renderer.backend_mut().draw( + &mut device, + &mut staging_belt, + &mut encoder, + &frame.output.view, + &viewport, + state.primitive(), + &debug.overlay(), + ); + + // Then we submit the work + staging_belt.finish(); + queue.submit(Some(encoder.finish())); + + // Update the mouse cursor + window.set_cursor_icon( + iced_winit::conversion::mouse_interaction( + mouse_interaction, + ), + ); + + // And recall staging buffers + local_pool + .spawner() + .spawn(staging_belt.recall()) + .expect("Recall staging buffers"); + + local_pool.run_until_stalled(); + } + Err(error) => match error { + wgpu::SwapChainError::OutOfMemory => { + panic!("Swapchain error: {}. Rendering cannot continue.", error) + } + _ => { + // Try rendering again next frame. + window.request_redraw(); + } + }, + } + } + _ => {} + } + }) +} |