From 0e02f904424fbd7a8283083e57faf291e311790f Mon Sep 17 00:00:00 2001 From: Ian Chamberlain Date: Sat, 25 Nov 2023 00:13:35 -0500 Subject: [PATCH] Initial texenv implementation --- citro3d-sys/bindgen.sh | 5 -- citro3d/examples/triangle.rs | 25 +++------ citro3d/src/lib.rs | 1 + citro3d/src/texenv.rs | 99 ++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 24 deletions(-) delete mode 100755 citro3d-sys/bindgen.sh create mode 100644 citro3d/src/texenv.rs diff --git a/citro3d-sys/bindgen.sh b/citro3d-sys/bindgen.sh deleted file mode 100755 index ebb4ff9..0000000 --- a/citro3d-sys/bindgen.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail - -cargo run --package bindgen-citro3d > src/bindings.rs diff --git a/citro3d/examples/triangle.rs b/citro3d/examples/triangle.rs index a6a5152..ca1358a 100644 --- a/citro3d/examples/triangle.rs +++ b/citro3d/examples/triangle.rs @@ -6,6 +6,7 @@ use citro3d::macros::include_shader; use citro3d::math::{AspectRatio, ClipPlanes, Matrix4, Projection, StereoDisplacement}; use citro3d::render::ClearFlags; +use citro3d::texenv::{self, CombineFunc, TexEnv}; use citro3d::{attrib, buffer, render, shader}; use ctru::prelude::*; use ctru::services::gfx::{RawFrameBuffer, Screen, TopScreen3D}; @@ -88,7 +89,11 @@ fn main() { let mut buf_info = buffer::Info::new(); let (attr_info, vbo_idx) = prepare_vbos(&mut buf_info, &vbo_data); - scene_init(); + // 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 + TexEnv::get(&mut instance, texenv::Id(0)) + .src(texenv::Mode::BOTH, texenv::Source::PrimaryColor, None, None) + .func(texenv::Mode::BOTH, CombineFunc::Replace); let projection_uniform_idx = program.get_uniform("projection").unwrap(); @@ -191,21 +196,3 @@ fn calculate_projections() -> Projections { center, } } - -fn scene_init() { - // Load the vertex shader, create a shader program and bind it - unsafe { - // 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 - let env = citro3d_sys::C3D_GetTexEnv(0); - citro3d_sys::C3D_TexEnvInit(env); - citro3d_sys::C3D_TexEnvSrc( - env, - citro3d_sys::C3D_Both, - ctru_sys::GPU_PRIMARY_COLOR, - 0, - 0, - ); - citro3d_sys::C3D_TexEnvFunc(env, citro3d_sys::C3D_Both, ctru_sys::GPU_REPLACE); - } -} diff --git a/citro3d/src/lib.rs b/citro3d/src/lib.rs index 9368b5c..3cdd983 100644 --- a/citro3d/src/lib.rs +++ b/citro3d/src/lib.rs @@ -15,6 +15,7 @@ pub mod error; pub mod math; pub mod render; pub mod shader; +pub mod texenv; pub mod uniform; pub use error::{Error, Result}; diff --git a/citro3d/src/texenv.rs b/citro3d/src/texenv.rs new file mode 100644 index 0000000..fc5798a --- /dev/null +++ b/citro3d/src/texenv.rs @@ -0,0 +1,99 @@ +//! Texture environment support. See `` for more information. + +use bitflags::bitflags; + +use crate::Instance; + +#[doc(alias = "C3D_TexEnv")] +pub struct TexEnv<'a> { + raw: *mut citro3d_sys::C3D_TexEnv, + _instance: &'a mut Instance, +} + +impl<'a> TexEnv<'a> { + #[doc(alias = "C3D_TexEnvInit")] + pub fn set(&self, _instance: &mut Instance, id: Id) { + unsafe { + // SAFETY: pointee is only copied from, not modified + citro3d_sys::C3D_SetTexEnv(id.0, self.raw); + } + } + + pub fn get(instance: &'a mut Instance, id: Id) -> Self { + unsafe { + Self { + raw: citro3d_sys::C3D_GetTexEnv(id.0), + _instance: instance, + } + } + } + + pub fn src( + &mut self, + mode: Mode, + s1: Source, + s2: Option, + s3: Option, + ) -> &mut Self { + unsafe { + citro3d_sys::C3D_TexEnvSrc( + self.raw, + mode.bits(), + s1 as _, + s2.unwrap_or(Source::PrimaryColor) as _, + s3.unwrap_or(Source::PrimaryColor) as _, + ) + } + self + } + + pub fn func(&mut self, mode: Mode, func: CombineFunc) -> &mut Self { + unsafe { + citro3d_sys::C3D_TexEnvFunc(self.raw, mode.bits(), func as _); + } + + self + } +} + +bitflags! { + #[doc(alias = "C3D_TexEnvMode")] + pub struct Mode: citro3d_sys::C3D_TexEnvMode { + const RGB = citro3d_sys::C3D_RGB; + const ALPHA = citro3d_sys::C3D_Alpha; + const BOTH = citro3d_sys::C3D_Both; + } +} + +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +#[doc(alias = "GPU_TEVSRC")] +pub enum Source { + PrimaryColor = ctru_sys::GPU_PRIMARY_COLOR, + FragmentPrimaryColor = ctru_sys::GPU_FRAGMENT_PRIMARY_COLOR, + FragmentSecondaryColor = ctru_sys::GPU_FRAGMENT_SECONDARY_COLOR, + Texture0 = ctru_sys::GPU_TEXTURE0, + Texture1 = ctru_sys::GPU_TEXTURE1, + Texture2 = ctru_sys::GPU_TEXTURE2, + Texture3 = ctru_sys::GPU_TEXTURE3, + PreviousBuffer = ctru_sys::GPU_PREVIOUS_BUFFER, + Constant = ctru_sys::GPU_CONSTANT, + Previous = ctru_sys::GPU_PREVIOUS, +} + +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +#[doc(alias = "GPU_COMBINEFUNC")] +pub enum CombineFunc { + Replace = ctru_sys::GPU_REPLACE, + Modulate = ctru_sys::GPU_MODULATE, + Add = ctru_sys::GPU_ADD, + AddSigned = ctru_sys::GPU_ADD_SIGNED, + Interpolate = ctru_sys::GPU_INTERPOLATE, + Subtract = ctru_sys::GPU_SUBTRACT, + Dot3Rgb = ctru_sys::GPU_DOT3_RGB, + Dot3Rgba = ctru_sys::GPU_DOT3_RGBA, +} + +#[derive(Copy, Clone, Debug)] +pub struct Id(/* TODO maybe non pub? idk */ pub libc::c_int);