1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
extern crate objc;
use cocoa::{appkit::NSView, base::id as cocoa_id};
use core_graphics_types::geometry::CGSize;
use metal::*;
use objc::{rc::autoreleasepool, runtime::YES};
use std::mem;
use winit::{
event::{Event, WindowEvent},
event_loop::ControlFlow,
platform::macos::WindowExtMacOS,
};
pub mod camera;
pub mod geometry;
pub mod renderer;
pub mod scene;
fn find_raytracing_supporting_device() -> Device {
for device in Device::all() {
if !device.supports_raytracing() {
continue;
}
if device.is_low_power() {
continue;
}
return device;
}
panic!("No device in this machine supports raytracing!")
}
fn main() {
let events_loop = winit::event_loop::EventLoop::new();
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)
.unwrap();
let device = find_raytracing_supporting_device();
let layer = MetalLayer::new();
layer.set_device(&device);
layer.set_pixel_format(MTLPixelFormat::RGBA16Float);
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()));
}
let draw_size = window.inner_size();
let cg_size = CGSize::new(draw_size.width as f64, draw_size.height as f64);
layer.set_drawable_size(cg_size);
let mut renderer = renderer::Renderer::new(device);
renderer.window_resized(cg_size);
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) => {
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);
}
_ => {}
}
});
});
}
|