From a7a4fc82ac83be4161a0ad846f0f542c8ede866e Mon Sep 17 00:00:00 2001 From: mars Date: Sat, 14 May 2022 17:28:37 -0600 Subject: [PATCH] Editor winit + wgpu rendering hello world --- editor/Cargo.toml | 4 ++ editor/src/main.rs | 126 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 2 deletions(-) diff --git a/editor/Cargo.toml b/editor/Cargo.toml index c3cb724..fbbc268 100644 --- a/editor/Cargo.toml +++ b/editor/Cargo.toml @@ -5,3 +5,7 @@ edition = "2021" [dependencies] cyborg = { path = "../" } +egui = "0.17.0" +egui-winit = "0.17.0" +egui_wgpu_backend = "0.17.0" +pollster = "0.2" diff --git a/editor/src/main.rs b/editor/src/main.rs index e7a11a9..a984534 100644 --- a/editor/src/main.rs +++ b/editor/src/main.rs @@ -1,3 +1,125 @@ -fn main() { - println!("Hello, world!"); +use egui_wgpu_backend::wgpu; +use egui_winit::winit::{ + self, + event::{Event, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, +}; + +async fn get_device( + window: &winit::window::Window, +) -> ( + wgpu::Device, + wgpu::Queue, + wgpu::Surface, + wgpu::SurfaceConfiguration, +) { + let size = window.inner_size(); + let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY); + let surface = unsafe { instance.create_surface(window) }; + let adapter = instance + .request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::LowPower, + compatible_surface: Some(&surface), + force_fallback_adapter: false, + }) + .await + .unwrap(); + let (device, queue) = adapter + .request_device( + &wgpu::DeviceDescriptor { + features: wgpu::Features::empty(), + limits: wgpu::Limits::default(), + label: None, + }, + None, + ) + .await + .unwrap(); + let config = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + format: surface.get_preferred_format(&adapter).unwrap(), + width: size.width, + height: size.height, + present_mode: wgpu::PresentMode::Mailbox, + }; + surface.configure(&device, &config); + + (device, queue, surface, config) +} + +fn main() { + let event_loop = EventLoop::new(); + + let window = WindowBuilder::new() + .with_title("Cyborg Editor") + .build(&event_loop) + .unwrap(); + + let mut egui_state = egui_winit::State::new(4096, &window); + let egui_ctx = egui::Context::default(); + + let (device, queue, surface, surface_config) = pollster::block_on(get_device(&window)); + + let mut egui_rp = egui_wgpu_backend::RenderPass::new(&device, surface_config.format, 1); + + event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Wait; + println!("{:?}", event); + + match event { + Event::WindowEvent { event, window_id } if window_id == window.id() => match event { + WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, + event => { + egui_state.on_event(&egui_ctx, &event); + } + }, + Event::RedrawRequested(window_id) if window_id == window.id() => { + match surface.get_current_texture() { + // Err(wgpu::SurfaceError::Lost) => resize(), + Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit, + Err(e) => eprintln!("Surface error: {:?}", e), + Ok(surface_texture) => { + let raw_input = egui_state.take_egui_input(&window); + let output = egui_ctx.run(raw_input, |ctx| { + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Hello world!"); + }); + }); + egui_state.handle_platform_output( + &window, + &egui_ctx, + output.platform_output, + ); + + let meshes = egui_ctx.tessellate(output.shapes); + + let screen_desc = egui_wgpu_backend::ScreenDescriptor { + physical_width: surface_config.width, + physical_height: surface_config.height, + scale_factor: 1.0, // TODO ??? + }; + + egui_rp.update_buffers(&device, &queue, &meshes, &screen_desc); + egui_rp + .add_textures(&device, &queue, &output.textures_delta) + .unwrap(); + + let output_view = surface_texture.texture.create_view(&Default::default()); + let mut cmds = device.create_command_encoder(&Default::default()); + egui_rp + .execute(&mut cmds, &output_view, &meshes, &screen_desc, None) + .unwrap(); + queue.submit(std::iter::once(cmds.finish())); + surface_texture.present(); + egui_rp.remove_textures(output.textures_delta).unwrap(); + } + } + } + Event::MainEventsCleared => { + window.request_redraw(); + } + _ => (), + } + }); }