From e33bed276ad40d8095feec10c39cc56b6fc20dcb Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Sat, 15 Aug 2020 18:28:25 -0400 Subject: [PATCH] extract point cloud compute shader; share file ops --- src/files/mod.rs | 1 + src/files/read_file_string_contents.rs | 10 +++ src/main.rs | 3 +- src/point_cloud/gpu_point_cloud_converter.rs | 62 ++----------------- src/point_cloud/point_cloud_renderer.rs | 16 ++--- .../shaders/point_cloud_compute_shader.glsl | 53 ++++++++++++++++ 6 files changed, 76 insertions(+), 69 deletions(-) create mode 100644 src/files/mod.rs create mode 100644 src/files/read_file_string_contents.rs create mode 100644 src/point_cloud/shaders/point_cloud_compute_shader.glsl diff --git a/src/files/mod.rs b/src/files/mod.rs new file mode 100644 index 0000000000..9ba4e750e9 --- /dev/null +++ b/src/files/mod.rs @@ -0,0 +1 @@ +pub mod read_file_string_contents; \ No newline at end of file diff --git a/src/files/read_file_string_contents.rs b/src/files/read_file_string_contents.rs new file mode 100644 index 0000000000..a70c3e1b69 --- /dev/null +++ b/src/files/read_file_string_contents.rs @@ -0,0 +1,10 @@ +use anyhow::Result as AnyhowResult; +use std::fs::File; +use std::io::Read; + +pub fn read_file_string_contents(filename: &str) -> AnyhowResult { + let mut file = File::open(filename)?; + let mut contents = String::new(); + file.read_to_string(&mut contents)?; + Ok(contents) +} diff --git a/src/main.rs b/src/main.rs index ff92dd6334..b6a840e7a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,10 +31,11 @@ use kinect::k4a_sys_wrapper::Device; use kinect::sensor_control::{capture_thread, CaptureProvider}; use kinect::multi_device_capturer::{MultiDeviceCapturer, start_capture_thread}; -pub mod image_debug; pub mod core_types; +pub mod files; pub mod graphics_imgui; pub mod gui; +pub mod image_debug; pub mod imgui_support; pub mod kinect; pub mod opengl; diff --git a/src/point_cloud/gpu_point_cloud_converter.rs b/src/point_cloud/gpu_point_cloud_converter.rs index c70e87a649..38c06a82dd 100644 --- a/src/point_cloud/gpu_point_cloud_converter.rs +++ b/src/point_cloud/gpu_point_cloud_converter.rs @@ -20,6 +20,7 @@ use opengl::opengl_wrapper::OpenGlError; use opengl::opengl_wrapper::Texture; use opengl::opengl_wrapper::{Buffer, gl_get_error}; use point_cloud::pixel_structs::DepthPixel; +use files::read_file_string_contents::read_file_string_contents; pub type Result = std::result::Result; @@ -55,62 +56,6 @@ impl std::error::Error for PointCloudComputeError { } } -/// This is taken from Microsoft's MIT-licensed k4a libraries. -/// From the file `tools/k4aviewer/graphics/shaders/gpudepthtopointcloudconverter.cpp` -pub static COMPUTE_SHADER_SRC: &'static str = "\ -#version 430 - -layout(location=0, rgba32f) writeonly uniform image2D destTex; - -layout(location=1, r16ui) readonly uniform uimage2D depthImage; -layout(location=2, rg32f) readonly uniform image2D xyTable; - -layout(local_size_x = 1, local_size_y = 1) in; - -void main() -{ - ivec2 pixel = ivec2(gl_GlobalInvocationID.xy); - - float vertexValue = float(imageLoad(depthImage, pixel)); - // TODO: The problem is that these are bound to (0.0, 0.0). It isn't working. - vec2 xyValue = imageLoad(xyTable, pixel).xy; - - float alpha = 1.0f; - // vertexPosition format: RGB colors as floats, but not range [0.0, 1.0], but rather [0.0, 255.0] - // HOWEVER, there are operations that reverse the sign of the 'x' channel ('r') and scale down by 1000 below. - vec3 vertexPosition = vec3(vertexValue * xyValue.x, vertexValue * xyValue.y, vertexValue); - - // Invalid pixels have their XY table values set to 0. - // Set the rest of their values to 0 so clients can pick them out. - // - if (xyValue.x == 0.0f && xyValue.y == 0.0f) - { - alpha = 0.0f; - vertexValue = 0.0f; - } - - // Vertex positions are in millimeters, but everything else is in meters, so we need to convert - // - vertexPosition /= 1000.0f; - - // OpenGL and K4A have different conventions on which direction is positive - - // we need to flip the X coordinate. - // - vertexPosition.x *= -1; - - // Distance Threshold - // TODO: Make configurable. - /*if (vertexPosition.z > 1.5) { - alpha = 0.0f; - vertexPosition.x = 0.0; - vertexPosition.y = 0.0; - vertexPosition.z = 0.0; - }*/ - - imageStore(destTex, pixel, vec4(vertexPosition, alpha)); -} -"; - /// The format that the point cloud texture uses internally to store points. /// If you want to use the texture that this outputs from your shader, you /// need to pass this as the format argument to glBindImageTexture(). @@ -143,7 +88,10 @@ impl GpuPointCloudConverter { pub fn new() -> Self { let program_id = unsafe { gl::CreateProgram() }; - let shader_id = compile_shader(COMPUTE_SHADER_SRC, gl::COMPUTE_SHADER); + + let point_cloud_compute_shader = read_file_string_contents("src/point_cloud/shaders/point_cloud_compute_shader.glsl").unwrap(); + + let shader_id = compile_shader(&point_cloud_compute_shader, gl::COMPUTE_SHADER); link_program(program_id, shader_id); diff --git a/src/point_cloud/point_cloud_renderer.rs b/src/point_cloud/point_cloud_renderer.rs index 4a4470f48b..f62a0550d1 100644 --- a/src/point_cloud/point_cloud_renderer.rs +++ b/src/point_cloud/point_cloud_renderer.rs @@ -27,6 +27,7 @@ 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; +use files::read_file_string_contents::read_file_string_contents; pub type Result = std::result::Result; @@ -170,8 +171,8 @@ impl PointCloudRenderer { let program_id = unsafe { gl::CreateProgram() }; - let mut point_cloud_vertex_shader = read_file_contents("src/point_cloud/shaders/point_cloud_vertex_shader.glsl").unwrap(); - let mut point_cloud_fragment_shader = read_file_contents("src/point_cloud/shaders/point_cloud_fragment_shader.glsl").unwrap(); + let mut point_cloud_vertex_shader = read_file_string_contents("src/point_cloud/shaders/point_cloud_vertex_shader.glsl").unwrap(); + let mut point_cloud_fragment_shader = read_file_string_contents("src/point_cloud/shaders/point_cloud_fragment_shader.glsl").unwrap(); let vertex_shader_id = compile_shader(&point_cloud_vertex_shader, gl::VERTEX_SHADER); let fragment_shader_id = compile_shader(&point_cloud_fragment_shader, gl::FRAGMENT_SHADER); @@ -268,8 +269,8 @@ impl PointCloudRenderer { 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()); + 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, @@ -557,13 +558,6 @@ impl PointCloudRenderer { } } -fn read_file_contents(filename: &str) -> AnyhowResult { - let mut file = File::open(filename)?; - let mut contents = String::new(); - file.read_to_string(&mut contents)?; - Ok(contents) -} - /// Raw memory copy into a file fn write_file_from_byte_ptr(filename: &str, byte_src: *const u8, size_bytes: usize) -> AnyhowResult<()> { let mut file = OpenOptions::new() diff --git a/src/point_cloud/shaders/point_cloud_compute_shader.glsl b/src/point_cloud/shaders/point_cloud_compute_shader.glsl new file mode 100644 index 0000000000..22e9d6a38b --- /dev/null +++ b/src/point_cloud/shaders/point_cloud_compute_shader.glsl @@ -0,0 +1,53 @@ +// This is taken from Microsoft's MIT-licensed k4a libraries. +// From the file `tools/k4aviewer/graphics/shaders/gpudepthtopointcloudconverter.cpp` +#version 430 + +layout(location=0, rgba32f) writeonly uniform image2D destTex; + +layout(location=1, r16ui) readonly uniform uimage2D depthImage; +layout(location=2, rg32f) readonly uniform image2D xyTable; + +layout(local_size_x = 1, local_size_y = 1) in; + +void main() +{ + ivec2 pixel = ivec2(gl_GlobalInvocationID.xy); + + float vertexValue = float(imageLoad(depthImage, pixel)); + // TODO: The problem is that these are bound to (0.0, 0.0). It isn't working. + vec2 xyValue = imageLoad(xyTable, pixel).xy; + + float alpha = 1.0f; + // vertexPosition format: RGB colors as floats, but not range [0.0, 1.0], but rather [0.0, 255.0] + // HOWEVER, there are operations that reverse the sign of the 'x' channel ('r') and scale down by 1000 below. + vec3 vertexPosition = vec3(vertexValue * xyValue.x, vertexValue * xyValue.y, vertexValue); + + // Invalid pixels have their XY table values set to 0. + // Set the rest of their values to 0 so clients can pick them out. + // + if (xyValue.x == 0.0f && xyValue.y == 0.0f) + { + alpha = 0.0f; + vertexValue = 0.0f; + } + + // Vertex positions are in millimeters, but everything else is in meters, so we need to convert + // + vertexPosition /= 1000.0f; + + // OpenGL and K4A have different conventions on which direction is positive - + // we need to flip the X coordinate. + // + vertexPosition.x *= -1; + + // Distance Threshold + // TODO: Make configurable. + /*if (vertexPosition.z > 1.5) { + alpha = 0.0f; + vertexPosition.x = 0.0; + vertexPosition.y = 0.0; + vertexPosition.z = 0.0; + }*/ + + imageStore(destTex, pixel, vec4(vertexPosition, alpha)); +}