Skip to content

Commit

Permalink
Refactor out gui module
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Oom committed Jun 30, 2024
1 parent f1adb47 commit dd11b61
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 114 deletions.
109 changes: 109 additions & 0 deletions pathtracer-gui/src/gui.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use std::time;

use egui::Vec2;
use nalgebra::Vector3;
use tracing::pathtracer::Pathtracer;

use crate::workers::Workers;

struct RenderState {
iteration: u16,
duration: time::Duration,
texture: egui::TextureHandle,
}

pub(crate) struct PathtracerGui {
size: Vec2,
render: Option<RenderState>,
workers: Workers,
}

impl PathtracerGui {
pub(crate) fn new(pathtracer: Pathtracer) -> Self {
Self {
size: Vec2::new(512.0, 512.0),
render: None,
workers: Workers::new(pathtracer, 512, 512),
}
}

pub(crate) fn run(self) -> Result<(), eframe::Error> {
eframe::run_native(
"pathtracer-gui",
Default::default(),
Box::new(move |_cc| Box::new(self)),
)
}
}

impl eframe::App for PathtracerGui {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
ctx.request_repaint_after(std::time::Duration::from_millis(100));
egui::CentralPanel::default().show(ctx, |ui| {
ui.vertical(|ui| {
ui.label(
self.render
.as_ref()
.map_or("rendering...".to_string(), |meta| {
format!("{} in {} ms", meta.iteration, meta.duration.as_millis())
}),
);

let mut resize = false;
ui.horizontal(|ui| {
resize = ui.button("Auto-Size").clicked();
if ui.button("Exit").clicked() {
ui.ctx().send_viewport_cmd(egui::ViewportCommand::Close);
}
});

let mut translation = Vector3::zeros();
if ui.input(|i| i.key_pressed(egui::Key::ArrowUp)) {
translation.y = 0.1;
}
if ui.input(|i| i.key_pressed(egui::Key::ArrowDown)) {
translation.y = -0.1;
}
if ui.input(|i| i.key_pressed(egui::Key::ArrowLeft)) {
translation.x = -0.1;
}
if ui.input(|i| i.key_pressed(egui::Key::ArrowRight)) {
translation.x = 0.1;
}

if resize {
self.size = ui.available_size();
}

if resize || translation != Vector3::zeros() {
self.workers
.send(self.size.x as u32, self.size.y as u32, translation);
}

if let Some(render) = &self.render {
ui.image(&render.texture);
}
});

if let Some(result) = self.workers.try_recv() {
let image = egui::ColorImage::from_rgba_unmultiplied(
[
result.image.width() as usize,
result.image.height() as usize,
],
&result.image.to_rgba8(),
);
let texture = ui.ctx().load_texture("buffer", image, Default::default());
self.render = Some(RenderState {
iteration: result.iteration,
duration: result.duration,
texture,
});
}
});
}

fn on_exit(&mut self, _gl: Option<&eframe::glow::Context>) {
self.workers.join();
}
}
118 changes: 6 additions & 112 deletions pathtracer-gui/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use clap::Parser;
use eframe::egui;
use egui::Vec2;
use kdtree::{build::build_kdtree, build_sah::SahKdTreeBuilder};
use nalgebra::Vector3;
use scene::Scene;
use std::{str, sync::Arc, time};
use tracing::pathtracer::Pathtracer;
use workers::Workers;

use crate::gui::PathtracerGui;

mod gui;
mod workers;

#[derive(Parser, Debug)]
Expand All @@ -25,100 +23,6 @@ struct Args {
empty_factor: f32,
}

struct RenderState {
iteration: u16,
duration: time::Duration,
texture: egui::TextureHandle,
}

struct PathtracerGui {
size: Vec2,
render: Option<RenderState>,
workers: Workers,
}

impl PathtracerGui {
fn new(workers: Workers) -> Self {
Self {
size: Vec2::new(512.0, 512.0),
render: None,
workers,
}
}
}

impl eframe::App for PathtracerGui {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
ctx.request_repaint_after(std::time::Duration::from_millis(100));
egui::CentralPanel::default().show(ctx, |ui| {
ui.vertical(|ui| {
ui.label(
self.render
.as_ref()
.map_or("rendering...".to_string(), |meta| {
format!("{} in {} ms", meta.iteration, meta.duration.as_millis())
}),
);

let mut resize = false;
ui.horizontal(|ui| {
resize = ui.button("Auto-Size").clicked();
if ui.button("Exit").clicked() {
ui.ctx().send_viewport_cmd(egui::ViewportCommand::Close);
}
});

let mut translation = Vector3::zeros();
if ui.input(|i| i.key_pressed(egui::Key::ArrowUp)) {
translation.y = 0.1;
}
if ui.input(|i| i.key_pressed(egui::Key::ArrowDown)) {
translation.y = -0.1;
}
if ui.input(|i| i.key_pressed(egui::Key::ArrowLeft)) {
translation.x = -0.1;
}
if ui.input(|i| i.key_pressed(egui::Key::ArrowRight)) {
translation.x = 0.1;
}

if resize {
self.size = ui.available_size();
}

if resize || translation != Vector3::zeros() {
self.workers
.send(self.size.x as u32, self.size.y as u32, translation);
}

if let Some(render) = &self.render {
ui.image(&render.texture);
}
});

if let Some(result) = self.workers.try_recv() {
let image = egui::ColorImage::from_rgba_unmultiplied(
[
result.image.width() as usize,
result.image.height() as usize,
],
&result.image.to_rgba8(),
);
let texture = ui.ctx().load_texture("buffer", image, Default::default());
self.render = Some(RenderState {
iteration: result.iteration,
duration: result.duration,
texture,
});
}
});
}

fn on_exit(&mut self, _gl: Option<&eframe::glow::Context>) {
self.workers.join();
}
}

fn main() {
let args = Args::parse();
let scene = Scene::read_obj_file_with_print_logging(&args.input);
Expand All @@ -138,21 +42,11 @@ fn main() {
args.max_depth,
);

let pathtracer = Arc::new(Pathtracer {
let pathtracer = Pathtracer {
max_bounces: 16,
scene,
kdtree,
});
let gui = PathtracerGui::new(Workers::new(pathtracer, 512, 512));

let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([512.0, 512.0]),
..Default::default()
};
eframe::run_native(
"pathtracer-cli",
options,
Box::new(move |_cc| Box::new(gui)),
)
.unwrap();

PathtracerGui::new(pathtracer).run().unwrap();
}
11 changes: 9 additions & 2 deletions pathtracer-gui/src/workers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,21 @@ pub struct Workers {
}

impl Workers {
pub fn new(pathtracer: Arc<Pathtracer>, width: u32, height: u32) -> Workers {
pub fn new(pathtracer: Pathtracer, width: u32, height: u32) -> Workers {
let (render_result_tx, render_result_rx) = mpsc::channel::<RenderResult>();
let camera = pathtracer.scene.cameras[0].clone();
let pinhole = Pinhole::new(&camera, width, height);
let (render_settings_tx, render_settings_rx) = mpsc::channel::<Pinhole>();
let thread = std::thread::Builder::new()
.name("Pathtracer Thread".to_string())
.spawn(move || worker_loop(pathtracer, pinhole, render_settings_rx, render_result_tx))
.spawn(move || {
worker_loop(
Arc::new(pathtracer),
pinhole,
render_settings_rx,
render_result_tx,
)
})
.unwrap();

Workers {
Expand Down

0 comments on commit dd11b61

Please sign in to comment.