get color matrix stuff working
This commit is contained in:
parent
8842c5a364
commit
f1e112cdec
3 changed files with 336 additions and 176 deletions
152
Cargo.lock
generated
152
Cargo.lock
generated
|
@ -1192,6 +1192,7 @@ checksum = "1b78779f35ded1a853786c9ce0b43fe1053e10a21ea3b23ebea411805ce41593"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"egui",
|
"egui",
|
||||||
"enum-map",
|
"enum-map",
|
||||||
|
"image 0.24.9",
|
||||||
"log",
|
"log",
|
||||||
"mime_guess2",
|
"mime_guess2",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1566,6 +1567,19 @@ dependencies = [
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generator"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"rustversion",
|
||||||
|
"windows 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.7"
|
version = "0.14.7"
|
||||||
|
@ -2013,6 +2027,12 @@ version = "3.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lebe"
|
name = "lebe"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
@ -2111,6 +2131,20 @@ version = "0.4.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "loom"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"generator",
|
||||||
|
"pin-utils",
|
||||||
|
"scoped-tls",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "loop9"
|
name = "loop9"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -2129,6 +2163,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata 0.1.10",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mathe-img-processor"
|
name = "mathe-img-processor"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -2140,6 +2183,8 @@ dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"image 0.25.1",
|
"image 0.25.1",
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
|
"oneshot",
|
||||||
|
"rayon",
|
||||||
"threadpool",
|
"threadpool",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2370,6 +2415,16 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-ansi-term"
|
||||||
|
version = "0.46.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||||
|
dependencies = [
|
||||||
|
"overload",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
|
@ -2582,6 +2637,15 @@ version = "1.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oneshot"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f6640c6bda7731b1fdbab747981a0f896dd1fedaf9f4a53fa237a04a84431f4"
|
||||||
|
dependencies = [
|
||||||
|
"loom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "option-ext"
|
name = "option-ext"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -2607,6 +2671,12 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "overload"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owned_ttf_parser"
|
name = "owned_ttf_parser"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
|
@ -2992,8 +3062,17 @@ checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata",
|
"regex-automata 0.4.6",
|
||||||
"regex-syntax",
|
"regex-syntax 0.8.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||||
|
dependencies = [
|
||||||
|
"regex-syntax 0.6.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3004,9 +3083,15 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-syntax",
|
"regex-syntax 0.8.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.3"
|
version = "0.8.3"
|
||||||
|
@ -3061,6 +3146,12 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "safe_arch"
|
name = "safe_arch"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@ -3155,6 +3246,15 @@ dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.2"
|
version = "1.4.2"
|
||||||
|
@ -3397,6 +3497,16 @@ dependencies = [
|
||||||
"syn 2.0.64",
|
"syn 2.0.64",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "threadpool"
|
name = "threadpool"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
|
@ -3542,6 +3652,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"valuable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-log"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.3.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||||
|
dependencies = [
|
||||||
|
"matchers",
|
||||||
|
"nu-ansi-term",
|
||||||
|
"once_cell",
|
||||||
|
"regex",
|
||||||
|
"sharded-slab",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3652,6 +3792,12 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "valuable"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version-compare"
|
name = "version-compare"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
|
@ -7,10 +7,12 @@ edition = "2021"
|
||||||
bytemuck = "1.16.0"
|
bytemuck = "1.16.0"
|
||||||
eframe = {version = "0.27", features = ["wgpu"]}
|
eframe = {version = "0.27", features = ["wgpu"]}
|
||||||
egui-file-dialog = "0.5.0"
|
egui-file-dialog = "0.5.0"
|
||||||
egui_extras = "0.27.2"
|
egui_extras = { version = "0.27.2", features = ["image"] }
|
||||||
env_logger = "0.11.3"
|
env_logger = "0.11.3"
|
||||||
image = "0.25.1"
|
image = "0.25.1"
|
||||||
nalgebra = "0.32.5"
|
nalgebra = "0.32.5"
|
||||||
|
oneshot = "0.1.6"
|
||||||
|
rayon = "1.10.0"
|
||||||
threadpool = "1.8.1"
|
threadpool = "1.8.1"
|
||||||
# winit = { version = "0.30", features = ["rwh_05" ] }
|
# winit = { version = "0.30", features = ["rwh_05" ] }
|
||||||
# log = "0.4"
|
# log = "0.4"
|
||||||
|
|
356
src/lib.rs
356
src/lib.rs
|
@ -1,182 +1,49 @@
|
||||||
use std::{num::NonZeroU64, path::PathBuf};
|
use std::{num::NonZeroU64, path::PathBuf, sync::Arc, thread};
|
||||||
|
|
||||||
use cb::TriangleRenderResources;
|
use cb::TriangleRenderResources;
|
||||||
use eframe::{
|
use eframe::{
|
||||||
egui, egui_wgpu,
|
egui::{self, ImageSource},
|
||||||
|
egui_wgpu,
|
||||||
wgpu::{self, util::DeviceExt},
|
wgpu::{self, util::DeviceExt},
|
||||||
};
|
};
|
||||||
use egui_file_dialog::FileDialog;
|
use egui_file_dialog::FileDialog;
|
||||||
|
use image::Rgb32FImage;
|
||||||
|
use img_processor::Processor;
|
||||||
use nalgebra::{Matrix3, SMatrix};
|
use nalgebra::{Matrix3, SMatrix};
|
||||||
|
use oneshot::TryRecvError;
|
||||||
|
|
||||||
use crate::cb::CustomTriangleCallback;
|
use crate::cb::CustomTriangleCallback;
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
color_matrix: SMatrix<f32, 4, 4>,
|
color_matrix: SMatrix<f32, 3, 4>,
|
||||||
pos_matrix: SMatrix<f32, 3, 3>,
|
pos_matrix: SMatrix<f32, 2, 3>,
|
||||||
file_dialog: FileDialog,
|
file_dialog: FileDialog,
|
||||||
new_file: Option<PathBuf>,
|
new_file: Option<PathBuf>,
|
||||||
cur_img_size: Option<egui::Vec2>,
|
cur_img: Option<Arc<Rgb32FImage>>,
|
||||||
image_loaded: bool,
|
proc: Processor,
|
||||||
|
cur_rx: Option<oneshot::Receiver<(egui::TextureHandle, (f32, f32))>>,
|
||||||
|
cur_res: Option<egui::TextureHandle>,
|
||||||
|
cur_size: Option<(f32, f32)>,
|
||||||
}
|
}
|
||||||
impl App {
|
impl App {
|
||||||
pub fn new<'a>(cc: &'a eframe::CreationContext<'a>) -> Option<Self> {
|
pub fn new<'a>(cc: &'a eframe::CreationContext<'a>) -> Option<Self> {
|
||||||
// Get the WGPU render state from the eframe creation context. This can also be retrieved
|
|
||||||
// from `eframe::Frame` when you don't have a `CreationContext` available.
|
|
||||||
let wgpu_render_state = cc.wgpu_render_state.as_ref()?;
|
|
||||||
|
|
||||||
let device = &wgpu_render_state.device;
|
|
||||||
|
|
||||||
// let cat = include_bytes!("./cat.jpg");
|
|
||||||
// let cat_img = image::load_from_memory(cat).unwrap();
|
|
||||||
// let cat_rgba = cat_img.to_rgba();
|
|
||||||
|
|
||||||
// use image::GenericImageView;
|
|
||||||
// let dimensions = cat_img.dimensions();
|
|
||||||
|
|
||||||
// let tex_size = wgpu::Extent3d {
|
|
||||||
// width: dimensions.0,
|
|
||||||
// height: dimensions.1,
|
|
||||||
// depth_or_array_layers: 1,
|
|
||||||
// };
|
|
||||||
// let cat_tex = device.create_texture(&wgpu::TextureDescriptor {
|
|
||||||
// size: tex_size,
|
|
||||||
// mip_level_count: 1,
|
|
||||||
// sample_count: 1,
|
|
||||||
// dimension: wgpu::TextureDimension::D2,
|
|
||||||
// format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
|
||||||
// usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
|
||||||
// label: Some("cat"),
|
|
||||||
// view_formats: &[],
|
|
||||||
// });
|
|
||||||
|
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
|
||||||
label: Some("shader"),
|
|
||||||
source: wgpu::ShaderSource::Wgsl(include_str!("./shader.wgsl").into()),
|
|
||||||
});
|
|
||||||
|
|
||||||
let tex_bind_group_layout =
|
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
|
||||||
label: Some("tex_bind_group_layout"),
|
|
||||||
entries: &[
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 0,
|
|
||||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
|
||||||
ty: wgpu::BindingType::Texture {
|
|
||||||
multisampled: false,
|
|
||||||
view_dimension: wgpu::TextureViewDimension::D2,
|
|
||||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 1,
|
|
||||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
|
||||||
// This should match the filterable field of the
|
|
||||||
// corresponding Texture entry above.
|
|
||||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let matrices_bind_group_layout =
|
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
|
||||||
label: Some("matrices_bind_group_layout"),
|
|
||||||
entries: &[
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 0,
|
|
||||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
|
||||||
ty: wgpu::BindingType::Buffer {
|
|
||||||
ty: wgpu::BufferBindingType::Uniform,
|
|
||||||
has_dynamic_offset: false,
|
|
||||||
min_binding_size: Some(NonZeroU64::new(64)?),
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 1,
|
|
||||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
|
||||||
ty: wgpu::BindingType::Buffer {
|
|
||||||
ty: wgpu::BufferBindingType::Uniform,
|
|
||||||
has_dynamic_offset: false,
|
|
||||||
min_binding_size: Some(NonZeroU64::new(36)?),
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
|
||||||
label: Some("pipeline_layout"),
|
|
||||||
bind_group_layouts: &[&tex_bind_group_layout, &matrices_bind_group_layout],
|
|
||||||
push_constant_ranges: &[],
|
|
||||||
});
|
|
||||||
|
|
||||||
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
|
||||||
label: Some("custom3d"),
|
|
||||||
layout: Some(&pipeline_layout),
|
|
||||||
vertex: wgpu::VertexState {
|
|
||||||
module: &shader,
|
|
||||||
entry_point: "vs_main",
|
|
||||||
buffers: &[],
|
|
||||||
// compilation_options: wgpu::PipelineCompilationOptions::default(),
|
|
||||||
},
|
|
||||||
fragment: Some(wgpu::FragmentState {
|
|
||||||
module: &shader,
|
|
||||||
entry_point: "fs_main",
|
|
||||||
targets: &[Some(wgpu_render_state.target_format.into())],
|
|
||||||
// compilation_options: wgpu::PipelineCompilationOptions::default(),
|
|
||||||
}),
|
|
||||||
primitive: wgpu::PrimitiveState::default(),
|
|
||||||
depth_stencil: None,
|
|
||||||
multisample: wgpu::MultisampleState::default(),
|
|
||||||
multiview: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
// let color_matrix_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
|
||||||
// label: Some("color_matrix_buffer"),
|
|
||||||
// contents: bytemuck::cast_slice(&[0.0_f32; 4]), // 16 bytes aligned!
|
|
||||||
// // Mapping at creation (as done by the create_buffer_init utility) doesn't require us to to add the MAP_WRITE usage
|
|
||||||
// // (this *happens* to workaround this bug )
|
|
||||||
// usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::UNIFORM,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
|
||||||
// label: Some("custom3d"),
|
|
||||||
// layout: &bind_group_layout,
|
|
||||||
// entries: &[wgpu::BindGroupEntry {
|
|
||||||
// binding: 0,
|
|
||||||
// resource: uniform_buffer.as_entire_binding(),
|
|
||||||
// }],
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Because the graphics pipeline must have the same lifetime as the egui render pass,
|
|
||||||
// instead of storing the pipeline in our `Custom3D` struct, we insert it into the
|
|
||||||
// `paint_callback_resources` type map, which is stored alongside the render pass.
|
|
||||||
|
|
||||||
// wgpu_render_state
|
|
||||||
// .renderer
|
|
||||||
// .write()
|
|
||||||
// .callback_resources
|
|
||||||
// .insert(TriangleRenderResources {
|
|
||||||
// pipeline,
|
|
||||||
// bind_group,
|
|
||||||
// uniform_buffer,
|
|
||||||
// });
|
|
||||||
|
|
||||||
Some(Self {
|
Some(Self {
|
||||||
color_matrix: SMatrix::identity(),
|
color_matrix: SMatrix::identity(),
|
||||||
pos_matrix: SMatrix::identity(),
|
pos_matrix: SMatrix::identity(),
|
||||||
file_dialog: FileDialog::new(),
|
file_dialog: FileDialog::new(),
|
||||||
new_file: None,
|
new_file: None,
|
||||||
image_loaded: false,
|
cur_img: None,
|
||||||
cur_img_size: None,
|
proc: Processor::init(),
|
||||||
|
cur_rx: None,
|
||||||
|
cur_res: None,
|
||||||
|
cur_size: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl eframe::App for App {
|
impl eframe::App for App {
|
||||||
fn update(&mut self, ctx: &eframe::egui::Context, frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &eframe::egui::Context, frame: &mut eframe::Frame) {
|
||||||
let mut img = None;
|
let mut mats_changed = false;
|
||||||
egui::SidePanel::right("sidebar").show(ctx, |ui| {
|
egui::SidePanel::right("sidebar").show(ctx, |ui| {
|
||||||
if ui.button("Select Image").clicked() {
|
if ui.button("Select Image").clicked() {
|
||||||
self.file_dialog.select_file()
|
self.file_dialog.select_file()
|
||||||
|
@ -184,43 +51,188 @@ impl eframe::App for App {
|
||||||
if self.file_dialog.update(ctx).selected().is_some() {
|
if self.file_dialog.update(ctx).selected().is_some() {
|
||||||
if let Some(path) = self.file_dialog.take_selected() {
|
if let Some(path) = self.file_dialog.take_selected() {
|
||||||
println!("path: {path:?}");
|
println!("path: {path:?}");
|
||||||
if path.ends_with(".jpg") || path.ends_with(".jpeg") || path.ends_with(".png") {
|
let Some(ext) = path.extension() else {
|
||||||
img = Some(image::open(path).unwrap().to_rgba8());
|
panic!("path should have an extension")
|
||||||
|
};
|
||||||
|
if ext == "jpg" || ext == "jpeg" || ext == "png" {
|
||||||
|
println!("img!");
|
||||||
|
self.cur_img = Some(Arc::new(image::open(path).unwrap().into_rgb32f()));
|
||||||
|
|
||||||
|
self.cur_rx = Some(self.proc.exec(
|
||||||
|
self.cur_img.clone().unwrap(),
|
||||||
|
self.color_matrix,
|
||||||
|
self.pos_matrix,
|
||||||
|
ctx.clone(),
|
||||||
|
self.cur_res.clone(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.add_space(8.);
|
ui.add_space(8.);
|
||||||
|
let old_color_mat = self.color_matrix;
|
||||||
|
let old_pos_mat = self.pos_matrix;
|
||||||
ui.label("Color Matrix Editor");
|
ui.label("Color Matrix Editor");
|
||||||
components::mat_editor(ui, &mut self.color_matrix, "color_matrix");
|
let color_mat_edited =
|
||||||
|
components::mat_editor(ui, &mut self.color_matrix, "color_matrix").dragged();
|
||||||
ui.add_space(8.);
|
ui.add_space(8.);
|
||||||
ui.label("Position Matrix Editor");
|
ui.label("Position Matrix Editor");
|
||||||
components::mat_editor(ui, &mut self.pos_matrix, "pos_matrix");
|
let pos_mat_edited =
|
||||||
|
components::mat_editor(ui, &mut self.pos_matrix, "pos_matrix").dragged();
|
||||||
|
mats_changed |= old_color_mat == self.color_matrix || old_pos_mat == self.pos_matrix;
|
||||||
|
|
||||||
|
if mats_changed
|
||||||
|
&& self.cur_img.is_some()
|
||||||
|
&& self.cur_res.is_some()
|
||||||
|
&& !color_mat_edited
|
||||||
|
&& !pos_mat_edited
|
||||||
|
&& self.cur_rx.is_none()
|
||||||
|
{
|
||||||
|
self.cur_rx = Some(self.proc.exec(
|
||||||
|
self.cur_img.clone().unwrap(),
|
||||||
|
self.color_matrix,
|
||||||
|
self.pos_matrix,
|
||||||
|
ctx.clone(),
|
||||||
|
self.cur_res.clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
ui.heading("My egui Application");
|
ui.heading("My egui Application");
|
||||||
|
|
||||||
if let Some(dimensions) = self.cur_img_size {
|
if let Some(r) = &self.cur_rx {
|
||||||
egui::Frame::canvas(ui.style()).show(ui, |ui| {
|
match r.try_recv() {
|
||||||
let (rect, response) = ui.allocate_exact_size(dimensions, egui::Sense::drag());
|
Ok((handle, size)) => {
|
||||||
|
println!("mew");
|
||||||
// let callback = egui_wgpu::Callback::new_paint_callback(
|
self.cur_res = Some(handle);
|
||||||
// rect,
|
self.cur_size = Some(size);
|
||||||
// CustomTriangleCallback { angle: 0.5 },
|
self.cur_rx = None;
|
||||||
// );
|
}
|
||||||
// ui.painter().add(callback);
|
Err(TryRecvError::Empty) => {}
|
||||||
});
|
Err(TryRecvError::Disconnected) => panic!("oneshot channel disconnected"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(r) = &self.cur_res {
|
||||||
|
let sized_img =
|
||||||
|
egui::load::SizedTexture::new(r.id(), egui::Vec2::from(self.cur_size.unwrap()));
|
||||||
|
let img = egui::Image::from_texture(sized_img);
|
||||||
|
ui.add(img);
|
||||||
|
}
|
||||||
|
// if let Some(dimensions) = self.cur_img_size {
|
||||||
|
// egui::Frame::canvas(ui.style()).show(ui, |ui| {
|
||||||
|
// let (rect, response) = ui.allocate_exact_size(dimensions, egui::Sense::drag());
|
||||||
|
|
||||||
|
// let callback = egui_wgpu::Callback::new_paint_callback(
|
||||||
|
// rect,
|
||||||
|
// CustomTriangleCallback { angle: 0.5 },
|
||||||
|
// );
|
||||||
|
// ui.painter().add(callback);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod gpu_proc {
|
mod img_processor {
|
||||||
use eframe::wgpu;
|
use std::{
|
||||||
|
sync::{mpsc, Arc},
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct GpuResources {
|
use eframe::egui::{self, TextureOptions};
|
||||||
pipeline: wgpu::RenderPipeline,
|
use image::{DynamicImage, Pixel, Rgb, Rgb32FImage};
|
||||||
// img_buffer: Option<wgpu::
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +252,7 @@ mod components {
|
||||||
ui.add(
|
ui.add(
|
||||||
egui::DragValue::new(item)
|
egui::DragValue::new(item)
|
||||||
.speed(0.01)
|
.speed(0.01)
|
||||||
.clamp_range(-1.0..=1.0),
|
.clamp_range(-10.0..=10.0),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
Loading…
Reference in a new issue