Compare commits
	
		
			2 Commits
		
	
	
		
			ceb772bbec
			...
			2dfdea361e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2dfdea361e | |||
| 38f383a0b2 | 
							
								
								
									
										1
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -1299,6 +1299,7 @@ dependencies = [ | ||||
|  "egui", | ||||
|  "egui-wgpu", | ||||
|  "env_logger", | ||||
|  "epaint", | ||||
|  "flare-shader", | ||||
|  "futures", | ||||
|  "futures-executor", | ||||
|  | ||||
| @ -158,15 +158,24 @@ impl ThreadState { | ||||
| #[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] | ||||
| #[repr(C)] | ||||
| pub struct Coefs { | ||||
|     a: f32, | ||||
|     b: f32, | ||||
|     c: f32, | ||||
|     d: f32, | ||||
|     e: f32, | ||||
|     f: f32, | ||||
|     pub a: f32, | ||||
|     pub b: f32, | ||||
|     pub c: f32, | ||||
|     pub d: f32, | ||||
|     pub e: f32, | ||||
|     pub f: f32, | ||||
| } | ||||
|  | ||||
| impl Coefs { | ||||
|     pub const IDENTITY: Coefs = Coefs { | ||||
|         a: 1.0, | ||||
|         b: 0.0, | ||||
|         c: 0.0, | ||||
|         d: 0.0, | ||||
|         e: 1.0, | ||||
|         f: 0.0 | ||||
|     }; | ||||
|  | ||||
|     pub fn new(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32) -> Self { | ||||
|         Self { a, b, c, d, e, f } | ||||
|     } | ||||
|  | ||||
| @ -12,6 +12,7 @@ eframe = { version = "0.31", features = ["wgpu"]} | ||||
| egui = "0.31" | ||||
| egui-wgpu = "0.31" | ||||
| env_logger.workspace = true | ||||
| epaint = "0.31" | ||||
| flare-shader = { path = "../flare-shader" } | ||||
| futures = "0.3" | ||||
| futures-executor.workspace = true | ||||
|  | ||||
							
								
								
									
										58
									
								
								crates/flare/examples/transform_editor.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								crates/flare/examples/transform_editor.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| use flare::transform_editor::TransformEditor; | ||||
| use flare_shader::Coefs; | ||||
|  | ||||
| struct TransformEditorApp { | ||||
|     transform_editor: TransformEditor, | ||||
| } | ||||
|  | ||||
| impl TransformEditorApp { | ||||
|     fn new() -> Self { | ||||
|         Self { | ||||
|             transform_editor: TransformEditor::new() | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl eframe::App for TransformEditorApp { | ||||
|     fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { | ||||
|         egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { | ||||
|             egui::menu::bar(ui, |ui| { | ||||
|                 ui.menu_button("File", |ui| { | ||||
|                     if ui.button("Quit").clicked() { | ||||
|                         ctx.send_viewport_cmd(egui::ViewportCommand::Close); | ||||
|                     } | ||||
|                 }); | ||||
|                 if ui.button("Add Transform").clicked() { | ||||
|                     self.transform_editor.add_transform(Coefs::IDENTITY) | ||||
|                 } | ||||
|             }) | ||||
|         }); | ||||
|  | ||||
|         egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| { | ||||
|             ui.label(format!("Transforms: {}", self.transform_editor.len())) | ||||
|         }); | ||||
|  | ||||
|         egui::CentralPanel::default().show(ctx, |ui| { | ||||
|             self.transform_editor.ui(ui) | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn main() -> eframe::Result { | ||||
|     env_logger::init(); | ||||
|  | ||||
|     let initial_dimensions = egui::vec2(800., 600.); | ||||
|     let native_options = eframe::NativeOptions { | ||||
|         viewport: egui::ViewportBuilder::default().with_inner_size(initial_dimensions), | ||||
|         renderer: eframe::Renderer::Wgpu, | ||||
|         ..Default::default() | ||||
|     }; | ||||
|  | ||||
|     eframe::run_native( | ||||
|         "transform_editor", | ||||
|         native_options, | ||||
|         Box::new(|cc| { | ||||
|             Ok(Box::new(TransformEditorApp::new())) | ||||
|         }), | ||||
|     ) | ||||
| } | ||||
							
								
								
									
										1
									
								
								crates/flare/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								crates/flare/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| pub mod transform_editor; | ||||
| @ -15,6 +15,8 @@ use std::fs::File; | ||||
| use wgpu::util::DeviceExt; | ||||
| use wgpu::{CommandBuffer, CommandEncoder, Device, Queue, RenderPass}; | ||||
|  | ||||
| pub mod transform_editor; | ||||
|  | ||||
| struct RenderGroup { | ||||
|     device: wgpu::Device, | ||||
|     queue: wgpu::Queue, | ||||
|  | ||||
							
								
								
									
										71
									
								
								crates/flare/src/transform_editor.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								crates/flare/src/transform_editor.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| use egui::{emath, Rect, Sense}; | ||||
| use epaint::{Color32, Shape, Stroke}; | ||||
| use flare_shader::Coefs; | ||||
|  | ||||
| pub struct TransformEditor { | ||||
|     transforms: Vec<Coefs> | ||||
| } | ||||
|  | ||||
| fn coef_to_shapes(coef: &Coefs, to_screen: emath::RectTransform) -> Vec<Shape> { | ||||
|     let origin = to_screen.transform_pos(egui::pos2(coef.c, -coef.f)); | ||||
|     let x = to_screen.transform_pos(egui::pos2(coef.c + coef.a, -(coef.f + coef.b))); | ||||
|     let y = to_screen.transform_pos(egui::pos2(coef.c + coef.d, -(coef.f + coef.e))); | ||||
|  | ||||
|     let stroke = Stroke::new(2.0, Color32::BLUE); | ||||
|     let translucent = Color32::from_rgba_unmultiplied(0, 0, 255, 8); | ||||
|  | ||||
|     let shapes = vec![ | ||||
|         Shape::circle_stroke(origin, 5.0, stroke), | ||||
|         Shape::circle_stroke(x, 5.0, stroke), | ||||
|         Shape::circle_stroke(y, 5.0, stroke), | ||||
|         Shape::convex_polygon(vec![origin, x, y], translucent, stroke), | ||||
|     ]; | ||||
|  | ||||
|     shapes | ||||
| } | ||||
|  | ||||
| impl TransformEditor { | ||||
|     pub fn new() -> Self { | ||||
|         let mut editor = Self { transforms: vec![] }; | ||||
|         editor.add_transform(Coefs::IDENTITY); | ||||
|  | ||||
|         editor | ||||
|     } | ||||
|  | ||||
|     pub fn add_transform(&mut self, coefs: Coefs) { | ||||
|         self.transforms.push(coefs); | ||||
|     } | ||||
|  | ||||
|     pub fn len(&self) -> usize { | ||||
|         self.transforms.len() | ||||
|     } | ||||
|  | ||||
|     pub fn ui(&mut self, ui: &mut egui::Ui) -> egui::Response { | ||||
|         let (response, painter) = ui.allocate_painter(ui.available_size(), Sense::hover()); | ||||
|  | ||||
|         let interact_rect = response.interact_rect; | ||||
|  | ||||
|         // Aspect-ratio scaling; minimum dimension will be [-2.0, 2.0] | ||||
|         let interact_max_dim = interact_rect.width().max(interact_rect.height()); | ||||
|         let interact_min_dim = interact_rect.width().min(interact_rect.height()); | ||||
|         let interact_max_is_width = interact_max_dim == interact_rect.width(); | ||||
|         let ifs_scale = interact_max_dim / interact_min_dim * 4.0; | ||||
|  | ||||
|         let ifs_min = if interact_max_is_width { | ||||
|             egui::pos2(-ifs_scale / 2.0, -2.0) | ||||
|         } else { | ||||
|             egui::pos2(-2.0, -ifs_scale / 2.0) | ||||
|         }; | ||||
|  | ||||
|         let transform_area = Rect::from_min_max(ifs_min, ifs_min * -1.0); | ||||
|         let to_screen = emath::RectTransform::from_to(transform_area, response.interact_rect); | ||||
|  | ||||
|         self.transforms.iter().map(|coef| { | ||||
|             coef_to_shapes(coef, to_screen) | ||||
|         }).flat_map(|x| x).for_each(|shape| { | ||||
|             let _ = painter.add(shape); | ||||
|         }); | ||||
|  | ||||
|         response | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user