Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dev-dependencies: cocoa, glam, winit. #310

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
Expand Down
165 changes: 87 additions & 78 deletions examples/circle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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();
Expand All @@ -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
Expand Down
106 changes: 58 additions & 48 deletions examples/mesh-shader/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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");
Expand All @@ -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();
Expand Down Expand Up @@ -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();
}
Loading
Loading