From 436cb7fa8ab5241f45e6faf9926e5683ca333976 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Sat, 15 Aug 2020 17:34:27 -0400 Subject: [PATCH] use static color frame data instead of from camera --- src/point_cloud/debug/color_image_bytes.rs | 27 +++ src/point_cloud/debug/mod.rs | 1 + src/point_cloud/mod.rs | 7 +- src/point_cloud/point_cloud_renderer.rs | 193 +++++++++++++-------- 4 files changed, 155 insertions(+), 73 deletions(-) create mode 100644 src/point_cloud/debug/color_image_bytes.rs create mode 100644 src/point_cloud/debug/mod.rs diff --git a/src/point_cloud/debug/color_image_bytes.rs b/src/point_cloud/debug/color_image_bytes.rs new file mode 100644 index 0000000000..3b619dce73 --- /dev/null +++ b/src/point_cloud/debug/color_image_bytes.rs @@ -0,0 +1,27 @@ +use anyhow::Result as AnyhowResult; +use std::fs::File; +use std::fs; +use std::io::Read; + +/// Loaded color images from the filesystem +pub struct ColorImageBytes { + bytes: Vec, +} + +impl ColorImageBytes { + pub fn from_file(filename: &str) -> AnyhowResult { + let mut file = File::open(filename)?; + let metadata = fs::metadata(&filename)?; + + let mut buffer = vec![0u8; metadata.len() as usize]; + file.read(&mut buffer)?; + + Ok(Self { + bytes: buffer, + }) + } + + pub fn get_bytes(&self) -> &[u8] { + &self.bytes + } +} diff --git a/src/point_cloud/debug/mod.rs b/src/point_cloud/debug/mod.rs new file mode 100644 index 0000000000..0c6a037336 --- /dev/null +++ b/src/point_cloud/debug/mod.rs @@ -0,0 +1 @@ +pub mod color_image_bytes; \ No newline at end of file diff --git a/src/point_cloud/mod.rs b/src/point_cloud/mod.rs index fd0920a0a8..28b4389fc4 100644 --- a/src/point_cloud/mod.rs +++ b/src/point_cloud/mod.rs @@ -1,6 +1,7 @@ +pub mod debug; pub mod gpu_point_cloud_converter; +pub mod pixel_structs; pub mod point_cloud_renderer; pub mod point_cloud_visualiser; -pub mod pixel_structs; -pub mod viewer_image; -pub mod util; \ No newline at end of file +pub mod util; +pub mod viewer_image; \ No newline at end of file diff --git a/src/point_cloud/point_cloud_renderer.rs b/src/point_cloud/point_cloud_renderer.rs index 96c5e3aba7..3b0029a4cd 100644 --- a/src/point_cloud/point_cloud_renderer.rs +++ b/src/point_cloud/point_cloud_renderer.rs @@ -26,6 +26,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; use opengl::link_program::link_shader_program; +use point_cloud::debug::color_image_bytes::ColorImageBytes; pub type Result = std::result::Result; @@ -106,6 +107,10 @@ pub struct PointCloudRenderer { vertex_color_buffer_objects: Vec, vertex_attrib_locations: Vec, + + /// For debugging + /// If present, use these instead of camera captures. + debug_static_color_frames: Vec, } const fn translation_matrix_4x4(x: f32, y: f32, z: f32) -> [f32; 16] { @@ -261,6 +266,11 @@ impl PointCloudRenderer { [0.0, 0.0, -0.2002, 0.0], ]; + let mut debug_static_color_frames = Vec::new(); + + debug_static_color_frames.push(ColorImageBytes::from_file("output/color_src_0").unwrap()); + debug_static_color_frames.push(ColorImageBytes::from_file("output/color_src_1").unwrap()); + Self { num_cameras, arcball_camera: arcball, @@ -281,6 +291,7 @@ impl PointCloudRenderer { vertex_array_objects, vertex_color_buffer_objects, vertex_attrib_locations, + debug_static_color_frames, } } @@ -320,29 +331,10 @@ impl PointCloudRenderer { (1, 2) }; - let (lower_range, upper_range) = (0, 2); + //let (lower_range, upper_range) = (0, 2); //for i in 0 .. self.num_cameras { for i in lower_range .. upper_range { - - let color_image = color_images.get(i).unwrap(); - let point_cloud_texture = point_cloud_textures.get(i).unwrap(); - - // NB: This experiment demonstrates that only one set of texture (colors) seem to be updated. - // let i = if seconds % 10 > 4 { - // j // primary camera first - // } else { - // 1 - j // secondary camera first - // }; - - // EXPERIMENTAL RESULTS TABLE. - // The first camera index is the one that gets the color - //let i = j; // geometry1, cameratexture1, (below is i=j) - //let i = 1 - j; //geometry2, cameratexture2 (below is i=j) - //let i = j; // geometry2, cameratexture1, (below is i=1-j) - //let i = 1 - j; //geometry1, cameratexture2 (below is i=1-j) - //let i = if swap { j } else { 1 - j }; // swaps which image data is used - let vertex_array_object = self.vertex_array_objects.get(i).unwrap(); let vertex_color_buffer_object = self.vertex_color_buffer_objects.get(i).unwrap(); let mut vertex_array_size_bytes = self.vertex_arrays_size_bytes.get_mut(i).unwrap(); @@ -353,62 +345,123 @@ impl PointCloudRenderer { gl::BindBuffer(gl::ARRAY_BUFFER, vertex_color_buffer_object.id()); } - let color_image_size_bytes = color_image.get_size() as i32; + if let Some(debug_color_image) = self.debug_static_color_frames.get(i) { + let color_image_bytes = debug_color_image.get_bytes(); + let color_image_size_bytes = color_image_bytes.len() as i32; - if *vertex_array_size_bytes != color_image_size_bytes { - println!("Establishing buffer"); - *vertex_array_size_bytes = color_image_size_bytes; + if *vertex_array_size_bytes != color_image_size_bytes { + println!("Establishing buffer"); + *vertex_array_size_bytes = color_image_size_bytes; - unsafe { - gl::BufferData( + unsafe { + gl::BufferData( + gl::ARRAY_BUFFER, + *vertex_array_size_bytes as isize, + null(), + gl::STREAM_DRAW + ); + } + } + + let vertex_mapped_buffer = unsafe { + gl::MapBufferRange( gl::ARRAY_BUFFER, - *vertex_array_size_bytes as isize, - null(), - gl::STREAM_DRAW - ); + 0, + color_image_size_bytes as isize, + gl::MAP_WRITE_BIT | gl::MAP_INVALIDATE_BUFFER_BIT + ) as *mut u8 + }; + + if vertex_mapped_buffer as usize == 0 { + let error = gl_get_error().expect_err("should be map buffer range error"); + return Err(PointCloudRendererError::OpenGlError(error)); + } + + let typed_color_src = color_image_bytes.as_ptr(); + + let result = unsafe { + /*if i == 9 { + // TODO TESTING - writing pure white changes the color of the final output "line" to white: + std::ptr::copy::(color_src, vertex_mapped_buffer as *mut u8, color_image_size_bytes as usize); + std::ptr::write_bytes(vertex_mapped_buffer, 255, color_image_size_bytes as usize); + } else { + }*/ + + // NB: This is the working texturing: + std::ptr::copy_nonoverlapping::(typed_color_src, + vertex_mapped_buffer, + color_image_size_bytes as usize); + + gl::UnmapBuffer(gl::ARRAY_BUFFER) + }; + + if result == gl::FALSE { + let error = gl_get_error().expect_err("should be unmap buffer error"); + return Err(PointCloudRendererError::OpenGlError(error)); + } + + } else { + let color_image = color_images.get(i).unwrap(); + let color_image_size_bytes = color_image.get_size() as i32; + + if *vertex_array_size_bytes != color_image_size_bytes { + println!("Establishing buffer"); + *vertex_array_size_bytes = color_image_size_bytes; + + unsafe { + gl::BufferData( + gl::ARRAY_BUFFER, + *vertex_array_size_bytes as isize, + null(), + gl::STREAM_DRAW + ); + } + } + + let vertex_mapped_buffer = unsafe { + gl::MapBufferRange( + gl::ARRAY_BUFFER, + 0, + color_image_size_bytes as isize, + gl::MAP_WRITE_BIT | gl::MAP_INVALIDATE_BUFFER_BIT + ) as *mut u8 + }; + + if vertex_mapped_buffer as usize == 0 { + let error = gl_get_error().expect_err("should be map buffer range error"); + return Err(PointCloudRendererError::OpenGlError(error)); + } + + let color_src = color_image.get_buffer(); + let typed_color_src = color_src as *const u8; + + //let filename = format!("output/color_src_{}", i); + //write_file_from_byte_ptr(&filename, color_src, color_image_size_bytes as usize).unwrap(); + + let result = unsafe { + /*if i == 9 { + // TODO TESTING - writing pure white changes the color of the final output "line" to white: + std::ptr::copy::(color_src, vertex_mapped_buffer as *mut u8, color_image_size_bytes as usize); + std::ptr::write_bytes(vertex_mapped_buffer, 255, color_image_size_bytes as usize); + } else { + }*/ + + // NB: This is the working texturing: + std::ptr::copy_nonoverlapping::(typed_color_src, + vertex_mapped_buffer, + color_image_size_bytes as usize); + + gl::UnmapBuffer(gl::ARRAY_BUFFER) + }; + + if result == gl::FALSE { + let error = gl_get_error().expect_err("should be unmap buffer error"); + return Err(PointCloudRendererError::OpenGlError(error)); } } - let vertex_mapped_buffer = unsafe { - gl::MapBufferRange( - gl::ARRAY_BUFFER, - 0, - color_image_size_bytes as isize, - gl::MAP_WRITE_BIT | gl::MAP_INVALIDATE_BUFFER_BIT - ) as *mut u8 - }; - if vertex_mapped_buffer as usize == 0 { - let error = gl_get_error().expect_err("should be map buffer range error"); - return Err(PointCloudRendererError::OpenGlError(error)); - } - - let color_src = color_image.get_buffer(); - let typed_color_src = color_src as *const u8; - - let filename = format!("output/color_src_{}", i); - write_file_from_byte_ptr(&filename, color_src, color_image_size_bytes as usize).unwrap(); - - let result = unsafe { - /*if i == 9 { - // TODO TESTING - writing pure white changes the color of the final output "line" to white: - std::ptr::copy::(color_src, vertex_mapped_buffer as *mut u8, color_image_size_bytes as usize); - std::ptr::write_bytes(vertex_mapped_buffer, 255, color_image_size_bytes as usize); - } else { - }*/ - - // NB: This is the working texturing: - std::ptr::copy_nonoverlapping::(typed_color_src, - vertex_mapped_buffer, - color_image_size_bytes as usize); - - gl::UnmapBuffer(gl::ARRAY_BUFFER) - }; - - if result == gl::FALSE { - let error = gl_get_error().expect_err("should be unmap buffer error"); - return Err(PointCloudRendererError::OpenGlError(error)); - } + let point_cloud_texture = point_cloud_textures.get(i).unwrap(); // NB: This controls which geometry gets the texture/color data. If we hardcode it to // a single index, only one of the camera geometries gets shaded. @@ -510,7 +563,7 @@ impl PointCloudRenderer { (1, 2) }; - let (lower_range, upper_range) = (0, 2); + //let (lower_range, upper_range) = (0, 2); // Render point cloud //for i in 0 .. self.num_cameras {