organise the code

This commit is contained in:
Schrottkatze 2024-05-22 09:08:55 +02:00
parent f1e112cdec
commit 238519ee90
Signed by: schrottkatze
SSH key fingerprint: SHA256:hXb3t1vINBFCiDCmhRABHX5ocdbLiKyCdKI4HK2Rbbc
3 changed files with 122 additions and 186 deletions

23
src/components.rs Normal file
View file

@ -0,0 +1,23 @@
use eframe::egui;
use nalgebra::{Matrix, SMatrix};
pub fn mat_editor<const R: usize, const C: usize>(
ui: &mut egui::Ui,
mat: &mut SMatrix<f32, R, C>,
id: &str,
) -> egui::Response {
egui::Grid::new(id)
.show(ui, |ui| {
mat.row_iter_mut().enumerate().for_each(|(i, mut row)| {
row.iter_mut().for_each(|item| {
ui.add(
egui::DragValue::new(item)
.speed(0.01)
.clamp_range(-10.0..=10.0),
);
});
ui.end_row();
})
})
.response
}

97
src/img_processor.rs Normal file
View file

@ -0,0 +1,97 @@
use std::{
sync::{mpsc, Arc},
thread,
};
use eframe::egui::{self, TextureOptions};
use image::{DynamicImage, Pixel, Rgb, Rgb32FImage};
use nalgebra::{SMatrix, Vector4};
use rayon::prelude::*;
use image::EncodableLayout;
struct ProcessorInstruction {
img: Arc<Rgb32FImage>,
color_matrix: SMatrix<f32, 3, 4>,
pos_matrix: SMatrix<f32, 2, 3>,
ret: oneshot::Sender<(egui::TextureHandle, (f32, f32))>,
ctx: egui::Context,
handle: Option<egui::TextureHandle>,
}
pub struct Processor {
channel: mpsc::Sender<ProcessorInstruction>,
}
impl Processor {
pub fn init() -> Self {
let (tx, rx) = mpsc::channel();
thread::spawn(|| {
for ProcessorInstruction {
img,
color_matrix,
pos_matrix,
ret,
ctx,
handle,
} in rx
{
let (width, height) = img.dimensions();
let mut r = (*img).clone();
if !color_matrix.is_identity(f32::EPSILON) {
r.par_pixels_mut().for_each(|px| {
*px = Rgb::from(
TryInto::<[f32; 3]>::try_into(
(color_matrix * Vector4::new(px.0[0], px.0[1], px.0[2], 1.))
.as_slice(),
)
.unwrap(),
)
});
}
let color_image = {
let image = DynamicImage::from(r).to_rgb8();
egui::ColorImage::from_rgb(
[image.width() as usize, image.height() as usize],
image.as_bytes(),
)
};
let handle = if let Some(mut handle) = handle {
handle.set(color_image, TextureOptions::default());
handle
} else {
ctx.load_texture("res_tex", color_image, TextureOptions::default())
};
ret.send((handle, (width as f32, height as f32))).unwrap();
// (color_matrix.is_identity(f32::EPSILON), pos_matrix.is_identity(f32::EPSILON))
}
});
Self { channel: tx }
}
pub fn exec(
&self,
img: Arc<Rgb32FImage>,
color_matrix: SMatrix<f32, 3, 4>,
pos_matrix: SMatrix<f32, 2, 3>,
ctx: egui::Context,
handle: Option<egui::TextureHandle>,
) -> oneshot::Receiver<(egui::TextureHandle, (f32, f32))> {
let (tx, rx) = oneshot::channel();
let r = self.channel.send(ProcessorInstruction {
img,
color_matrix,
pos_matrix,
ret: tx,
ctx,
handle,
});
dbg!(r).unwrap();
rx
}
}

View file

@ -1,6 +1,5 @@
use std::{num::NonZeroU64, path::PathBuf, sync::Arc, thread};
use cb::TriangleRenderResources;
use eframe::{
egui::{self, ImageSource},
egui_wgpu,
@ -12,7 +11,8 @@ use img_processor::Processor;
use nalgebra::{Matrix3, SMatrix};
use oneshot::TryRecvError;
use crate::cb::CustomTriangleCallback;
mod components;
mod img_processor;
pub struct App {
color_matrix: SMatrix<f32, 3, 4>,
@ -133,187 +133,3 @@ impl eframe::App for App {
});
}
}
mod img_processor {
use std::{
sync::{mpsc, Arc},
thread,
};
use eframe::egui::{self, TextureOptions};
use image::{DynamicImage, Pixel, Rgb, Rgb32FImage};
use nalgebra::{SMatrix, Vector4};
use rayon::prelude::*;
use image::EncodableLayout;
struct ProcessorInstruction {
img: Arc<Rgb32FImage>,
color_matrix: SMatrix<f32, 3, 4>,
pos_matrix: SMatrix<f32, 2, 3>,
ret: oneshot::Sender<(egui::TextureHandle, (f32, f32))>,
ctx: egui::Context,
handle: Option<egui::TextureHandle>,
}
pub struct Processor {
channel: mpsc::Sender<ProcessorInstruction>,
}
impl Processor {
pub fn init() -> Self {
let (tx, rx) = mpsc::channel();
thread::spawn(|| {
for ProcessorInstruction {
img,
color_matrix,
pos_matrix,
ret,
ctx,
handle,
} in rx
{
let (width, height) = img.dimensions();
println!("a");
let mut r = (*img).clone();
if !color_matrix.is_identity(f32::EPSILON) {
r.par_pixels_mut().for_each(|px| {
*px = Rgb::from(
TryInto::<[f32; 3]>::try_into(
(color_matrix * Vector4::new(px.0[0], px.0[1], px.0[2], 1.))
.as_slice(),
)
.unwrap(),
)
});
}
println!("b");
let color_image = {
let image = DynamicImage::from(r).to_rgb8();
egui::ColorImage::from_rgb(
[image.width() as usize, image.height() as usize],
image.as_bytes(),
)
};
let handle = if let Some(mut handle) = handle {
handle.set(color_image, TextureOptions::default());
handle
} else {
ctx.load_texture("res_tex", color_image, TextureOptions::default())
};
println!("c");
ret.send((handle, (width as f32, height as f32))).unwrap();
// (color_matrix.is_identity(f32::EPSILON), pos_matrix.is_identity(f32::EPSILON))
}
});
Self { channel: tx }
}
pub fn exec(
&self,
img: Arc<Rgb32FImage>,
color_matrix: SMatrix<f32, 3, 4>,
pos_matrix: SMatrix<f32, 2, 3>,
ctx: egui::Context,
handle: Option<egui::TextureHandle>,
) -> oneshot::Receiver<(egui::TextureHandle, (f32, f32))> {
let (tx, rx) = oneshot::channel();
let r = self.channel.send(ProcessorInstruction {
img,
color_matrix,
pos_matrix,
ret: tx,
ctx,
handle,
});
dbg!(r).unwrap();
rx
}
}
}
mod components {
use eframe::egui;
use nalgebra::{Matrix, SMatrix};
pub fn mat_editor<const R: usize, const C: usize>(
ui: &mut egui::Ui,
mat: &mut SMatrix<f32, R, C>,
id: &str,
) -> egui::Response {
egui::Grid::new(id)
.show(ui, |ui| {
mat.row_iter_mut().enumerate().for_each(|(i, mut row)| {
row.iter_mut().for_each(|item| {
ui.add(
egui::DragValue::new(item)
.speed(0.01)
.clamp_range(-10.0..=10.0),
);
});
ui.end_row();
})
})
.response
}
}
mod cb {
use eframe::{egui, egui_wgpu, wgpu};
pub struct CustomTriangleCallback {
pub angle: f32,
}
impl egui_wgpu::CallbackTrait for CustomTriangleCallback {
fn prepare(
&self,
device: &wgpu::Device,
queue: &wgpu::Queue,
_screen_descriptor: &egui_wgpu::ScreenDescriptor,
_egui_encoder: &mut wgpu::CommandEncoder,
resources: &mut egui_wgpu::CallbackResources,
) -> Vec<wgpu::CommandBuffer> {
let resources: &TriangleRenderResources = resources.get().unwrap();
resources.prepare(device, queue, self.angle);
Vec::new()
}
fn paint<'a>(
&self,
_info: egui::PaintCallbackInfo,
render_pass: &mut wgpu::RenderPass<'a>,
resources: &'a egui_wgpu::CallbackResources,
) {
let resources: &TriangleRenderResources = resources.get().unwrap();
resources.paint(render_pass);
}
}
pub struct TriangleRenderResources {
pub pipeline: wgpu::RenderPipeline,
pub bind_group: wgpu::BindGroup,
pub uniform_buffer: wgpu::Buffer,
}
impl TriangleRenderResources {
fn prepare(&self, _device: &wgpu::Device, queue: &wgpu::Queue, angle: f32) {
// Update our uniform buffer with the angle from the UI
queue.write_buffer(
&self.uniform_buffer,
0,
bytemuck::cast_slice(&[angle, 0.0, 0.0, 0.0]),
);
}
fn paint<'rp>(&'rp self, render_pass: &mut wgpu::RenderPass<'rp>) {
// Draw our triangle!
render_pass.set_pipeline(&self.pipeline);
render_pass.set_bind_group(0, &self.bind_group, &[]);
render_pass.draw(0..3, 0..1);
}
}
}