Browse Source

Add safe wrapper for C3D_BindProgram

pull/33/head
Ian Chamberlain 1 year ago
parent
commit
d2b65c8ff1
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 9
      citro3d/examples/triangle.rs
  2. 12
      citro3d/src/lib.rs
  3. 8
      citro3d/src/shader.rs

9
citro3d/examples/triangle.rs

@ -79,7 +79,8 @@ fn main() {
let shader = shader::Library::from_bytes(SHADER_BYTES).unwrap(); let shader = shader::Library::from_bytes(SHADER_BYTES).unwrap();
let vertex_shader = shader.get(0).unwrap(); let vertex_shader = shader.get(0).unwrap();
let mut program = shader::Program::new(vertex_shader).unwrap(); let program = shader::Program::new(vertex_shader).unwrap();
instance.bind_program(&program);
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);
@ -87,7 +88,7 @@ fn main() {
let mut buf_info = buffer::Info::new(); let mut buf_info = buffer::Info::new();
let (attr_info, vbo_idx) = prepare_vbos(&mut buf_info, &vbo_data); let (attr_info, vbo_idx) = prepare_vbos(&mut buf_info, &vbo_data);
scene_init(&mut program); scene_init();
let projection_uniform_idx = program.get_uniform("projection").unwrap(); let projection_uniform_idx = program.get_uniform("projection").unwrap();
@ -191,11 +192,9 @@ fn calculate_projections() -> Projections {
} }
} }
fn scene_init(program: &mut shader::Program) { fn scene_init() {
// Load the vertex shader, create a shader program and bind it // Load the vertex shader, create a shader program and bind it
unsafe { unsafe {
citro3d_sys::C3D_BindProgram(program.as_raw_mut());
// Configure the first fragment shading substage to just pass through the vertex color // Configure the first fragment shading substage to just pass through the vertex color
// See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight // See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight
let env = citro3d_sys::C3D_GetTexEnv(0); let env = citro3d_sys::C3D_GetTexEnv(0);

12
citro3d/src/lib.rs

@ -73,7 +73,8 @@ impl Instance {
} }
/// Render a frame. The passed in function/closure can mutate the instance, /// Render a frame. The passed in function/closure can mutate the instance,
/// such as to [select a render target](Self::select_render_target). /// such as to [select a render target](Self::select_render_target)
/// or [bind a new shader program](Self::bind_program).
#[doc(alias = "C3D_FrameBegin")] #[doc(alias = "C3D_FrameBegin")]
#[doc(alias = "C3D_FrameEnd")] #[doc(alias = "C3D_FrameEnd")]
pub fn render_frame_with(&mut self, f: impl FnOnce(&mut Self)) { pub fn render_frame_with(&mut self, f: impl FnOnce(&mut Self)) {
@ -139,6 +140,15 @@ impl Instance {
} }
} }
/// Use the given [`shader::Program`] for subsequent draw calls.
pub fn bind_program(&mut self, program: &shader::Program) {
// SAFETY: AFAICT C3D_BindProgram just copies pointers from the given program,
// instead of mutating the pointee in any way that would cause UB
unsafe {
citro3d_sys::C3D_BindProgram(program.as_raw().cast_mut());
}
}
/// Bind a uniform to the given `index` in the vertex shader for the next draw call. /// Bind a uniform to the given `index` in the vertex shader for the next draw call.
/// ///
/// # Example /// # Example

8
citro3d/src/shader.rs

@ -17,6 +17,7 @@ use crate::uniform;
/// ///
/// The PICA200 does not support user-programmable fragment shaders. /// The PICA200 does not support user-programmable fragment shaders.
#[doc(alias = "shaderProgram_s")] #[doc(alias = "shaderProgram_s")]
#[must_use]
pub struct Program { pub struct Program {
program: ctru_sys::shaderProgram_s, program: ctru_sys::shaderProgram_s,
} }
@ -102,18 +103,13 @@ impl Program {
pub(crate) fn as_raw(&self) -> *const ctru_sys::shaderProgram_s { pub(crate) fn as_raw(&self) -> *const ctru_sys::shaderProgram_s {
&self.program &self.program
} }
// TODO: pub(crate)
pub fn as_raw_mut(&mut self) -> *mut ctru_sys::shaderProgram_s {
&mut self.program
}
} }
impl Drop for Program { impl Drop for Program {
#[doc(alias = "shaderProgramFree")] #[doc(alias = "shaderProgramFree")]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
let _ = ctru_sys::shaderProgramFree(self.as_raw_mut()); let _ = ctru_sys::shaderProgramFree(self.as_raw().cast_mut());
} }
} }
} }

Loading…
Cancel
Save