summaryrefslogtreecommitdiff
path: root/crates/renderer/src
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2026-06-09 03:20:53 -0400
committerLLLL Colonq <llll@colonq>2026-06-09 03:20:53 -0400
commit9065f3c9765123f5f5bc503407c493fdb7c79488 (patch)
treea442c9be93715217fd6e05b1bab2a20dc2fe7d18 /crates/renderer/src
parent01899d77e0e04a470fbc1ca000fef6e467334516 (diff)
Initial handcam stuff
Diffstat (limited to 'crates/renderer/src')
-rw-r--r--crates/renderer/src/main.rs23
-rw-r--r--crates/renderer/src/overlay.rs7
-rw-r--r--crates/renderer/src/overlay/handcam.rs43
-rw-r--r--crates/renderer/src/overlay/model.rs2
-rw-r--r--crates/renderer/src/texture_server.rs6
5 files changed, 57 insertions, 24 deletions
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;