From 19e4385dad94089388165df9e7d354a9b2ecc453 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Tue, 23 Apr 2024 21:12:04 +0700 Subject: [PATCH] Update dev-dependencies: cocoa, glam, winit. --- Cargo.toml | 6 +- examples/circle/main.rs | 165 +++++++++++++------------- examples/mesh-shader/main.rs | 106 +++++++++-------- examples/raytracing/main.rs | 58 +++++----- examples/shader-dylib/main.rs | 56 ++++----- examples/texture/Cargo.toml | 4 +- examples/texture/src/main.rs | 85 +++++++------- examples/window/main.rs | 212 ++++++++++++++++++---------------- 8 files changed, 361 insertions(+), 331 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6a3d426b..1165da08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,12 +34,12 @@ paste = "1" version = "0.2.4" [dev-dependencies] -cocoa = "0.24.0" +cocoa = "0.25.0" cty = "0.2.1" -winit = "0.27" +winit = "0.29" sema = "0.1.4" png = "0.17" -glam = "0.22" +glam = "0.27" rand = "0.8" [[example]] diff --git a/examples/circle/main.rs b/examples/circle/main.rs index ed17a734..7124a589 100644 --- a/examples/circle/main.rs +++ b/examples/circle/main.rs @@ -3,7 +3,7 @@ use metal::*; use winit::{ event::{Event, WindowEvent}, event_loop::{ControlFlow, EventLoop}, - platform::macos::WindowExtMacOS, + raw_window_handle::{HasWindowHandle, RawWindowHandle}, }; use cocoa::{appkit::NSView, base::id as cocoa_id}; @@ -33,7 +33,7 @@ pub struct AAPLVertex { fn main() { // Create a window for viewing the content - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let size = winit::dpi::LogicalSize::new(800, 600); let window = winit::window::WindowBuilder::new() @@ -100,9 +100,11 @@ fn main() { layer.set_presents_with_transaction(false); unsafe { - let view = window.ns_view() as cocoa_id; - view.setWantsLayer(YES); - view.setLayer(mem::transmute(layer.as_ref())); + if let Ok(RawWindowHandle::AppKit(rw)) = window.window_handle().map(|wh| wh.as_raw()) { + let view = rw.ns_view.as_ptr() as cocoa_id; + view.setWantsLayer(YES); + view.setLayer(mem::transmute(layer.as_ref())); + } } let draw_size = window.inner_size(); @@ -119,80 +121,87 @@ fn main() { ) }; - event_loop.run(move |event, _, control_flow| { - autoreleasepool(|| { - // ControlFlow::Wait pauses the event loop if no events are available to process. - // This is ideal for non-game applications that only update in response to user - // input, and uses significantly less power/CPU time than ControlFlow::Poll. - *control_flow = ControlFlow::Wait; - - match event { - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => { - println!("The close button was pressed; stopping"); - *control_flow = ControlFlow::Exit - } - Event::MainEventsCleared => { - // Queue a RedrawRequested event. - window.request_redraw(); - } - Event::RedrawRequested(_) => { - // It's preferrable to render in this event rather than in MainEventsCleared, since - // rendering in here allows the program to gracefully handle redraws requested - // by the OS. - let drawable = match layer.next_drawable() { - Some(drawable) => drawable, - None => return, - }; - - // Create a new command buffer for each render pass to the current drawable - let command_buffer = command_queue.new_command_buffer(); - - // Obtain a renderPassDescriptor generated from the view's drawable textures. - let render_pass_descriptor = RenderPassDescriptor::new(); - handle_render_pass_color_attachment( - &render_pass_descriptor, - drawable.texture(), - ); - handle_render_pass_sample_buffer_attachment( - &render_pass_descriptor, - &counter_sample_buffer, - ); - - // Create a render command encoder. - let encoder = - command_buffer.new_render_command_encoder(&render_pass_descriptor); - encoder.set_render_pipeline_state(&pipeline_state); - // Pass in the parameter data. - encoder.set_vertex_buffer(0, Some(&vbuf), 0); - // Draw the triangles which will eventually form the circle. - encoder.draw_primitives(MTLPrimitiveType::TriangleStrip, 0, 1080); - encoder.end_encoding(); - - resolve_samples_into_buffer( - &command_buffer, - &counter_sample_buffer, - &destination_buffer, - ); - - // Schedule a present once the framebuffer is complete using the current drawable. - command_buffer.present_drawable(&drawable); - - // Finalize rendering here & push the command buffer to the GPU. - command_buffer.commit(); - command_buffer.wait_until_completed(); - - let mut cpu_end = 0; - let mut gpu_end = 0; - device.sample_timestamps(&mut cpu_end, &mut gpu_end); - handle_timestamps(&destination_buffer, cpu_start, cpu_end, gpu_start, gpu_end); + event_loop + .run(move |event, event_loop| { + autoreleasepool(|| { + // ControlFlow::Wait pauses the event loop if no events are available to process. + // This is ideal for non-game applications that only update in response to user + // input, and uses significantly less power/CPU time than ControlFlow::Poll. + event_loop.set_control_flow(ControlFlow::Wait); + + match event { + Event::AboutToWait => window.request_redraw(), + Event::WindowEvent { event, .. } => { + match event { + WindowEvent::CloseRequested => { + println!("The close button was pressed; stopping"); + event_loop.exit(); + } + WindowEvent::RedrawRequested => { + // It's preferrable to render in this event rather than in MainEventsCleared, since + // rendering in here allows the program to gracefully handle redraws requested + // by the OS. + let drawable = match layer.next_drawable() { + Some(drawable) => drawable, + None => return, + }; + + // Create a new command buffer for each render pass to the current drawable + let command_buffer = command_queue.new_command_buffer(); + + // Obtain a renderPassDescriptor generated from the view's drawable textures. + let render_pass_descriptor = RenderPassDescriptor::new(); + handle_render_pass_color_attachment( + &render_pass_descriptor, + drawable.texture(), + ); + handle_render_pass_sample_buffer_attachment( + &render_pass_descriptor, + &counter_sample_buffer, + ); + + // Create a render command encoder. + let encoder = command_buffer + .new_render_command_encoder(&render_pass_descriptor); + encoder.set_render_pipeline_state(&pipeline_state); + // Pass in the parameter data. + encoder.set_vertex_buffer(0, Some(&vbuf), 0); + // Draw the triangles which will eventually form the circle. + encoder.draw_primitives(MTLPrimitiveType::TriangleStrip, 0, 1080); + encoder.end_encoding(); + + resolve_samples_into_buffer( + &command_buffer, + &counter_sample_buffer, + &destination_buffer, + ); + + // Schedule a present once the framebuffer is complete using the current drawable. + command_buffer.present_drawable(&drawable); + + // Finalize rendering here & push the command buffer to the GPU. + command_buffer.commit(); + command_buffer.wait_until_completed(); + + let mut cpu_end = 0; + let mut gpu_end = 0; + device.sample_timestamps(&mut cpu_end, &mut gpu_end); + handle_timestamps( + &destination_buffer, + cpu_start, + cpu_end, + gpu_start, + gpu_end, + ); + } + _ => (), + } + } + _ => (), } - _ => (), - } - }); - }); + }); + }) + .unwrap(); } // If we want to draw a circle, we need to draw it out of the three primitive diff --git a/examples/mesh-shader/main.rs b/examples/mesh-shader/main.rs index 8edb30ce..df8f5929 100644 --- a/examples/mesh-shader/main.rs +++ b/examples/mesh-shader/main.rs @@ -6,11 +6,11 @@ use core_graphics_types::geometry::CGSize; use metal::*; use objc::{rc::autoreleasepool, runtime::YES}; use std::mem; -use winit::platform::macos::WindowExtMacOS; use winit::{ event::{Event, WindowEvent}, event_loop::ControlFlow, + raw_window_handle::{HasWindowHandle, RawWindowHandle}, }; fn prepare_render_pass_descriptor(descriptor: &RenderPassDescriptorRef, texture: &TextureRef) { @@ -23,13 +23,13 @@ fn prepare_render_pass_descriptor(descriptor: &RenderPassDescriptorRef, texture: } fn main() { - let events_loop = winit::event_loop::EventLoop::new(); + let event_loop = winit::event_loop::EventLoop::new().unwrap(); let size = winit::dpi::LogicalSize::new(800, 600); let window = winit::window::WindowBuilder::new() .with_inner_size(size) .with_title("Metal Mesh Shader Example".to_string()) - .build(&events_loop) + .build(&event_loop) .unwrap(); let device = Device::system_default().expect("no device found"); @@ -40,9 +40,11 @@ fn main() { layer.set_presents_with_transaction(false); unsafe { - let view = window.ns_view() as cocoa_id; - view.setWantsLayer(YES); - view.setLayer(mem::transmute(layer.as_ref())); + if let Ok(RawWindowHandle::AppKit(rw)) = window.window_handle().map(|wh| wh.as_raw()) { + let view = rw.ns_view.as_ptr() as cocoa_id; + view.setWantsLayer(YES); + view.setLayer(mem::transmute(layer.as_ref())); + } } let draw_size = window.inner_size(); @@ -70,49 +72,57 @@ fn main() { let command_queue = device.new_command_queue(); - events_loop.run(move |event, _, control_flow| { - autoreleasepool(|| { - *control_flow = ControlFlow::Poll; + event_loop + .run(move |event, event_loop| { + autoreleasepool(|| { + event_loop.set_control_flow(ControlFlow::Poll); - match event { - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, - WindowEvent::Resized(size) => { - layer.set_drawable_size(CGSize::new(size.width as f64, size.height as f64)); + match event { + Event::AboutToWait => { + window.request_redraw(); } - _ => (), - }, - Event::MainEventsCleared => { - window.request_redraw(); + Event::WindowEvent { event, .. } => match event { + WindowEvent::CloseRequested => event_loop.exit(), + WindowEvent::Resized(size) => { + layer.set_drawable_size(CGSize::new( + size.width as f64, + size.height as f64, + )); + } + WindowEvent::RedrawRequested => { + let drawable = match layer.next_drawable() { + Some(drawable) => drawable, + None => return, + }; + + let render_pass_descriptor = RenderPassDescriptor::new(); + + prepare_render_pass_descriptor( + &render_pass_descriptor, + drawable.texture(), + ); + + let command_buffer = command_queue.new_command_buffer(); + let encoder = + command_buffer.new_render_command_encoder(&render_pass_descriptor); + + encoder.set_render_pipeline_state(&pipeline_state); + encoder.draw_mesh_threads( + MTLSize::new(1, 1, 1), + MTLSize::new(1, 1, 1), + MTLSize::new(1, 1, 1), + ); + + encoder.end_encoding(); + + command_buffer.present_drawable(&drawable); + command_buffer.commit(); + } + _ => (), + }, + _ => {} } - Event::RedrawRequested(_) => { - let drawable = match layer.next_drawable() { - Some(drawable) => drawable, - None => return, - }; - - let render_pass_descriptor = RenderPassDescriptor::new(); - - prepare_render_pass_descriptor(&render_pass_descriptor, drawable.texture()); - - let command_buffer = command_queue.new_command_buffer(); - let encoder = - command_buffer.new_render_command_encoder(&render_pass_descriptor); - - encoder.set_render_pipeline_state(&pipeline_state); - encoder.draw_mesh_threads( - MTLSize::new(1, 1, 1), - MTLSize::new(1, 1, 1), - MTLSize::new(1, 1, 1), - ); - - encoder.end_encoding(); - - command_buffer.present_drawable(&drawable); - command_buffer.commit(); - } - _ => {} - } - }); - }); + }); + }) + .unwrap(); } diff --git a/examples/raytracing/main.rs b/examples/raytracing/main.rs index 68eaf3df..4c4aed12 100644 --- a/examples/raytracing/main.rs +++ b/examples/raytracing/main.rs @@ -8,7 +8,7 @@ use std::mem; use winit::{ event::{Event, WindowEvent}, event_loop::ControlFlow, - platform::macos::WindowExtMacOS, + raw_window_handle::{HasWindowHandle, RawWindowHandle}, }; pub mod camera; @@ -31,13 +31,13 @@ fn find_raytracing_supporting_device() -> Device { } fn main() { - let events_loop = winit::event_loop::EventLoop::new(); + let event_loop = winit::event_loop::EventLoop::new().unwrap(); let size = winit::dpi::LogicalSize::new(800, 600); let window = winit::window::WindowBuilder::new() .with_inner_size(size) .with_title("Metal Raytracing Example".to_string()) - .build(&events_loop) + .build(&event_loop) .unwrap(); let device = find_raytracing_supporting_device(); @@ -48,9 +48,11 @@ fn main() { layer.set_presents_with_transaction(false); unsafe { - let view = window.ns_view() as cocoa_id; - view.setWantsLayer(YES); - view.setLayer(mem::transmute(layer.as_ref())); + if let Ok(RawWindowHandle::AppKit(rw)) = window.window_handle().map(|wh| wh.as_raw()) { + let view = rw.ns_view.as_ptr() as cocoa_id; + view.setWantsLayer(YES); + view.setLayer(mem::transmute(layer.as_ref())); + } } let draw_size = window.inner_size(); @@ -60,28 +62,28 @@ fn main() { let mut renderer = renderer::Renderer::new(device); renderer.window_resized(cg_size); - events_loop.run(move |event, _, control_flow| { - autoreleasepool(|| { - *control_flow = ControlFlow::Poll; + event_loop + .run(move |event, event_loop| { + autoreleasepool(|| { + event_loop.set_control_flow(ControlFlow::Poll); - match event { - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, - WindowEvent::Resized(size) => { - let size = CGSize::new(size.width as f64, size.height as f64); - layer.set_drawable_size(size); - renderer.window_resized(size); - } - _ => (), - }, - Event::MainEventsCleared => { - window.request_redraw(); - } - Event::RedrawRequested(_) => { - renderer.draw(&layer); + match event { + Event::AboutToWait => window.request_redraw(), + Event::WindowEvent { event, .. } => match event { + WindowEvent::CloseRequested => event_loop.exit(), + WindowEvent::Resized(size) => { + let size = CGSize::new(size.width as f64, size.height as f64); + layer.set_drawable_size(size); + renderer.window_resized(size); + } + WindowEvent::RedrawRequested => { + renderer.draw(&layer); + } + _ => (), + }, + _ => {} } - _ => {} - } - }); - }); + }); + }) + .unwrap(); } diff --git a/examples/shader-dylib/main.rs b/examples/shader-dylib/main.rs index 60b6aa0d..8dd2582c 100644 --- a/examples/shader-dylib/main.rs +++ b/examples/shader-dylib/main.rs @@ -7,7 +7,7 @@ use objc::{rc::autoreleasepool, runtime::YES}; use winit::{ event::{Event, WindowEvent}, event_loop::ControlFlow, - platform::macos::WindowExtMacOS, + raw_window_handle::{HasWindowHandle, RawWindowHandle}, }; use std::mem; @@ -43,9 +43,11 @@ impl App { layer.set_presents_with_transaction(false); layer.set_framebuffer_only(false); unsafe { - let view = window.ns_view() as cocoa_id; - view.setWantsLayer(YES); - view.setLayer(mem::transmute(layer.as_ref())); + if let Ok(RawWindowHandle::AppKit(rw)) = window.window_handle().map(|wh| wh.as_raw()) { + let view = rw.ns_view.as_ptr() as cocoa_id; + view.setWantsLayer(YES); + view.setLayer(mem::transmute(layer.as_ref())); + } } let draw_size = window.inner_size(); layer.set_drawable_size(CGSize::new(draw_size.width as f64, draw_size.height as f64)); @@ -141,37 +143,37 @@ impl App { } fn main() { - let events_loop = winit::event_loop::EventLoop::new(); + let event_loop = winit::event_loop::EventLoop::new().unwrap(); let size = winit::dpi::LogicalSize::new(800, 600); let window = winit::window::WindowBuilder::new() .with_inner_size(size) .with_title("Metal Shader Dylib Example".to_string()) - .build(&events_loop) + .build(&event_loop) .unwrap(); let mut app = App::new(&window); - events_loop.run(move |event, _, control_flow| { - autoreleasepool(|| { - *control_flow = ControlFlow::Poll; - - match event { - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, - WindowEvent::Resized(size) => { - app.resize(size.width, size.height); - } - _ => (), - }, - Event::MainEventsCleared => { - window.request_redraw(); - } - Event::RedrawRequested(_) => { - app.draw(); + event_loop + .run(move |event, event_loop| { + autoreleasepool(|| { + event_loop.set_control_flow(ControlFlow::Poll); + + match event { + Event::AboutToWait => window.request_redraw(), + Event::WindowEvent { event, .. } => match event { + WindowEvent::CloseRequested => event_loop.exit(), + WindowEvent::Resized(size) => { + app.resize(size.width, size.height); + } + WindowEvent::RedrawRequested => { + app.draw(); + } + _ => (), + }, + _ => {} } - _ => {} - } - }); - }); + }); + }) + .unwrap(); } diff --git a/examples/texture/Cargo.toml b/examples/texture/Cargo.toml index 8af54a9a..5dfdaece 100644 --- a/examples/texture/Cargo.toml +++ b/examples/texture/Cargo.toml @@ -10,11 +10,11 @@ bindgen = { version = "0.60", default-features = false, features = ["logging", " [dependencies] core-graphics-types = "0.1" -cocoa = "0.24" +cocoa = "0.25" core-graphics = "0.22" png = "0.17" metal = { path = "../../" } -winit = "0.27" +winit = "0.29" [dependencies.objc] version = "0.2.4" diff --git a/examples/texture/src/main.rs b/examples/texture/src/main.rs index de7a4765..34839030 100644 --- a/examples/texture/src/main.rs +++ b/examples/texture/src/main.rs @@ -1,14 +1,15 @@ //! Renders a textured quad to a window and adjusts the GPU buffer that contains the viewport's //! height and width whenever the window is resized. +use std::mem; use std::path::PathBuf; use cocoa::{appkit::NSView, base::id as cocoa_id}; use core_graphics_types::geometry::CGSize; -use objc::rc::autoreleasepool; +use objc::{rc::autoreleasepool, runtime::YES}; use winit::dpi::LogicalSize; use winit::event_loop::{ControlFlow, EventLoop}; -use winit::platform::macos::WindowExtMacOS; +use winit::raw_window_handle::{HasWindowHandle, RawWindowHandle}; use winit::window::Window; use metal::{ @@ -31,7 +32,7 @@ const INITIAL_WINDOW_HEIGHT: u32 = 600; const PIXEL_FORMAT: MTLPixelFormat = MTLPixelFormat::BGRA8Unorm; fn main() { - let event_loop = EventLoop::new(); + let event_loop = EventLoop::new().unwrap(); let window = init_window(&event_loop); let device = Device::system_default().expect("No device found"); @@ -57,27 +58,40 @@ fn main() { let pipeline_state = prepare_pipeline_state(&device, &library); let command_queue = device.new_command_queue(); - event_loop.run(move |event, _, control_flow| { - autoreleasepool(|| { - *control_flow = ControlFlow::Poll; - - match event { - Event::WindowEvent { event, .. } => { - handle_window_event(event, control_flow, &layer, &viewport_size_buffer) + event_loop + .run(move |event, event_loop| { + autoreleasepool(|| { + event_loop.set_control_flow(ControlFlow::Poll); + + match event { + Event::AboutToWait => window.request_redraw(), + Event::WindowEvent { event, .. } => match event { + WindowEvent::CloseRequested => event_loop.exit(), + WindowEvent::Resized(size) => { + layer.set_drawable_size(CGSize::new( + size.width as f64, + size.height as f64, + )); + update_viewport_size_buffer( + &viewport_size_buffer, + (size.width, size.height), + ); + } + WindowEvent::RedrawRequested => redraw( + &layer, + &pipeline_state, + &command_queue, + &vertex_buffer, + &viewport_size_buffer, + &texture_to_render, + ), + _ => {} + }, + _ => {} } - Event::MainEventsCleared => window.request_redraw(), - Event::RedrawRequested(_) => redraw( - &layer, - &pipeline_state, - &command_queue, - &vertex_buffer, - &viewport_size_buffer, - &texture_to_render, - ), - _ => {} - } - }); - }); + }); + }) + .unwrap(); } // The `TexturedVertex` type is generated by `build.rs` by parsing `shader_types.h` @@ -174,9 +188,11 @@ fn get_window_layer(window: &Window, device: &Device) -> MetalLayer { )); unsafe { - let view = window.ns_view() as cocoa_id; - view.setWantsLayer(true as _); - view.setLayer(std::mem::transmute(layer.as_ref())); + if let Ok(RawWindowHandle::AppKit(rw)) = window.window_handle().map(|wh| wh.as_raw()) { + let view = rw.ns_view.as_ptr() as cocoa_id; + view.setWantsLayer(YES); + view.setLayer(mem::transmute(layer.as_ref())); + } } layer @@ -206,23 +222,6 @@ fn prepare_pipeline_state(device: &Device, library: &Library) -> RenderPipelineS .unwrap() } -fn handle_window_event( - event: WindowEvent, - control_flow: &mut ControlFlow, - layer: &MetalLayerRef, - viewport_size_buffer: &Buffer, -) { - match event { - WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, - WindowEvent::Resized(size) => { - layer.set_drawable_size(CGSize::new(size.width as f64, size.height as f64)); - - update_viewport_size_buffer(viewport_size_buffer, (size.width, size.height)); - } - _ => {} - } -} - fn update_viewport_size_buffer(viewport_size_buffer: &Buffer, size: (u32, u32)) { let contents = viewport_size_buffer.contents(); let viewport_size: [u32; 2] = [size.0, size.1]; diff --git a/examples/window/main.rs b/examples/window/main.rs index 08936e82..0c9da3fe 100644 --- a/examples/window/main.rs +++ b/examples/window/main.rs @@ -13,11 +13,11 @@ use core_graphics_types::geometry::CGSize; use metal::*; use objc::{rc::autoreleasepool, runtime::YES}; use std::mem; -use winit::platform::macos::WindowExtMacOS; use winit::{ event::{Event, WindowEvent}, event_loop::ControlFlow, + raw_window_handle::{HasWindowHandle, RawWindowHandle}, }; #[repr(C)] @@ -85,13 +85,13 @@ fn prepare_render_pass_descriptor(descriptor: &RenderPassDescriptorRef, texture: } fn main() { - let events_loop = winit::event_loop::EventLoop::new(); + let event_loop = winit::event_loop::EventLoop::new().unwrap(); let size = winit::dpi::LogicalSize::new(800, 600); let window = winit::window::WindowBuilder::new() .with_inner_size(size) .with_title("Metal Window Example".to_string()) - .build(&events_loop) + .build(&event_loop) .unwrap(); let device = Device::system_default().expect("no device found"); @@ -102,9 +102,11 @@ fn main() { layer.set_presents_with_transaction(false); unsafe { - let view = window.ns_view() as cocoa_id; - view.setWantsLayer(YES); - view.setLayer(mem::transmute(layer.as_ref())); + if let Ok(RawWindowHandle::AppKit(rw)) = window.window_handle().map(|wh| wh.as_raw()) { + let view = rw.ns_view.as_ptr() as cocoa_id; + view.setWantsLayer(YES); + view.setLayer(mem::transmute(layer.as_ref())); + } } let draw_size = window.inner_size(); @@ -161,101 +163,107 @@ fn main() { MTLResourceOptions::CPUCacheModeDefaultCache | MTLResourceOptions::StorageModeManaged, ); - events_loop.run(move |event, _, control_flow| { - autoreleasepool(|| { - *control_flow = ControlFlow::Poll; - - match event { - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, - WindowEvent::Resized(size) => { - layer.set_drawable_size(CGSize::new(size.width as f64, size.height as f64)); - } - _ => (), - }, - Event::MainEventsCleared => { - window.request_redraw(); + event_loop + .run(move |event, event_loop| { + autoreleasepool(|| { + event_loop.set_control_flow(ControlFlow::Poll); + + match event { + Event::AboutToWait => window.request_redraw(), + Event::WindowEvent { event, .. } => match event { + WindowEvent::CloseRequested => event_loop.exit(), + WindowEvent::Resized(size) => { + layer.set_drawable_size(CGSize::new( + size.width as f64, + size.height as f64, + )); + } + WindowEvent::RedrawRequested => { + let p = vbuf.contents(); + let vertex_data = [ + 0.0f32, + 0.5, + 1.0, + 0.0, + 0.0, + -0.5 + (r.cos() / 2. + 0.5), + -0.5, + 0.0, + 1.0, + 0.0, + 0.5 - (r.cos() / 2. + 0.5), + -0.5, + 0.0, + 0.0, + 1.0, + ]; + + unsafe { + std::ptr::copy( + vertex_data.as_ptr(), + p as *mut f32, + (vertex_data.len() * mem::size_of::()) as usize, + ); + } + + vbuf.did_modify_range(crate::NSRange::new( + 0 as u64, + (vertex_data.len() * mem::size_of::()) as u64, + )); + + let drawable = match layer.next_drawable() { + Some(drawable) => drawable, + None => return, + }; + + let render_pass_descriptor = RenderPassDescriptor::new(); + + prepare_render_pass_descriptor( + &render_pass_descriptor, + drawable.texture(), + ); + + let command_buffer = command_queue.new_command_buffer(); + let encoder = + command_buffer.new_render_command_encoder(&render_pass_descriptor); + + encoder.set_scissor_rect(MTLScissorRect { + x: 20, + y: 20, + width: 100, + height: 100, + }); + encoder.set_render_pipeline_state(&clear_rect_pipeline_state); + encoder.set_vertex_buffer(0, Some(&clear_rect_buffer), 0); + encoder.draw_primitives_instanced( + metal::MTLPrimitiveType::TriangleStrip, + 0, + 4, + 1, + ); + let physical_size = window.inner_size(); + encoder.set_scissor_rect(MTLScissorRect { + x: 0, + y: 0, + width: physical_size.width as _, + height: physical_size.height as _, + }); + + encoder.set_render_pipeline_state(&triangle_pipeline_state); + encoder.set_vertex_buffer(0, Some(&vbuf), 0); + encoder.draw_primitives(MTLPrimitiveType::Triangle, 0, 3); + encoder.end_encoding(); + + command_buffer.present_drawable(&drawable); + command_buffer.commit(); + + r += 0.01f32; + } + _ => (), + }, + _ => {} } - Event::RedrawRequested(_) => { - let p = vbuf.contents(); - let vertex_data = [ - 0.0f32, - 0.5, - 1.0, - 0.0, - 0.0, - -0.5 + (r.cos() / 2. + 0.5), - -0.5, - 0.0, - 1.0, - 0.0, - 0.5 - (r.cos() / 2. + 0.5), - -0.5, - 0.0, - 0.0, - 1.0, - ]; - - unsafe { - std::ptr::copy( - vertex_data.as_ptr(), - p as *mut f32, - (vertex_data.len() * mem::size_of::()) as usize, - ); - } - - vbuf.did_modify_range(crate::NSRange::new( - 0 as u64, - (vertex_data.len() * mem::size_of::()) as u64, - )); - - let drawable = match layer.next_drawable() { - Some(drawable) => drawable, - None => return, - }; - - let render_pass_descriptor = RenderPassDescriptor::new(); - - prepare_render_pass_descriptor(&render_pass_descriptor, drawable.texture()); - - let command_buffer = command_queue.new_command_buffer(); - let encoder = - command_buffer.new_render_command_encoder(&render_pass_descriptor); - - encoder.set_scissor_rect(MTLScissorRect { - x: 20, - y: 20, - width: 100, - height: 100, - }); - encoder.set_render_pipeline_state(&clear_rect_pipeline_state); - encoder.set_vertex_buffer(0, Some(&clear_rect_buffer), 0); - encoder.draw_primitives_instanced( - metal::MTLPrimitiveType::TriangleStrip, - 0, - 4, - 1, - ); - let physical_size = window.inner_size(); - encoder.set_scissor_rect(MTLScissorRect { - x: 0, - y: 0, - width: physical_size.width as _, - height: physical_size.height as _, - }); - - encoder.set_render_pipeline_state(&triangle_pipeline_state); - encoder.set_vertex_buffer(0, Some(&vbuf), 0); - encoder.draw_primitives(MTLPrimitiveType::Triangle, 0, 3); - encoder.end_encoding(); - - command_buffer.present_drawable(&drawable); - command_buffer.commit(); - - r += 0.01f32; - } - _ => {} - } - }); - }); + }); + }) + .unwrap(); }