diff --git a/citro3d-sys/build.rs b/citro3d-sys/build.rs index ff80359..e865214 100644 --- a/citro3d-sys/build.rs +++ b/citro3d-sys/build.rs @@ -6,7 +6,7 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-env-changed=DEVKITPRO"); - println!("cargo:rustc-link-search=native={}/libctru/lib", dkp_path); + println!("cargo:rustc-link-search=native={dkp_path}/libctru/lib"); println!( "cargo:rustc-link-lib=static={}", match debug_symbols.as_str() { diff --git a/citro3d/Cargo.toml b/citro3d/Cargo.toml index 8bdaf3f..34e418e 100644 --- a/citro3d/Cargo.toml +++ b/citro3d/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" bitflags = "1.3.2" bytemuck = { version = "1.10.0", features = ["extern_crate_std"] } citro3d-sys = { git = "https://github.com/ian-h-chamberlain/citro3d-rs.git" } -ctru-rs = { git = "https://github.com/Meziu/ctru-rs.git" } +ctru-rs = { git = "https://github.com/rust3ds/ctru-rs.git" } libc = "0.2.125" [dev-dependencies] diff --git a/citro3d/examples/triangle.rs b/citro3d/examples/triangle.rs index 42084c5..e23424a 100644 --- a/citro3d/examples/triangle.rs +++ b/citro3d/examples/triangle.rs @@ -1,16 +1,16 @@ +use citro3d::render::ClearFlags; use citro3d::{include_aligned_bytes, shader}; use citro3d_sys::C3D_Mtx; -use ctru::gfx::{Gfx, Side}; +use ctru::gfx::{Gfx, Screen}; use ctru::services::apt::Apt; use ctru::services::hid::{Hid, KeyPad}; use ctru::services::soc::Soc; -use citro3d::render::ClearFlags; - use std::ffi::CStr; use std::mem::MaybeUninit; #[repr(C)] +#[derive(Copy, Clone)] struct Vec3 { x: f32, y: f32, @@ -24,6 +24,7 @@ impl Vec3 { } #[repr(C)] +#[derive(Copy, Clone)] struct Vertex { pos: Vec3, color: Vec3, @@ -58,7 +59,7 @@ fn main() { let apt = Apt::init().expect("Couldn't obtain APT controller"); let mut top_screen = gfx.top_screen.borrow_mut(); - let frame_buffer = top_screen.get_raw_framebuffer(Side::Left); + let frame_buffer = top_screen.get_raw_framebuffer(); let (width, height) = (frame_buffer.width, frame_buffer.height); let mut instance = citro3d::Instance::new().expect("failed to initialize Citro3D"); @@ -66,9 +67,6 @@ fn main() { let mut render_target = citro3d::render::Target::new(width, height, top_screen, None) .expect("failed to create render target"); - render_target.set_output(Side::Left); - render_target.set_output(Side::Right); - let mut bottom_screen = gfx.bottom_screen.borrow_mut(); let frame_buffer = bottom_screen.get_raw_framebuffer(); let (width, height) = (frame_buffer.width, frame_buffer.height); @@ -76,8 +74,6 @@ fn main() { let mut bottom_target = citro3d::render::Target::new(width, height, bottom_screen, None) .expect("failed to create bottom screen render target"); - bottom_target.set_output(Side::Left); - let shader = shader::Library::from_bytes(SHADER_BYTES).unwrap(); let vertex_shader = shader.get(0).unwrap(); diff --git a/citro3d/src/lib.rs b/citro3d/src/lib.rs index dbd92ce..fa66fc5 100644 --- a/citro3d/src/lib.rs +++ b/citro3d/src/lib.rs @@ -7,7 +7,6 @@ pub mod texture; pub mod vbo; use citro3d_sys::C3D_FrameDrawOn; -use ctru::gfx::Screen; pub use error::{Error, Result}; /// The single instance for using `citro3d`. This is the base type that an application @@ -44,10 +43,7 @@ impl Instance { /// # Errors /// /// Fails if the given target cannot be used for drawing. - pub fn select_render_target<'s, S: Screen>( - &mut self, - target: &render::Target<'s, S>, - ) -> Result<()> { + pub fn select_render_target(&mut self, target: &render::Target<'_>) -> Result<()> { let _ = self; if unsafe { C3D_FrameDrawOn(target.as_raw()) } { Ok(()) diff --git a/citro3d/src/render.rs b/citro3d/src/render.rs index a79b45f..a6fc9c9 100644 --- a/citro3d/src/render.rs +++ b/citro3d/src/render.rs @@ -7,7 +7,7 @@ use citro3d_sys::{ C3D_RenderTarget, C3D_RenderTargetCreate, C3D_RenderTargetDelete, C3D_DEPTHTYPE, GPU_COLORBUF, GPU_DEPTHBUF, }; -use ctru::gfx::{self, Screen}; +use ctru::gfx::Screen; use ctru::services::gspgpu::FramebufferFormat; use crate::{Error, Result}; @@ -16,13 +16,14 @@ mod transfer; /// A render target for `citro3d`. Frame data will be written to this target /// to be rendered on the GPU and displayed on the screen. -pub struct Target<'s, S> { +pub struct Target<'screen> { raw: *mut citro3d_sys::C3D_RenderTarget, - color_format: ColorFormat, - screen: RefMut<'s, S>, + // This is unused after construction, but ensures unique access to the + // screen this target writes to during rendering + _screen: RefMut<'screen, dyn Screen>, } -impl<'s, S> Drop for Target<'s, S> { +impl Drop for Target<'_> { fn drop(&mut self) { unsafe { C3D_RenderTargetDelete(self.raw); @@ -30,10 +31,7 @@ impl<'s, S> Drop for Target<'s, S> { } } -impl<'s, S> Target<'s, S> -where - S: Screen, -{ +impl<'screen> Target<'screen> { /// Create a new render target with the specified size, color format, /// and depth format. /// @@ -43,10 +41,11 @@ where pub fn new( width: u16, height: u16, - screen: RefMut<'s, S>, + // TODO: is there a use case for a render target that isn't associated with a Screen? + screen: RefMut<'screen, dyn Screen>, depth_format: Option, ) -> Result { - let color_format = screen.get_framebuffer_format().into(); + let color_format: ColorFormat = screen.get_framebuffer_format().into(); let raw = unsafe { C3D_RenderTargetCreate( @@ -58,33 +57,27 @@ where }; if raw.is_null() { - Err(Error::FailedToInitialize) - } else { - Ok(Self { - raw, - color_format, - screen, - }) + return Err(Error::FailedToInitialize); } - } - - /// Sets the screen to actually display the output of this render target - /// on the given [`Side`](gfx::Side). - pub fn set_output(&mut self, side: gfx::Side) { - let framebuf_format = self.screen.get_framebuffer_format(); + // Set the render target to actually output to the given screen let flags = transfer::Flags::default() - .in_format(self.color_format.into()) - .out_format(ColorFormat::from(framebuf_format).into()); + .in_format(color_format.into()) + .out_format(color_format.into()); unsafe { citro3d_sys::C3D_RenderTargetSetOutput( - self.raw, - self.screen.as_raw(), - side.into(), + raw, + screen.as_raw(), + screen.side().into(), flags.bits(), ); } + + Ok(Self { + raw, + _screen: screen, + }) } /// Clear the render target with the given 32-bit RGBA color and depth buffer value.