Browse Source

Update ctru-rs APIs based on split screen PR

pull/4/head
Ian Chamberlain 2 years ago
parent
commit
894eb66806
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 2
      citro3d-sys/build.rs
  2. 2
      citro3d/Cargo.toml
  3. 14
      citro3d/examples/triangle.rs
  4. 6
      citro3d/src/lib.rs
  5. 51
      citro3d/src/render.rs

2
citro3d-sys/build.rs

@ -6,7 +6,7 @@ fn main() { @@ -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() {

2
citro3d/Cargo.toml

@ -7,7 +7,7 @@ edition = "2021" @@ -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]

14
citro3d/examples/triangle.rs

@ -1,16 +1,16 @@ @@ -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 { @@ -24,6 +24,7 @@ impl Vec3 {
}
#[repr(C)]
#[derive(Copy, Clone)]
struct Vertex {
pos: Vec3,
color: Vec3,
@ -58,7 +59,7 @@ fn main() { @@ -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() { @@ -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() { @@ -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();

6
citro3d/src/lib.rs

@ -7,7 +7,6 @@ pub mod texture; @@ -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 { @@ -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(())

51
citro3d/src/render.rs

@ -7,7 +7,7 @@ use citro3d_sys::{ @@ -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; @@ -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> { @@ -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 @@ -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<DepthFormat>,
) -> Result<Self> {
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 @@ -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.

Loading…
Cancel
Save