diff --git a/editor/src/main.rs b/editor/src/main.rs index 573f678..73d44ce 100644 --- a/editor/src/main.rs +++ b/editor/src/main.rs @@ -1,4 +1,5 @@ use futures::executor::block_on; +use wgpu::util::DeviceExt; use winit::{ dpi::LogicalSize, event::{Event, WindowEvent}, @@ -6,6 +7,33 @@ use winit::{ window::WindowBuilder, }; +#[repr(C)] +struct Vertex([f32; 3]); + +impl Vertex { + const fn desc() -> wgpu::VertexBufferLayout<'static> { + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &[wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x3, + offset: 0, + shader_location: 0, + }], + } + } +} + +const FULL_QUAD_VERTS: &[Vertex] = &[ + Vertex([-1.0, -1.0, 0.0]), + Vertex([-1.0, 1.0, 0.0]), + Vertex([1.0, 1.0, 0.0]), + // + Vertex([-1.0, -1.0, 0.0]), + Vertex([1.0, -1.0, 0.0]), + Vertex([1.0, 1.0, 0.0]), +]; + fn main() -> Result<(), Box> { let event_loop = EventLoop::new()?; let logical_size = LogicalSize::new(800.0, 600.0); @@ -16,7 +44,12 @@ fn main() -> Result<(), Box> { .build(&event_loop)?; let window_size = window.inner_size(); - let instance = wgpu::Instance::default(); + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + backends: wgpu::Backends::METAL, + flags: wgpu::InstanceFlags::default(), + dx12_shader_compiler: wgpu::Dx12Compiler::default(), + gles_minor_version: wgpu::Gles3MinorVersion::Automatic, + }); let surface = instance.create_surface(&window)?; let adapter = block_on(instance.request_adapter(&wgpu::RequestAdapterOptions { @@ -30,7 +63,7 @@ fn main() -> Result<(), Box> { &wgpu::DeviceDescriptor { label: None, required_features: wgpu::Features::empty(), - required_limits: wgpu::Limits::downlevel_webgl2_defaults(), + required_limits: wgpu::Limits::default(), }, None, )) @@ -40,6 +73,15 @@ fn main() -> Result<(), Box> { label: None, source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(include_str!("shader.wgsl"))), }); + + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: unsafe { + let len = std::mem::size_of_val(FULL_QUAD_VERTS); + core::slice::from_raw_parts(FULL_QUAD_VERTS.as_ptr() as *const u8, len) + }, + usage: wgpu::BufferUsages::VERTEX, + }); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, bind_group_layouts: &[], @@ -54,7 +96,7 @@ fn main() -> Result<(), Box> { vertex: wgpu::VertexState { module: &shader, entry_point: "vs_main", - buffers: &[], + buffers: &[Vertex::desc()], }, primitive: wgpu::PrimitiveState::default(), depth_stencil: None, @@ -66,57 +108,69 @@ fn main() -> Result<(), Box> { }), multiview: None, }); - let config = surface + let mut config = surface .get_default_config(&adapter, window_size.width, window_size.height) .unwrap(); surface.configure(&device, &config); let window = &window; event_loop.set_control_flow(ControlFlow::Wait); - event_loop.run(move |event, elwt| match event { - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => { - elwt.exit(); - } - Event::AboutToWait => { - window.request_redraw(); - } - Event::WindowEvent { - event: WindowEvent::RedrawRequested, - .. - } => { - let frame = surface - .get_current_texture() - .expect("failed to acquire next swap chain texture"); - let view = frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - { - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), - store: wgpu::StoreOp::Store, - }, - })], - depth_stencil_attachment: None, - timestamp_writes: None, - occlusion_query_set: None, - }); - rpass.set_pipeline(&render_pipeline); - rpass.draw(0..3, 0..1); - } - queue.submit(Some(encoder.finish())); - frame.present(); - } + #[allow(clippy::single_match)] + event_loop.run(move |event, elwt| match event { + Event::WindowEvent { event, .. } => match event { + WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::DroppedFile(path_buf) => { + eprintln!("{path_buf:?}"); + } + WindowEvent::Resized(size) => { + config.width = size.width; + config.height = size.height; + + surface.configure(&device, &config); + + window.request_redraw(); + } + WindowEvent::MouseInput { .. } => window.request_redraw(), + WindowEvent::CursorMoved { .. } => { + window.request_redraw(); + } + WindowEvent::RedrawRequested => { + let frame = surface + .get_current_texture() + .expect("failed to acquire next swap chain texture"); + let view = frame + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), + store: wgpu::StoreOp::Store, + }, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + rpass.set_pipeline(&render_pipeline); + rpass.set_vertex_buffer(0, vertex_buffer.slice(..)); + rpass.draw(0..FULL_QUAD_VERTS.len() as u32, 0..1); + } + + queue.submit(Some(encoder.finish())); + frame.present(); + + eprintln!("redraw"); + } + _ => (), + }, _ => (), })?; diff --git a/editor/src/shader.wgsl b/editor/src/shader.wgsl index f84ccfe..b7a1b6f 100644 --- a/editor/src/shader.wgsl +++ b/editor/src/shader.wgsl @@ -1,11 +1,22 @@ +struct VertexInput { + @location(0) position: vec3, +} + +struct VertexOutput { + @builtin(position) clip_position: vec4, + @location(0) color: vec4, +} + @vertex -fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4 { - let x = f32(i32(in_vertex_index) - 1); - let y = f32(i32(in_vertex_index & 1u) * 2 - 1); - return vec4(x, y, 0.0, 1.0); +fn vs_main(quad: VertexInput) -> VertexOutput { + var out: VertexOutput; + out.color = vec4(1.0, 0.0, 0.0, 1.0); + out.clip_position = vec4(quad.position, 1.0); + + return out; } @fragment -fn fs_main() -> @location(0) vec4 { - return vec4(1.0, 0.0, 0.0, 1.0); +fn fs_main(in: VertexOutput) -> @location(0) vec4 { + return in.color; }