organise the code
This commit is contained in:
parent
f1e112cdec
commit
238519ee90
3 changed files with 122 additions and 186 deletions
23
src/components.rs
Normal file
23
src/components.rs
Normal 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
97
src/img_processor.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
188
src/lib.rs
188
src/lib.rs
|
@ -1,6 +1,5 @@
|
||||||
use std::{num::NonZeroU64, path::PathBuf, sync::Arc, thread};
|
use std::{num::NonZeroU64, path::PathBuf, sync::Arc, thread};
|
||||||
|
|
||||||
use cb::TriangleRenderResources;
|
|
||||||
use eframe::{
|
use eframe::{
|
||||||
egui::{self, ImageSource},
|
egui::{self, ImageSource},
|
||||||
egui_wgpu,
|
egui_wgpu,
|
||||||
|
@ -12,7 +11,8 @@ use img_processor::Processor;
|
||||||
use nalgebra::{Matrix3, SMatrix};
|
use nalgebra::{Matrix3, SMatrix};
|
||||||
use oneshot::TryRecvError;
|
use oneshot::TryRecvError;
|
||||||
|
|
||||||
use crate::cb::CustomTriangleCallback;
|
mod components;
|
||||||
|
mod img_processor;
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
color_matrix: SMatrix<f32, 3, 4>,
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue