Browse Source

Update example for 3D and new gfx APIs

pull/19/head
Ian Chamberlain 2 years ago
parent
commit
4fa59ada84
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 1
      Cargo.toml
  2. 69
      citro3d/examples/triangle.rs
  3. 12
      citro3d/src/render.rs

1
Cargo.toml

@ -1,5 +1,6 @@
[workspace] [workspace]
members = ["citro3d-sys", "citro3d", "bindgen-citro3d"] members = ["citro3d-sys", "citro3d", "bindgen-citro3d"]
default-members = ["citro3d", "citro3d-sys"]
[patch."https://github.com/rust3ds/citro3d-rs.git"] [patch."https://github.com/rust3ds/citro3d-rs.git"]
citro3d-sys = { path = "citro3d-sys" } citro3d-sys = { path = "citro3d-sys" }

69
citro3d/examples/triangle.rs

@ -3,11 +3,10 @@
use citro3d::render::{ClearFlags, Target}; use citro3d::render::{ClearFlags, Target};
use citro3d::{include_aligned_bytes, shader}; use citro3d::{include_aligned_bytes, shader};
use citro3d_sys::C3D_Mtx; use citro3d_sys::C3D_Mtx;
use ctru::gfx::{Gfx, RawFrameBuffer, Screen}; use ctru::prelude::*;
use ctru::services::apt::Apt; use ctru::services::gfx::{RawFrameBuffer, Screen, TopScreen3D};
use ctru::services::hid::{Hid, KeyPad};
use ctru::services::soc::Soc;
use std::f32::consts::PI;
use std::ffi::CStr; use std::ffi::CStr;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
@ -51,25 +50,31 @@ static SHADER_BYTES: &[u8] =
include_aligned_bytes!(concat!(env!("OUT_DIR"), "/examples/assets/vshader.shbin")); include_aligned_bytes!(concat!(env!("OUT_DIR"), "/examples/assets/vshader.shbin"));
fn main() { fn main() {
ctru::init(); ctru::use_panic_handler();
let mut soc = Soc::init().expect("failed to get SOC"); let mut soc = Soc::new().expect("failed to get SOC");
drop(soc.redirect_to_3dslink(true, true)); drop(soc.redirect_to_3dslink(true, true));
let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let hid = Hid::init().expect("Couldn't obtain HID controller"); let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller"); let apt = Apt::new().expect("Couldn't obtain APT controller");
let mut top_screen = gfx.top_screen.borrow_mut();
let RawFrameBuffer { width, height, .. } = top_screen.get_raw_framebuffer();
let mut instance = citro3d::Instance::new().expect("failed to initialize Citro3D"); let mut instance = citro3d::Instance::new().expect("failed to initialize Citro3D");
let mut top_target = citro3d::render::Target::new(width, height, top_screen, None) let top_screen = TopScreen3D::from(&gfx.top_screen);
let (mut top_left, mut top_right) = top_screen.split_mut();
let RawFrameBuffer { width, height, .. } = top_left.raw_framebuffer();
let mut top_left_target = citro3d::render::Target::new(width, height, top_left, None)
.expect("failed to create render target");
let RawFrameBuffer { width, height, .. } = top_right.raw_framebuffer();
let mut top_right_target = citro3d::render::Target::new(width, height, top_right, None)
.expect("failed to create render target"); .expect("failed to create render target");
let mut bottom_screen = gfx.bottom_screen.borrow_mut(); let mut bottom_screen = gfx.bottom_screen.borrow_mut();
let RawFrameBuffer { width, height, .. } = bottom_screen.get_raw_framebuffer(); let RawFrameBuffer { width, height, .. } = bottom_screen.raw_framebuffer();
let mut bottom_target = citro3d::render::Target::new(width, height, bottom_screen, None) let mut bottom_target = citro3d::render::Target::new(width, height, bottom_screen, None)
.expect("failed to create bottom screen render target"); .expect("failed to create bottom screen render target");
@ -82,29 +87,35 @@ fn main() {
let mut vbo_data = Vec::with_capacity_in(VERTICES.len(), ctru::linear::LinearAllocator); let mut vbo_data = Vec::with_capacity_in(VERTICES.len(), ctru::linear::LinearAllocator);
vbo_data.extend_from_slice(VERTICES); vbo_data.extend_from_slice(VERTICES);
let (uloc_projection, projection) = scene_init(&mut program, &vbo_data); let (projection_uniform_idx, mut projection) = scene_init(&mut program, &vbo_data);
unsafe { citro3d_sys::Mtx_RotateY(&mut projection, -PI / 12.0, true) };
let mut right_eye_projection = projection;
unsafe { citro3d_sys::Mtx_RotateY(&mut right_eye_projection, 2.0 * PI / 12.0, true) };
while apt.main_loop() { while apt.main_loop() {
hid.scan_input(); hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) { if hid.keys_down().contains(KeyPad::START) {
break; break;
} }
let mut render_to = |target: &mut Target| { instance.render_frame_with(|instance| {
instance.render_frame_with(|instance| { let mut render_to = |target: &mut Target, projection| {
instance instance
.select_render_target(target) .select_render_target(target)
.expect("failed to set render target"); .expect("failed to set render target");
let clear_color: u32 = 0x7F_7F_7F_FF; let clear_color: u32 = 0x7F_7F_7F_FF;
target.clear(ClearFlags::ALL, clear_color, 0); target.clear(ClearFlags::ALL, clear_color, 0);
scene_render(uloc_projection.into(), &projection); scene_render(projection_uniform_idx.into(), projection);
}); };
};
render_to(&mut top_target); render_to(&mut top_left_target, &projection);
render_to(&mut bottom_target); render_to(&mut top_right_target, &right_eye_projection);
render_to(&mut bottom_target, &projection);
});
} }
} }
@ -115,7 +126,7 @@ fn scene_init(program: &mut shader::Program, vbo_data: &[Vertex]) -> (i8, C3D_Mt
// Get the location of the uniforms // Get the location of the uniforms
let projection_name = CStr::from_bytes_with_nul(b"projection\0").unwrap(); let projection_name = CStr::from_bytes_with_nul(b"projection\0").unwrap();
let uloc_projection = ctru_sys::shaderInstanceGetUniformLocation( let projection_uniform_idx = ctru_sys::shaderInstanceGetUniformLocation(
(*program.as_raw()).vertexShader, (*program.as_raw()).vertexShader,
projection_name.as_ptr(), projection_name.as_ptr(),
); );
@ -169,14 +180,18 @@ fn scene_init(program: &mut shader::Program, vbo_data: &[Vertex]) -> (i8, C3D_Mt
); );
citro3d_sys::C3D_TexEnvFunc(env, citro3d_sys::C3D_Both, ctru_sys::GPU_REPLACE); citro3d_sys::C3D_TexEnvFunc(env, citro3d_sys::C3D_Both, ctru_sys::GPU_REPLACE);
(uloc_projection, projection) (projection_uniform_idx, projection)
} }
} }
fn scene_render(uloc_projection: i32, projection: &C3D_Mtx) { fn scene_render(projection_uniform_idx: i32, projection: &C3D_Mtx) {
unsafe { unsafe {
// Update the uniforms // Update the uniforms
citro3d_sys::C3D_FVUnifMtx4x4(ctru_sys::GPU_VERTEX_SHADER, uloc_projection, projection); citro3d_sys::C3D_FVUnifMtx4x4(
ctru_sys::GPU_VERTEX_SHADER,
projection_uniform_idx,
projection,
);
// Draw the VBO // Draw the VBO
citro3d_sys::C3D_DrawArrays( citro3d_sys::C3D_DrawArrays(

12
citro3d/src/render.rs

@ -6,7 +6,7 @@ use std::cell::RefMut;
use citro3d_sys::{ use citro3d_sys::{
C3D_RenderTarget, C3D_RenderTargetCreate, C3D_RenderTargetDelete, C3D_DEPTHTYPE, C3D_RenderTarget, C3D_RenderTargetCreate, C3D_RenderTargetDelete, C3D_DEPTHTYPE,
}; };
use ctru::gfx::Screen; use ctru::services::gfx::Screen;
use ctru::services::gspgpu::FramebufferFormat; use ctru::services::gspgpu::FramebufferFormat;
use ctru_sys::{GPU_COLORBUF, GPU_DEPTHBUF}; use ctru_sys::{GPU_COLORBUF, GPU_DEPTHBUF};
@ -39,17 +39,17 @@ impl<'screen> Target<'screen> {
/// ///
/// Fails if the target could not be created. /// Fails if the target could not be created.
pub fn new( pub fn new(
width: u16, width: usize,
height: u16, height: usize,
screen: RefMut<'screen, dyn Screen>, screen: RefMut<'screen, dyn Screen>,
depth_format: Option<DepthFormat>, depth_format: Option<DepthFormat>,
) -> Result<Self> { ) -> Result<Self> {
let color_format: ColorFormat = screen.get_framebuffer_format().into(); let color_format: ColorFormat = screen.framebuffer_format().into();
let raw = unsafe { let raw = unsafe {
C3D_RenderTargetCreate( C3D_RenderTargetCreate(
width.into(), width.try_into()?,
height.into(), height.try_into()?,
color_format as GPU_COLORBUF, color_format as GPU_COLORBUF,
depth_format.map_or(C3D_DEPTHTYPE { __i: -1 }, DepthFormat::as_raw), depth_format.map_or(C3D_DEPTHTYPE { __i: -1 }, DepthFormat::as_raw),
) )

Loading…
Cancel
Save