From 238519ee90992ce5ba79fae65637f0bc2f448f2b Mon Sep 17 00:00:00 2001 From: Schrottkatze Date: Wed, 22 May 2024 09:08:55 +0200 Subject: [PATCH] organise the code --- src/components.rs | 23 ++++++ src/img_processor.rs | 97 ++++++++++++++++++++++ src/lib.rs | 188 +------------------------------------------ 3 files changed, 122 insertions(+), 186 deletions(-) create mode 100644 src/components.rs create mode 100644 src/img_processor.rs diff --git a/src/components.rs b/src/components.rs new file mode 100644 index 0000000..1212ab6 --- /dev/null +++ b/src/components.rs @@ -0,0 +1,23 @@ +use eframe::egui; +use nalgebra::{Matrix, SMatrix}; + +pub fn mat_editor( + ui: &mut egui::Ui, + mat: &mut SMatrix, + 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 +} diff --git a/src/img_processor.rs b/src/img_processor.rs new file mode 100644 index 0000000..265be19 --- /dev/null +++ b/src/img_processor.rs @@ -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, + color_matrix: SMatrix, + pos_matrix: SMatrix, + ret: oneshot::Sender<(egui::TextureHandle, (f32, f32))>, + ctx: egui::Context, + handle: Option, +} + +pub struct Processor { + channel: mpsc::Sender, +} + +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, + color_matrix: SMatrix, + pos_matrix: SMatrix, + ctx: egui::Context, + handle: Option, + ) -> 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 + } +} diff --git a/src/lib.rs b/src/lib.rs index 12e6c5a..15a9842 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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, @@ -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, - color_matrix: SMatrix, - pos_matrix: SMatrix, - ret: oneshot::Sender<(egui::TextureHandle, (f32, f32))>, - ctx: egui::Context, - handle: Option, - } - - pub struct Processor { - channel: mpsc::Sender, - } - - 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, - color_matrix: SMatrix, - pos_matrix: SMatrix, - ctx: egui::Context, - handle: Option, - ) -> 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( - ui: &mut egui::Ui, - mat: &mut SMatrix, - 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 { - 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); - } - } -}