From e5e2e635864bc602b5e73116246a78d9f5c4eda1 Mon Sep 17 00:00:00 2001 From: Ian Chamberlain Date: Wed, 18 May 2022 08:49:59 -0400 Subject: [PATCH] port frame begin/end to safe rust --- citro3d/Cargo.toml | 1 - citro3d/examples/triangle.rs | 34 ++++++++++++---------------------- citro3d/src/lib.rs | 19 +++++++++++++++++++ 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/citro3d/Cargo.toml b/citro3d/Cargo.toml index fd1189d..8be434a 100644 --- a/citro3d/Cargo.toml +++ b/citro3d/Cargo.toml @@ -2,7 +2,6 @@ name = "citro3d" version = "0.1.0" edition = "2021" -authors = [""] [dependencies] bitflags = "1.3.2" diff --git a/citro3d/examples/triangle.rs b/citro3d/examples/triangle.rs index bce6779..6f3095d 100644 --- a/citro3d/examples/triangle.rs +++ b/citro3d/examples/triangle.rs @@ -44,6 +44,9 @@ const VERTICES: &[Vertex] = &[ }, ]; +static SHADER_BYTES: &[u8] = + include_bytes!(concat!(env!("OUT_DIR"), "/examples/assets/vshader.shbin")); + fn main() { ctru::init(); @@ -78,38 +81,25 @@ fn main() { break; } - unsafe { - citro3d_sys::C3D_FrameBegin( - citro3d_sys::C3D_FRAME_SYNCDRAW - .try_into() - .expect("const is valid u8"), - ); - } - - let clear_color: u32 = 0x7F_7F_7F_FF; - render_target.clear(ClearFlags::ALL, clear_color, 0); + instance.render_frame_with(|instance| { + let clear_color: u32 = 0x7F_7F_7F_FF; + render_target.clear(ClearFlags::ALL, clear_color, 0); - instance - .select_render_target(&render_target) - .expect("failed to set render target"); + instance + .select_render_target(&render_target) + .expect("failed to set render target"); - scene_render(uloc_projection.into(), &projection); - - unsafe { - citro3d_sys::C3D_FrameEnd(0); - } + scene_render(uloc_projection.into(), &projection); + }); } scene_exit(vbo_data, program, vshader_dvlb); } -static SHBIN_BYTES: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/examples/assets/vshader.shbin")); - fn scene_init() -> (shaderProgram_s, i8, C3D_Mtx, *mut libc::c_void, *mut DVLB_s) { // Load the vertex shader, create a shader program and bind it unsafe { - let mut shader_bytes = SHBIN_BYTES.to_owned(); + let mut shader_bytes = SHADER_BYTES.to_owned(); // Assume the data is aligned properly... let vshader_dvlb = citro3d_sys::DVLB_ParseFile( diff --git a/citro3d/src/lib.rs b/citro3d/src/lib.rs index 159d995..7d27f4f 100644 --- a/citro3d/src/lib.rs +++ b/citro3d/src/lib.rs @@ -74,6 +74,25 @@ impl Instance { Err(Error::InvalidRenderTarget) } } + + /// Render a frame. The passed in function/closure can mutate the instance, + /// such as to [select a render target](Self::select_render_target). + pub fn render_frame_with(&mut self, f: impl FnOnce(&mut Self)) { + unsafe { + citro3d_sys::C3D_FrameBegin( + // TODO: begin + end flags should be configurable + citro3d_sys::C3D_FRAME_SYNCDRAW + .try_into() + .expect("const is valid u8"), + ); + } + + f(self); + + unsafe { + citro3d_sys::C3D_FrameEnd(0); + } + } } impl Drop for Instance {