Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
silvanshade committed Aug 27, 2023
1 parent 6c5e6d8 commit d9312eb
Showing 1 changed file with 111 additions and 58 deletions.
169 changes: 111 additions & 58 deletions crates/icrate/examples/metal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@
use core::ptr::NonNull;

use icrate::{
ns_string,
AppKit::{
NSApplication, NSApplicationActivationPolicyRegular, NSApplicationDelegate,
NSBackingStoreBuffered, NSWindow, NSWindowStyleMaskClosable, NSWindowStyleMaskResizable,
NSWindowStyleMaskTitled,
},
Foundation::{
NSDate, NSNotification, NSObject, NSObjectProtocol, NSPoint, NSRect, NSSize, NSString,
ns_string, NSDate, NSNotification, NSObject, NSObjectProtocol, NSPoint, NSRect, NSSize,
NSString,
},
Metal::{
MTLArgumentEncoder, MTLCommandBuffer, MTLCommandEncoder, MTLCommandQueue,
MTLCreateSystemDefaultDevice, MTLDevice, MTLDrawable, MTLFunction, MTLLibrary,
MTLPrimitiveTypeTriangle, MTLRenderCommandEncoder, MTLRenderPipelineDescriptor,
MTLRenderPipelineState,
MTLCommandBuffer, MTLCommandEncoder, MTLCommandQueue, MTLCreateSystemDefaultDevice,
MTLDevice, MTLDrawable, MTLLibrary, MTLPrimitiveTypeTriangle, MTLRenderCommandEncoder,
MTLRenderPipelineDescriptor, MTLRenderPipelineState,
},
MetalKit::{MTKView, MTKViewDelegate},
};
Expand All @@ -29,6 +28,31 @@ use objc2::{
ClassType,
};

#[repr(C)]
pub struct SceneProperties {
pub time: f32,
}

#[repr(C)]
pub struct VertexInput {
pub position: Position,
pub color: Color,
}

#[repr(C)]
pub struct Position {
pub x: f32,
pub y: f32,
pub z: f32,
}

#[repr(C)]
pub struct Color {
pub r: f32,
pub g: f32,
pub b: f32,
}

// declare the Objective-C class machinery
declare_class!(
// declare the delegate class with our instance variables
Expand Down Expand Up @@ -170,49 +194,67 @@ declare_class!(
let Some(pass_descriptor) = (unsafe { self.mtk_view.currentRenderPassDescriptor() }) else { return; };
let Some(encoder) = command_buffer.renderCommandEncoderWithDescriptor(&pass_descriptor) else { return; };

#[rustfmt::skip]
let vertex_data: &mut [f32] = &mut [
-f32::sqrt(3.0) / 4.0, -0.25, 0. , 1. , 0. , 0. ,
f32::sqrt(3.0) / 4.0, -0.25, 0. , 0. , 1. , 0. ,
0. , 0.5, 0. , 0. , 0. , 1. ,
];

let vertex_bytes = unsafe {
NonNull::new_unchecked(vertex_data.as_mut_ptr().cast::<core::ffi::c_void>())
let mut scene_properties_data = SceneProperties {
time: unsafe { self.start_date.timeIntervalSinceNow() } as f32,
};
let scene_properties_bytes =
unsafe { NonNull::new_unchecked(&mut scene_properties_data) }
.cast::<core::ffi::c_void>();
unsafe {
encoder.setVertexBytes_length_atIndex(
vertex_bytes,
vertex_data.len() * core::mem::size_of::<f32>(),
scene_properties_bytes,
core::mem::size_of::<SceneProperties>(),
0,
)
};

let argument_encoder = unsafe {
self.pipeline_descriptor
.vertexFunction()
.unwrap()
.newArgumentEncoderWithBufferIndex(1)
};

let argument_buffer = self
.device
.newBufferWithLength_options(argument_encoder.encodedLength(), 0)
.unwrap();

let vertex_input_data: &mut [VertexInput] = &mut [
VertexInput {
position: Position {
x: -f32::sqrt(3.0) / 4.0,
y: -0.25,
z: 0.,
},
color: Color {
r: 1.,
g: 0.,
b: 0.,
},
},
VertexInput {
position: Position {
x: f32::sqrt(3.0) / 4.0,
y: -0.25,
z: 0.,
},
color: Color {
r: 0.,
g: 1.,
b: 0.,
},
},
VertexInput {
position: Position {
x: 0.,
y: 0.5,
z: 0.,
},
color: Color {
r: 0.,
g: 0.,
b: 1.,
},
},
];
let vertex_input_bytes =
unsafe { NonNull::new_unchecked(vertex_input_data) }.cast::<core::ffi::c_void>();
unsafe {
argument_encoder.setArgumentBuffer_offset(Some(&*argument_buffer), 0);
};

let time = unsafe {
(argument_encoder.constantDataAtIndex(0).as_ptr() as *mut f32)
.as_mut()
.unwrap()
encoder.setVertexBytes_length_atIndex(
vertex_input_bytes,
vertex_input_data.len() * core::mem::size_of::<VertexInput>(),
1,
)
};

*time = unsafe { self.start_date.timeIntervalSinceNow() as f32 };

unsafe { encoder.setVertexBuffer_offset_atIndex(Some(&*argument_buffer), 0, 1) };

encoder.setRenderPipelineState(&self.pipeline_state);
unsafe {
Expand Down Expand Up @@ -244,38 +286,49 @@ fn main() {
let app = unsafe { NSApplication::sharedApplication() };
unsafe { app.setActivationPolicy(NSApplicationActivationPolicyRegular) };

let shaders = ns_string!(
r#"
#[rustfmt::skip]
let shaders = ns_string!(r#"
#include <metal_stdlib>
using namespace metal;
struct FragmentShaderArguments {
float time [[id(0)]];
struct SceneProperties {
float time;
};
struct VertexIn {
struct VertexInput {
packed_float3 position;
packed_float3 color;
};
struct VertexOut {
struct VertexOutput {
float4 position [[position]];
float4 color;
};
vertex VertexOut vertex_main(
device const VertexIn *vertices [[buffer(0)]],
device const FragmentShaderArguments & arg [[buffer(1)]],
uint vertexId [[vertex_id]]
) {
VertexOut out;
VertexIn vert = vertices[vertexId];
out.position = float4(float2x2(cos(arg.time), -sin(arg.time), sin(arg.time), cos(arg.time))*vert.position.xy, vert.position.z, 1);
out.color = float4(vert.color, 1);
vertex VertexOutput vertex_main(
device const SceneProperties& properties [[buffer(0)]],
device const VertexInput* vertices [[buffer(1)]],
uint vertex_idx [[vertex_id]]
) {
VertexOutput out;
VertexInput in = vertices[vertex_idx];
out.position =
float4(
float2x2(
cos(properties.time), -sin(properties.time),
sin(properties.time), cos(properties.time)
) * in.position.xy,
in.position.z,
1);
out.color = float4(in.color, 1);
return out;
}
fragment float4 fragment_main(VertexOut in [[stage_in]]) {
fragment float4 fragment_main(VertexOutput in [[stage_in]]) {
return in.color;
}
"#
);
"#);

// initialize the delegate
let delegate = Delegate::init_with_shaders(shaders);
Expand Down

0 comments on commit d9312eb

Please sign in to comment.