diff options
| author | LLLL Colonq <llll@colonq> | 2026-06-09 03:20:53 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-06-09 03:20:53 -0400 |
| commit | 9065f3c9765123f5f5bc503407c493fdb7c79488 (patch) | |
| tree | a442c9be93715217fd6e05b1bab2a20dc2fe7d18 | |
| parent | 01899d77e0e04a470fbc1ca000fef6e467334516 (diff) | |
Initial handcam stuff
| -rw-r--r-- | .dir-locals.el | 8 | ||||
| -rw-r--r-- | Cargo.lock | 134 | ||||
| -rw-r--r-- | Cargo.toml | 10 | ||||
| -rw-r--r-- | crates/renderer/Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/renderer/src/main.rs | 23 | ||||
| -rw-r--r-- | crates/renderer/src/overlay.rs | 7 | ||||
| -rw-r--r-- | crates/renderer/src/overlay/handcam.rs | 43 | ||||
| -rw-r--r-- | crates/renderer/src/overlay/model.rs | 2 | ||||
| -rw-r--r-- | crates/renderer/src/texture_server.rs | 6 |
9 files changed, 206 insertions, 28 deletions
diff --git a/.dir-locals.el b/.dir-locals.el index d0146c5..25f36dd 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -1 +1,7 @@ -((rust-mode . ((eglot-workspace-configuration . (:rust-analyzer (:cargo (:target "x86_64-unknown-linux-gnu"))))))) +((rust-ts-mode . + ((eglot-workspace-configuration . + (:rust-analyzer + ( :check (:command "clippy") + :cargo (;; :target "wasm32-unknown-unknown" + :targetDir t) + :hover (:show (:fields 10)))))))) @@ -737,6 +737,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -862,6 +868,18 @@ dependencies = [ ] [[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + +[[package]] name = "foldhash" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -919,6 +937,18 @@ dependencies = [ ] [[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1482,6 +1512,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] name = "log" version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1564,6 +1603,31 @@ dependencies = [ ] [[package]] +name = "mozjpeg" +version = "0.10.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7891b80aaa86097d38d276eb98b3805d6280708c4e0a1e6f6aed9380c51fec9" +dependencies = [ + "arrayvec", + "bytemuck", + "libc", + "mozjpeg-sys", + "rgb", +] + +[[package]] +name = "mozjpeg-sys" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f0dc668bf9bf888c88e2fb1ab16a406d2c380f1d082b20d51dd540ab2aa70c1" +dependencies = [ + "cc", + "dunce", + "libc", + "nasm-rs", +] + +[[package]] name = "mutate_once" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1598,6 +1662,25 @@ dependencies = [ ] [[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.12", +] + +[[package]] +name = "nasm-rs" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706bf8a5e8c8ddb99128c3291d31bd21f4bcde17f0f4c20ec678d85c74faa149" +dependencies = [ + "jobserver", + "log", +] + +[[package]] name = "native-tls" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1687,6 +1770,7 @@ dependencies = [ "libc", "log", "newton_shader", + "nokhwa", "png 0.18.1", "polling", "rand", @@ -1734,6 +1818,31 @@ dependencies = [ ] [[package]] +name = "nokhwa" +version = "0.10.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d63f10b450319a0ace7aa8e0e25477d1fdb345313a97e220e886175539a1dbb" +dependencies = [ + "flume", + "image", + "nokhwa-core", + "paste", + "thiserror 2.0.11", +] + +[[package]] +name = "nokhwa-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1cba20bebd3bd9ae22f9273ade5bbe49da3e047c8512b53fbaf8b4b9c80d496" +dependencies = [ + "bytes", + "image", + "mozjpeg", + "thiserror 2.0.11", +] + +[[package]] name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2319,6 +2428,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] +name = "rgb" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" +dependencies = [ + "bytemuck", +] + +[[package]] name = "ringbuf" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2428,6 +2546,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] name = "sctk-adwaita" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2653,6 +2777,15 @@ dependencies = [ ] [[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2825,7 +2958,6 @@ dependencies = [ [[package]] name = "teleia" version = "0.1.0" -source = "git+https://github.com/lcolonq/teleia#bc0e38a0ad8b15db49d311d50a69aaa157fecde8" dependencies = [ "ahash", "base64 0.22.1", @@ -21,9 +21,14 @@ strip = true debug = 0 opt-level = 2 +[workspace.lints.clippy] +all = "deny" +pedantic = "deny" +nursery = "deny" + [workspace.dependencies] -teleia = { git = "https://github.com/lcolonq/teleia" } # engine -# teleia = { path = "../teleia/crates/teleia" } # engine +# teleia = { git = "https://github.com/lcolonq/teleia" } # engine +teleia = { path = "../teleia/crates/teleia" } # engine glfw = { git = "https://github.com/lcolonq/glfw-rs", features = ["serde"] } # window management glam = { version = "0.29.2", features = ["serde"] } # linear algebra glow = { version = "=0.13.1", features = [] } # gl bindings @@ -44,6 +49,7 @@ byteorder = "1.5.0" # read little-endian numbers image = { version = "0.25.10", default-features = false, features = ["jpeg", "png", "webp"] } # read and write image files png = "*" # encode apng cpal = "*" # record microphone +nokhwa = "*" # record webcam redis = "*" # database web-image-meta = "*" # edit image metadata uuid = {version = "*", features = ["v4"]} # generate uuids diff --git a/crates/renderer/Cargo.toml b/crates/renderer/Cargo.toml index 8990d06..67003cf 100644 --- a/crates/renderer/Cargo.toml +++ b/crates/renderer/Cargo.toml @@ -31,6 +31,7 @@ byteorder = { workspace = true } image = { workspace = true } png = { workspace = true } cpal = { workspace = true } +nokhwa = { workspace = true } redis = { workspace = true } web-image-meta = { workspace = true } uuid = { workspace = true } diff --git a/crates/renderer/src/main.rs b/crates/renderer/src/main.rs index cd5c1b0..d9ff83d 100644 --- a/crates/renderer/src/main.rs +++ b/crates/renderer/src/main.rs @@ -12,36 +12,25 @@ mod ffi; mod texture_server; use teleia::*; -use clap::{command, Command, Arg}; -use std::io::Write as _; +use clap::{command, Command}; pub fn main() -> Erm<()> { let matches = command!() .propagate_version(true) .subcommand_required(true) .arg_required_else_help(true) - .subcommand( - Command::new("overlay") - .about("Run the full-screen transparent overlay") - ) - .subcommand( - Command::new("model-terminal") - .about("Run the LCOLONQ model renderer in a terminal") - ) - .subcommand( - Command::new("repair-card") - .arg(Arg::new("path")) - .about("Repair the TCG card at the given path.") - ) + .subcommand(Command::new("overlay").about("Run the full-screen transparent overlay")) + .subcommand(Command::new("model-terminal").about("Run the LCOLONQ model renderer in a terminal")) .get_matches(); match matches.subcommand() { Some(("overlay", _cm)) => { - teleia::run("LCOLONQ", 1920, 1080, teleia::Options::OVERLAY, |ctx| { - overlay::Overlays::new(ctx, vec![ + teleia::run("LCOLONQ", 1920, 1080, teleia::Options::OVERLAY, |ctx, st| { + overlay::Overlays::new(ctx, st, vec![ Box::new(overlay::automata::Overlay::new(ctx)), Box::new(overlay::shader::Overlay::new(ctx)), Box::new(overlay::tcg::Overlay::new(ctx)), Box::new(overlay::clippy::Overlay::new(ctx)), + Box::new(overlay::handcam::Overlay::new(ctx)), Box::new(overlay::combo::Overlay::new(ctx)), Box::new(overlay::drawing::Overlay::new(ctx)), Box::new(overlay::asset::Overlay::new(ctx)), diff --git a/crates/renderer/src/overlay.rs b/crates/renderer/src/overlay.rs index 40775af..7ccf1f5 100644 --- a/crates/renderer/src/overlay.rs +++ b/crates/renderer/src/overlay.rs @@ -1,3 +1,5 @@ +pub mod asset; + pub mod model; pub mod shader; pub mod drawing; @@ -6,9 +8,8 @@ pub mod tcg; pub mod loopback; pub mod clippy; pub mod combo; -pub mod asset; +pub mod handcam; -use redis::Commands; use teleia::*; use std::f32::consts::PI; @@ -158,7 +159,7 @@ pub struct Overlays { overlays: Vec<Box<dyn Overlay>> } impl Overlays { - pub fn new(ctx: &context::Context, overlays: Vec<Box<dyn Overlay>>) -> Self { + pub fn new(ctx: &context::Context, st: &mut state::State, overlays: Vec<Box<dyn Overlay>>) -> Self { Self { state: State::new(ctx), overlays, diff --git a/crates/renderer/src/overlay/handcam.rs b/crates/renderer/src/overlay/handcam.rs new file mode 100644 index 0000000..fadbf24 --- /dev/null +++ b/crates/renderer/src/overlay/handcam.rs @@ -0,0 +1,43 @@ +use teleia::*; + +use crate::overlay; + +const WIDTH: usize = 1920; +const HEIGHT: usize = 1080; +const BLOCK_SIZE: usize = 16; +const BWIDTH: usize = WIDTH / BLOCK_SIZE; +const BHEIGHT: usize = HEIGHT / BLOCK_SIZE; + +pub struct Overlay { + camera: nokhwa::Camera, + texbuf: Vec<u8>, +} +impl Overlay { + pub fn new(ctx: &context::Context) -> Self { + let index = nokhwa::utils::CameraIndex::Index(0); + let requested = nokhwa::utils::RequestedFormat::new::<nokhwa::pixel_format::RgbAFormat>( + nokhwa::utils::RequestedFormatType::AbsoluteHighestFrameRate + ); + let mut camera = nokhwa::Camera::new(index, requested).expect("failed to open webcam"); + camera.open_stream().expect("failed to open stream"); + Self { + camera, + texbuf: vec![0; WIDTH * HEIGHT * 4], + } + } +} + +impl overlay::Overlay for Overlay { + fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &net::fig::BinaryMessage) -> Erm<()> { + Ok(()) + } + fn update(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> { + let frame = self.camera.frame().unwrap(); + frame.decode_image_to_buffer::<nokhwa::pixel_format::RgbAFormat>(&mut self.texbuf) + .expect("failed to decode frame"); + Ok(()) + } + fn render(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> { + Ok(()) + } +} diff --git a/crates/renderer/src/overlay/model.rs b/crates/renderer/src/overlay/model.rs index 9c4b51b..06140ed 100644 --- a/crates/renderer/src/overlay/model.rs +++ b/crates/renderer/src/overlay/model.rs @@ -12,7 +12,7 @@ pub struct Terminal { model_fb: framebuffer::Framebuffer, } impl Terminal { - pub fn new(ctx: &context::Context) -> Self { + pub fn new(ctx: &context::Context, _st: &mut state::State) -> Self { Self { ost: overlay::State::new(ctx), output: std::io::stdout().into_raw_mode().expect("failed to set raw mode"), diff --git a/crates/renderer/src/texture_server.rs b/crates/renderer/src/texture_server.rs index ce14262..ef2c6a9 100644 --- a/crates/renderer/src/texture_server.rs +++ b/crates/renderer/src/texture_server.rs @@ -1,12 +1,12 @@ use teleia::*; -use std::io::Write; -use std::os::fd::FromRawFd; +// use std::io::Write; +// use std::os::fd::FromRawFd; use std::os::unix::net::{AncillaryData, SocketAncillary}; use std::sync::mpsc::{Receiver, channel}; use std::{os::unix::net::UnixDatagram, thread::{spawn, JoinHandle}}; -use glow::HasContext; +// use glow::HasContext; use crate::ffi::egl; use crate::ffi::glfw; |
