summaryrefslogtreecommitdiff
path: root/crates/renderer
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2026-06-04 18:49:58 -0400
committerLLLL Colonq <llll@colonq>2026-06-04 18:50:57 -0400
commit2a8b8e6392d87247a5e7b73773daeece98fa0a73 (patch)
tree60ba094d9e3d47c9695af32aa4b7ce9f9a8695c3 /crates/renderer
parent5bdcffbe94fdc3ce9a12b3ae61e7bff3bcb2f17a (diff)
Update
Diffstat (limited to 'crates/renderer')
-rw-r--r--crates/renderer/src/assets/textures/placeholder.pngbin0 -> 162 bytes
-rw-r--r--crates/renderer/src/main.rs1
-rw-r--r--crates/renderer/src/overlay.rs3
-rw-r--r--crates/renderer/src/overlay/asset.rs120
-rw-r--r--crates/renderer/src/overlay/combo.rs15
-rw-r--r--crates/renderer/src/overlay/shader.rs2
-rw-r--r--crates/renderer/src/overlay/tcg.rs88
-rw-r--r--crates/renderer/src/terminal.rs8
8 files changed, 200 insertions, 37 deletions
diff --git a/crates/renderer/src/assets/textures/placeholder.png b/crates/renderer/src/assets/textures/placeholder.png
new file mode 100644
index 0000000..e0990b9
--- /dev/null
+++ b/crates/renderer/src/assets/textures/placeholder.png
Binary files differ
diff --git a/crates/renderer/src/main.rs b/crates/renderer/src/main.rs
index 6f951ac..cd5c1b0 100644
--- a/crates/renderer/src/main.rs
+++ b/crates/renderer/src/main.rs
@@ -44,6 +44,7 @@ pub fn main() -> Erm<()> {
Box::new(overlay::clippy::Overlay::new(ctx)),
Box::new(overlay::combo::Overlay::new(ctx)),
Box::new(overlay::drawing::Overlay::new(ctx)),
+ Box::new(overlay::asset::Overlay::new(ctx)),
// Box::new(overlay::model::Overlay::new(ctx)),
// Box::new(overlay::loopback::Overlay::new(ctx)),
])
diff --git a/crates/renderer/src/overlay.rs b/crates/renderer/src/overlay.rs
index 90c2016..40775af 100644
--- a/crates/renderer/src/overlay.rs
+++ b/crates/renderer/src/overlay.rs
@@ -6,6 +6,7 @@ pub mod tcg;
pub mod loopback;
pub mod clippy;
pub mod combo;
+pub mod asset;
use redis::Commands;
use teleia::*;
@@ -95,6 +96,8 @@ impl State {
b"overlay clippy border on",
b"overlay clippy border off",
b"overlay combo message",
+ b"overlay asset display",
+ b"overlay asset clear",
]).expect("failed to connect to bus"),
texture_server: texture_server::Server::new(ctx),
tracking: Tracking {
diff --git a/crates/renderer/src/overlay/asset.rs b/crates/renderer/src/overlay/asset.rs
new file mode 100644
index 0000000..a616703
--- /dev/null
+++ b/crates/renderer/src/overlay/asset.rs
@@ -0,0 +1,120 @@
+use teleia::*;
+
+use crate::overlay;
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub enum AssetSort {
+ Texture,
+ Mesh,
+}
+impl AssetSort {
+ pub fn from_str(s: &str) -> Option<Self> {
+ match s {
+ "texture" => Some(Self::Texture),
+ "mesh" => Some(Self::Mesh),
+ _ => None,
+ }
+ }
+}
+#[derive(Clone, PartialEq, Eq)]
+pub struct DisplayedAsset {
+ sort: AssetSort,
+ path: String,
+}
+pub struct Overlay {
+ loaded: Option<DisplayedAsset>,
+ displayed: Option<DisplayedAsset>,
+ texture_placeholder: texture::Texture,
+ texture: texture::Texture,
+ mesh: mesh::Mesh,
+}
+impl Overlay {
+ pub fn new(ctx: &context::Context) -> Self {
+ Self {
+ loaded: None,
+ displayed: None,
+ texture_placeholder: texture::Texture::new(ctx, include_bytes!("../assets/textures/placeholder.png")),
+ texture: texture::Texture::new_empty(ctx),
+ mesh: mesh::Mesh::new_empty(ctx, true, true),
+ }
+ }
+ pub fn load_displayed(&mut self, ctx: &context::Context) -> Erm<()> {
+ if let Some(d) = &self.displayed {
+ match d.sort {
+ AssetSort::Texture => {
+ let bs = std::fs::read(&d.path)?;
+ self.texture.upload(ctx, &bs);
+ },
+ AssetSort::Mesh => {
+ let bs = std::fs::read(&d.path)?;
+ self.mesh.upload_obj(ctx, &bs);
+ },
+ }
+ }
+ Ok(())
+ }
+}
+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<()> {
+ match &*msg.event {
+ b"overlay asset display" => {
+ let mut reader = std::io::Cursor::new(&msg.data);
+ let ssort = net::fig::read_length_prefixed_utf8(&mut reader)?;
+ let path = net::fig::read_length_prefixed_utf8(&mut reader)?;
+ if let Some(sort) = AssetSort::from_str(&ssort) {
+ log::warn!("displaying {} asset at: {}", ssort, path);
+ let new = Some(DisplayedAsset {sort, path});
+ if new != self.displayed {
+ self.displayed = new.clone();
+ if self.displayed != self.loaded {
+ if let Err(e) = self.load_displayed(ctx) {
+ self.displayed = None;
+ log::warn!("error when loading asset: {}", e);
+ } else {
+ self.loaded = new;
+ }
+ }
+ }
+ } else {
+ log::warn!("unknown asset sort: {}", ssort);
+ }
+ },
+ b"overlay asset clear" => {
+ self.displayed = None;
+ },
+ _ => {},
+ }
+ Ok(())
+ }
+ fn render(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
+ if let Some(d) = &self.displayed {
+ match d.sort {
+ AssetSort::Texture => {
+ st.bind_2d(ctx, &ost.assets.shader_flat);
+ self.texture.bind(ctx);
+ ost.assets.shader_flat.set_position_2d(
+ ctx, st,
+ &glam::Vec2::new(ost.info.emacs_cursor.0, ost.info.emacs_cursor.1),
+ &glam::Vec2::new(self.texture.width as f32, self.texture.height as f32)
+ );
+ st.mesh_square.render(ctx);
+ },
+ AssetSort::Mesh => {
+ st.bind_3d(ctx, &ost.assets.shader_flat);
+ ost.assets.shader_flat.set_f32(ctx, "transparency", 0.0);
+ self.texture_placeholder.bind(ctx);
+ ost.assets.shader_flat.set_position_3d(
+ ctx, st,
+ &glam::Mat4::from_scale_rotation_translation(
+ glam::Vec3::new(1.0, 1.0, 1.0),
+ glam::Quat::from_rotation_y(st.tick as f32 / 75.0),
+ glam::Vec3::new(0.0, 0.0, -8.0)
+ ),
+ );
+ self.mesh.render(ctx);
+ },
+ }
+ }
+ Ok(())
+ }
+}
diff --git a/crates/renderer/src/overlay/combo.rs b/crates/renderer/src/overlay/combo.rs
index f200e22..bf415a5 100644
--- a/crates/renderer/src/overlay/combo.rs
+++ b/crates/renderer/src/overlay/combo.rs
@@ -160,35 +160,38 @@ impl overlay::Overlay for Overlay {
// tags
let mut tagy = 124.0;
for (t, count) in self.tags.iter() {
- self.font.render_text_parameterized(
+ self.font.render_text_at(
ctx, st,
- &glam::Vec2::new(4.0, tagy),
+ glam::Vec2::new(4.0, tagy),
&format!("+ {t} (x{count})"),
font::BitmapParams {
color: &[glam::Vec3::new(1.0, 1.0, 1.0)],
scale: glam::Vec2::new(2.0, 2.0),
+ offset: glam::Vec2::ZERO,
},
);
tagy += 24.0;
}
// multiplier
- self.font.render_text_parameterized(
+ self.font.render_text_at(
ctx, st,
- &glam::Vec2::new(4.0, HEIGHT as f32 - 50.0),
+ glam::Vec2::new(4.0, HEIGHT as f32 - 50.0),
&format!("MULT:"),
font::BitmapParams {
color: &[glam::Vec3::new(1.0, 1.0, 1.0)],
scale: glam::Vec2::new(4.0, 4.0),
+ offset: glam::Vec2::ZERO,
},
);
- self.font.render_text_parameterized(
+ self.font.render_text_at(
ctx, st,
- &glam::Vec2::new(128.0, HEIGHT as f32 - 50.0),
+ glam::Vec2::new(128.0, HEIGHT as f32 - 50.0),
&format!("{}x", self.tag_multiplier()),
font::BitmapParams {
color: &[glam::Vec3::new(1.0, 0.7, 0.0)],
scale: glam::Vec2::new(4.0, 4.0),
+ offset: glam::Vec2::ZERO,
},
);
diff --git a/crates/renderer/src/overlay/shader.rs b/crates/renderer/src/overlay/shader.rs
index b30242f..05374e9 100644
--- a/crates/renderer/src/overlay/shader.rs
+++ b/crates/renderer/src/overlay/shader.rs
@@ -105,7 +105,7 @@ impl overlay::Overlay for Overlay {
authors.push(format!("music by {}", a));
}
let astr: String = authors.join(", ");
- ost.assets.font.render_text(ctx, st, &glam::Vec2::new(0.0, 0.0), &astr);
+ ost.assets.font.render_text_at(ctx, st, glam::Vec2::new(0.0, 0.0), &astr, font::BitmapParams::default());
Ok(())
}
}
diff --git a/crates/renderer/src/overlay/tcg.rs b/crates/renderer/src/overlay/tcg.rs
index acc9915..484f265 100644
--- a/crates/renderer/src/overlay/tcg.rs
+++ b/crates/renderer/src/overlay/tcg.rs
@@ -1,7 +1,6 @@
use teleia::*;
use std::{cell::RefCell, rc::Rc};
-use std::fmt::Write as _;
use redis::Commands;
use image::EncodableLayout;
@@ -340,13 +339,14 @@ impl Marquee {
if let Some(c) = &s.card.card {
let scale = 4.0;
let owner_width = c.owner.len() as f32 * self.font.char_width as f32 * scale;
- self.font.render_text_parameterized(ctx, st,
- &(p_screen + glam::Vec2::new(-owner_width / 2.0,
- -200.0 + if s.height_offset { -50.0 } else { 0.0 })),
+ self.font.render_text_at(ctx, st,
+ p_screen + glam::Vec2::new(-owner_width / 2.0,
+ -200.0 + if s.height_offset { -50.0 } else { 0.0 }),
&c.owner,
font::BitmapParams {
color: &[glam::Vec3::new(1.0, 1.0, 1.0)],
scale: glam::Vec2::new(scale, scale),
+ offset: glam::Vec2::ZERO,
},
);
}
@@ -429,15 +429,23 @@ impl CardRenderer {
glam::Vec2::new(0.0, 0.0),
glam::Vec2::new(WIDTH, 16.0),
);
- self.font.render_text_helper(ctx, st,
- &glam::Vec2::new(8.0, 1.0),
+ self.font.render_text_at(ctx, st,
+ glam::Vec2::new(8.0, 1.0),
&card.name,
- &[glam::Vec3::new(0.0, 0.0, 0.0)]
+ font::BitmapParams {
+ color: &[glam::Vec3::new(0.0, 0.0, 0.0)],
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ }
);
- self.font.render_text_helper(ctx, st,
- &glam::Vec2::new(WIDTH - 8.0 * card.rarity.len() as f32, 1.0),
+ self.font.render_text_at(ctx, st,
+ glam::Vec2::new(WIDTH - 8.0 * card.rarity.len() as f32, 1.0),
&card.rarity,
- &[glam::Vec3::new(0.0, 0.0, 0.0)]
+ font::BitmapParams {
+ color: &[glam::Vec3::new(0.0, 0.0, 0.0)],
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ }
);
// art
@@ -475,24 +483,36 @@ impl CardRenderer {
// boost text
let boost_pos = glam::Vec2::new(12.0, 105.0);
- self.font.render_text_helper(ctx, st,
- &boost_pos,
+ self.font.render_text_at(ctx, st,
+ boost_pos,
&card.boost_level,
- &[glam::Vec3::new(0.1, 0.1, 0.1)]
+ font::BitmapParams {
+ color: &[glam::Vec3::new(0.1, 0.1, 0.1)],
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ },
);
- self.font.render_text_helper(ctx, st,
- &(boost_pos - glam::Vec2::new(1.0, 1.0)),
+ self.font.render_text_at(ctx, st,
+ boost_pos - glam::Vec2::new(1.0, 1.0),
&card.boost_level,
- &[glam::Vec3::new(0.9, 0.9, 0.9)]
+ font::BitmapParams {
+ color: &[glam::Vec3::new(0.9, 0.9, 0.9)],
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ },
);
// equity marks
let equity_pos = glam::Vec2::new(12.0, 18.0);
for i in 0..card.equity {
- self.font.render_text_helper(ctx, st,
- &(equity_pos + glam::Vec2::new(0.0, 10.0) * i as f32),
+ self.font.render_text_at(ctx, st,
+ equity_pos + glam::Vec2::new(0.0, 10.0) * i as f32,
"$",
- &[glam::Vec3::new(0.1, 0.1, 0.1)]
+ font::BitmapParams {
+ color: &[glam::Vec3::new(0.1, 0.1, 0.1)],
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ },
);
}
@@ -504,10 +524,14 @@ impl CardRenderer {
);
for (i, cs) in card.body_text.chars().collect::<Vec<char>>().chunks(25).enumerate() {
let line: String = cs.iter().collect();
- self.font.render_text_helper(ctx, st,
- &glam::Vec2::new(5.0, 120.0 + 10.0 * i as f32),
+ self.font.render_text_at(ctx, st,
+ glam::Vec2::new(5.0, 120.0 + 10.0 * i as f32),
&format!("{}", line),
- &[glam::Vec3::new(0.2, 0.2, 0.2)]
+ font::BitmapParams {
+ color: &[glam::Vec3::new(0.2, 0.2, 0.2)],
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ },
);
}
@@ -517,15 +541,23 @@ impl CardRenderer {
glam::Vec2::new(0.0, HEIGHT - 16.0),
glam::Vec2::new(WIDTH, 16.0),
);
- self.font.render_text_helper(ctx, st,
- &glam::Vec2::new(1.0, HEIGHT - 15.0),
+ self.font.render_text_at(ctx, st,
+ glam::Vec2::new(1.0, HEIGHT - 15.0),
&format!("{}", card.set),
- &[glam::Vec3::new(1.0, 1.0, 1.0)]
+ font::BitmapParams {
+ color: &[glam::Vec3::new(1.0, 1.0, 1.0)],
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ }
);
- self.font.render_text_helper(ctx, st,
- &glam::Vec2::new(WIDTH - 7.0 * (card.minted_date.len() - 1) as f32, HEIGHT - 15.0),
+ self.font.render_text_at(ctx, st,
+ glam::Vec2::new(WIDTH - 7.0 * (card.minted_date.len() - 1) as f32, HEIGHT - 15.0),
&format!("{}", card.minted_date),
- &[glam::Vec3::new(1.0, 1.0, 1.0)]
+ font::BitmapParams {
+ color: &[glam::Vec3::new(1.0, 1.0, 1.0)],
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ }
);
st.bind_render_framebuffer(ctx);
}
diff --git a/crates/renderer/src/terminal.rs b/crates/renderer/src/terminal.rs
index cca2de6..9f7187b 100644
--- a/crates/renderer/src/terminal.rs
+++ b/crates/renderer/src/terminal.rs
@@ -194,7 +194,7 @@ impl Terminal {
}
return (CharPair { first: ' ', second: Some(' ') }, glam::Vec3::new(0.0, 0.0, 0.0));
}
- pub fn render(&self, ctx: &context::Context, st: &state::State, pos: &glam::Vec2) {
+ pub fn render(&self, ctx: &context::Context, st: &mut state::State, pos: &glam::Vec2) {
let mut s = String::new();
let mut colors = Vec::new();
for row in 0..self.height {
@@ -207,7 +207,11 @@ impl Terminal {
s += "\n";
colors.push(glam::Vec3::new(1.0, 1.0, 1.0));
}
- self.font.render_text_helper(ctx, st, pos, &s, &colors);
+ self.font.render_text_at(ctx, st, *pos, &s, font::BitmapParams {
+ color: &colors,
+ scale: glam::Vec2::ONE,
+ offset: glam::Vec2::ZERO,
+ });
}
pub fn write_tty<W>(&self, out: &mut W)
where W: Write {