Files
artcraft-services/old_code/cloudcam-green-screen/src/graphics_imgui.rs
T

281 lines
9.3 KiB
Rust

use anyhow::Result as AnyhowResult;
use kinect::Calibration;
use crate::ProgramArgs;
use crate::core_types::RgbaF32;
use crate::gui::enhanced_window::EnhancedWindow;
use crate::gui::mouse_camera_arcball::MouseCameraArcball;
use crate::azure_kinect::capture::device_capturer::CaptureProvider;
use crate::point_cloud::pixel_structs::BgraPixel;
use crate::point_cloud::point_cloud_visualiser::{ColorizationStrategy, PointCloudVisualizer, PointCloudVisualizerError};
use crate::point_cloud::viewer_image::ViewerImage;
use crate::webcam::WebcamWriter;
use gl;
use imgui::*;
use imgui::Image;
use std::path::Path;
use std::sync::{Arc, Mutex, PoisonError, MutexGuard};
use std::time::{Instant, Duration};
pub fn run(capture_provider: Arc<CaptureProvider>, program_args: ProgramArgs) -> AnyhowResult<()> {
let mut webcam_writer = None;
if program_args.enable_webcam_output_writing {
webcam_writer = Some(WebcamWriter::open_file("/dev/video0", 1280, 720, 3)
.expect("should be able to create webcamwriter"));
}
let sdl_arcball = Arc::new(Mutex::new(MouseCameraArcball::new(1280, 720)));
let sdl_context = sdl2::init().unwrap();
let video = sdl_context.video().unwrap();
{
let gl_attr = video.gl_attr();
gl_attr.set_context_profile(sdl2::video::GLProfile::Core);
gl_attr.set_context_version(3, 0);
}
let window = video.window("rust-imgui-sdl2 demo", 3000, 2000)
.position_centered()
.resizable()
.opengl()
.allow_highdpi()
.build()
.unwrap();
let _gl_context = window.gl_create_context().expect("Couldn't create GL context");
gl::load_with(|s| video.gl_get_proc_address(s) as _);
//enable_opengl_debugging();
let mut imgui = imgui::Context::create();
imgui.set_ini_filename(None);
imgui.io_mut().config_windows_move_from_title_bar_only = true;
/*let gl_texture_n64 = load_texture("n64logo.png");
let imgui_texture_n64 = TextureId::from(gl_texture_n64 as usize);
let mut gl_texture_snes = load_texture("sneslogo.png");
let mut imgui_texture_snes = TextureId::from(gl_texture_snes as usize);*/
let colorization_strategy = ColorizationStrategy::Color;
// NB: Green screen
//let clear_color = RgbaF32::gray(0.5);
let clear_color = RgbaF32::rgb(0.0, 1.0, 0.0);
let mut visualizer = PointCloudVisualizer::new(
capture_provider.get_num_cameras(),
capture_provider.get_calibrations(),
true,
colorization_strategy,
clear_color,
sdl_arcball.clone(),
);
//rebinder.restore();
let texture = ViewerImage::create(
// TODO: The following commented-out values work and look great,
// but now we're doing suboptimal webcam stuff:
//1280,
//1152,
1280,
720,
).expect("ViewerImage texture creation should work");
let mut imgui_visualizer_xyz_texture_0 : Option<TextureId> = None;
let mut imgui_visualizer_xyz_texture_1 : Option<TextureId> = None;
let imgui_point_cloud_convert_xy_table= TextureId::from(visualizer.point_cloud_converters.get(0).unwrap().xy_table_texture.id() as usize);
let imgui_kinect_final_output = TextureId::from(texture.texture_id() as usize);
let mut imgui_sdl2 = imgui_sdl2::ImguiSdl2::new(&mut imgui, &window);
let renderer = imgui_opengl_renderer::Renderer::new(&mut imgui, |s| video.gl_get_proc_address(s) as _);
let mut event_pump = sdl_context.event_pump().unwrap();
let mut last_frame = Instant::now();
let mut last_change = Instant::now();
let mut camera_index = 0;
visualizer.setup_rendering()?;
'running: loop {
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
for event in event_pump.poll_iter() {
imgui_sdl2.handle_event(&mut imgui, &event);
// TODO: This is how Imgui appears to tell SDL to ignore certain events.
if imgui_sdl2.ignore_event(&event) { continue; }
match event {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'running
},
_ => {}
}
/*// Also send to the arcball to update the view matrix.
match sdl_arcball.lock() {
Ok(mut arcball) => arcball.process_event(&event),
Err(_) => {},
}*/
}
imgui_sdl2.prepare_frame(imgui.io_mut(), &window, &event_pump.mouse_state());
let now = Instant::now();
let delta = now - last_frame;
let delta_s = delta.as_secs() as f32 + delta.subsec_nanos() as f32 / 1_000_000_000.0;
last_frame = now;
imgui.io_mut().delta_time = delta_s;
let ui = imgui.frame();
//ui.show_demo_window(&mut true);
const window_width : f32 = 1290.0;
const window_height : f32 = 760.0;
if imgui_visualizer_xyz_texture_0.is_none() {
// TODO: TEMPORARY MESS TO SUPPORT MULTI-CAMERA
if visualizer.xyz_textures.get(0).unwrap().id() != 0 {
imgui_visualizer_xyz_texture_0 = Some(TextureId::from(visualizer.xyz_textures.get(0).unwrap().id() as usize));
}
}
if imgui_visualizer_xyz_texture_1.is_none() {
// TODO: TEMPORARY MESS TO SUPPORT MULTI-CAMERA
// TODO/NB(2022-03-20): No multi camera
//if visualizer.xyz_textures.get(1).unwrap().id() != 0 {
// imgui_visualizer_xyz_texture_1 = Some(TextureId::from(visualizer.xyz_textures.get(1).unwrap().id() as usize));
//}
}
Window::new(im_str!("Visualizer XYZ Texture (0)"))
.scrollable(true)
.size([window_width, window_height], Condition::FirstUseEver)
.position([0.0, 0.0], Condition::FirstUseEver)
.build(&ui, || {
match imgui_visualizer_xyz_texture_0.as_ref() {
None => {},
Some(xyz_texture) => {
Image::new(xyz_texture.clone(), [1280.0, 720.0]).build(&ui);
},
}
});
// TODO/NB(2022-03-20): No multi camera
//Window::new(im_str!("Visualizer XYZ Texture (1)"))
// .size([window_width, window_height], Condition::FirstUseEver)
// .position([window_width + 50.0, 0.0], Condition::FirstUseEver)
// .movable(false)
// .build(&ui, || {
// match imgui_visualizer_xyz_texture_1.as_ref() {
// None => {},
// Some(xyz_texture) => {
// Image::new(xyz_texture.clone(), [1280.0, 720.0]).build(&ui);
// },
// }
// });
Window::new(im_str!("Point Cloud Converter XY Table"))
.size([window_width, window_height], Condition::FirstUseEver)
.position([0.0, window_height + 50.0], Condition::FirstUseEver)
.build(&ui, || {
Image::new(imgui_point_cloud_convert_xy_table, [1280.0, 720.0]).build(&ui);
});
// NB: This is larger. The texture is 1280x1152.
EnhancedWindow::new(&im_str!("Final Output: {:?}", colorization_strategy))
.size([window_width, window_height + 435.0], Condition::FirstUseEver)
.position([window_width + 50.0, window_height + 50.0], Condition::FirstUseEver)
.mouse_inputs(true)
.build(&ui, |window| {
if let Some(mouse_state) = window.get_window_bounded_mouse_state() {
match sdl_arcball.lock() {
Ok(mut arcball) => arcball.process_mouse_state(mouse_state),
Err(_) => {},
}
}
Image::new(imgui_kinect_final_output, [1280.0, 720.0]).build(&ui);
});
unsafe {
gl::ClearColor(0.2, 0.2, 0.2, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT);
}
imgui_sdl2.prepare_render(&ui, &window);
renderer.render(ui);
window.gl_swap_window();
if let Some(mut captures) = capture_provider.get_captures() {
if program_args.save_captures {
// Only save the last frame (for now)
for (i, capture) in captures.iter().enumerate() {
let suffix = format!("{}", i);
capture.debug_save_files(Path::new("output/"), &suffix).unwrap();
}
}
visualizer.update_texture_id(texture.texture_id(), captures)
.map(|_| {})
.map_err(|err| {
match err {
PointCloudVisualizerError::MissingDepthImage => { println!("Missing depth image"); },
PointCloudVisualizerError::MissingColorImage => { println!("Missing color image"); },
_ => {
unreachable!("Error: {:?}", err);
}
}
});
}
match sdl_arcball.lock() {
Ok(mut arcball) => {
arcball.animate();
},
Err(_) => {},
}
if let Some(mut webcam) = webcam_writer.as_mut() {
webcam.write_current_frame_to_file(texture.texture_id())
.expect("should write");
}
let change_delta = last_frame - last_change;
if change_delta > Duration::from_millis(5_000) {
camera_index = (camera_index + 1) % capture_provider.get_num_cameras();
last_change = Instant::now();
}
/*if change_delta > Duration::from_millis(5000) {
colorization_strategy = match colorization_strategy {
ColorizationStrategy::Simple => ColorizationStrategy::Shaded, // NB: We won't do simple.
ColorizationStrategy::Shaded => ColorizationStrategy::Color,
ColorizationStrategy::Color => ColorizationStrategy::Shaded,
};
println!("Changing colorization strategy: {:?}", colorization_strategy);
visualizer.set_colorization_strategy(colorization_strategy);
last_change = Instant::now();
}*/
//rebinder.restore();
std::thread::sleep(::std::time::Duration::new(0, 1_000_000_000u32 / 60));
}
Ok(())
}