From 6dfebcdc87bc5e57a0165e6ce096a72247770dd5 Mon Sep 17 00:00:00 2001
From: griffi-gh <prasol258@gmail.com>
Date: Mon, 31 Mar 2025 18:24:25 +0200
Subject: [PATCH] wip euc

---
 hui-euc/Cargo.toml                    |  3 ++
 hui-euc/src/lib.rs                    | 42 ++++++++---------
 hui-euc/src/pipeline.rs               | 67 +++++++++++++++++++++++++++
 hui-examples/Cargo.toml               |  1 +
 hui-examples/examples/test_hui_euc.rs | 17 +++++++
 5 files changed, 107 insertions(+), 23 deletions(-)
 create mode 100644 hui-euc/src/pipeline.rs
 create mode 100644 hui-examples/examples/test_hui_euc.rs

diff --git a/hui-euc/Cargo.toml b/hui-euc/Cargo.toml
index 6a1496e..bc1e03f 100644
--- a/hui-euc/Cargo.toml
+++ b/hui-euc/Cargo.toml
@@ -5,7 +5,10 @@ edition = "2024"
 publish = false
 
 [dependencies]
+hui-painter = { version = "=0.1.0-alpha.7", path = "../hui-painter", default-features = false }
 euc = { version = "0.5", default-features = false }
+glam = "0.30"
+# vek = "0.17"
 
 [features]
 default = [ "std" ]
diff --git a/hui-euc/src/lib.rs b/hui-euc/src/lib.rs
index e354c3b..fd72de1 100644
--- a/hui-euc/src/lib.rs
+++ b/hui-euc/src/lib.rs
@@ -1,34 +1,30 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 
-// TODO
+use hui_painter::backend::BackendData;
 
-use euc::Pipeline;
+mod pipeline;
+use pipeline::UiPipeline;
 
-struct UiPipeline;
+pub struct EucUiRenderer {
+  pipeline: UiPipeline,
+  // output: Buffer2d<<UiPipeline as Pipeline>::Pixel>,
+}
 
-impl Pipeline for UiPipeline {
-  type Vertex = [f32; 2];
-  type VsOut = ();
-  type Pixel = [u8; 4];
-
-  // Vertex shader
-  fn vert(&self, pos: &Self::Vertex) -> ([f32; 4], Self::VsOut) {
-    ([pos[0], pos[1], 0.0, 1.0], ())
+impl EucUiRenderer {
+  pub fn new() -> Self {
+    Self {
+      pipeline: UiPipeline::default(),
+    }
   }
 
-  // Fragment shader
-  fn frag(&self, _: &Self::VsOut) -> Self::Pixel {
-    [0, 0, 0, 255]
+  pub fn update(&mut self, data: &BackendData) {
+
   }
 }
 
-// fn main() {
-//   let mut color = Buffer2d::new([640, 480], [0; 4]);
-//   let mut depth = Buffer2d::new([640, 480], 1.0);
+impl Default for EucUiRenderer {
+  fn default() -> Self {
+    Self::new()
+  }
+}
 
-//   Example.draw::<Triangles<_>, _>(
-//     &[[-1.0, -1.0], [1.0, -1.0], [0.0, 1.0]],
-//     &mut color,
-//     &mut depth,
-//   );
-// }
diff --git a/hui-euc/src/pipeline.rs b/hui-euc/src/pipeline.rs
new file mode 100644
index 0000000..065bbfe
--- /dev/null
+++ b/hui-euc/src/pipeline.rs
@@ -0,0 +1,67 @@
+
+use euc::{buffer::Buffer2d, Interpolate, Pipeline, Target};
+use glam::{Vec2, Vec4};
+use hui_painter::paint::buffer::Vertex;
+
+pub struct UiPipeline {
+  atlas: Buffer2d<[u8; 4]>,
+}
+
+#[derive(Clone, Copy)]
+pub struct VsOut {
+  position: Vec2,
+  color: Vec4,
+  uv: Vec2,
+}
+
+impl Interpolate for VsOut {
+  fn lerp2(a: Self, b: Self, x: f32, y: f32) -> Self {
+    Self {
+      position: a.position.mul_add(Vec2::splat(x), y * b.position),
+      color: a.color.mul_add(Vec4::splat(x), y * b.color),
+      uv: a.uv.mul_add(Vec2::splat(x), y * b.uv),
+    }
+  }
+
+  fn lerp3(a: Self, b: Self, c: Self, x: f32, y: f32, z: f32) -> Self {
+    Self {
+      position: a.position.mul_add(Vec2::splat(x), b.position.mul_add(Vec2::splat(y), z * c.position)),
+      color: a.color.mul_add(Vec4::splat(x), b.color.mul_add(Vec4::splat(y), z * c.color)),
+      uv: a.uv.mul_add(Vec2::splat(x), b.uv.mul_add(Vec2::splat(y), z * c.uv)),
+    }
+  }
+}
+
+impl Default for UiPipeline {
+  fn default() -> Self {
+    Self {
+      atlas: Buffer2d::new([0, 0], [0; 4]),
+    }
+  }
+}
+
+impl Pipeline for UiPipeline {
+  type Vertex = Vertex;
+  type VsOut = VsOut;
+  type Pixel = [u8; 4];
+
+  // Vertex shader
+  fn vert(&self, vtx: &Self::Vertex) -> ([f32; 4], Self::VsOut) {
+    ([vtx.position.x, vtx.position.y, 0.0, 0.0], VsOut {
+      position: vtx.position,
+      color: vtx.color,
+      uv: vtx.uv,
+    })
+  }
+
+  // Fragment shader
+  fn frag(&self, vs: &Self::VsOut) -> Self::Pixel {
+    let color = vs.color.to_array().map(|x| (x * 255.).round() as u8);
+    color //TODO sampling
+    // match vs.uv != Vec2::ZERO {
+    //   true => color * self.atlas.get(),
+    //   false => color,
+    // }
+  }
+}
+
diff --git a/hui-examples/Cargo.toml b/hui-examples/Cargo.toml
index 9d58196..9c3dbfc 100644
--- a/hui-examples/Cargo.toml
+++ b/hui-examples/Cargo.toml
@@ -14,6 +14,7 @@ hui-winit = { path = "../hui-winit" }
 kubi-logging = { git = "https://github.com/griffi-gh/kubi", rev = "1e051c47b64c967305e4bbbd464ef5da2cc56bbb" }
 glium = "0.36"
 winit = "0.30"
+minifb = "0.28"
 glam = "0.30"
 log = "0.4"
 image = { version = "0.25", features = ["jpeg", "png"] }
diff --git a/hui-examples/examples/test_hui_euc.rs b/hui-examples/examples/test_hui_euc.rs
new file mode 100644
index 0000000..63ba745
--- /dev/null
+++ b/hui-examples/examples/test_hui_euc.rs
@@ -0,0 +1,17 @@
+use minifb::{Window, WindowOptions};
+
+pub fn main() {
+  let mut window = Window::new(
+    "hUI minfb (hui-euc)",
+    800, 600,
+    WindowOptions::default()
+  ).unwrap();
+
+  window.set_target_fps(60);
+
+  // while window.is_open() {
+  //   window
+  //     .update_with_buffer(&buffer, WIDTH, HEIGHT)
+  //     .unwrap();
+  // }
+}
\ No newline at end of file