From cdbdf77f156a1f27c28af0852eda46488927bbfc Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Tue, 18 Aug 2020 03:19:42 -0400 Subject: [PATCH] Lots of cleanup... following graphics4363 --- src/opengl/wrapper/buffer.rs | 6 + src/point_cloud/point_cloud_renderer.rs | 339 ++++-------------- .../shaders/point_cloud_vertex_shader.glsl | 10 +- 3 files changed, 71 insertions(+), 284 deletions(-) diff --git a/src/opengl/wrapper/buffer.rs b/src/opengl/wrapper/buffer.rs index 0e729560e4..bb43cc2801 100644 --- a/src/opengl/wrapper/buffer.rs +++ b/src/opengl/wrapper/buffer.rs @@ -43,6 +43,12 @@ impl Buffer { } } + pub fn bind_as_array_buffer(&self) { + unsafe { + gl::BindBuffer(gl::ARRAY_BUFFER, self.id); + } + } + pub fn gen(&mut self) { unsafe { gl::GenBuffers(1, &mut self.id); diff --git a/src/point_cloud/point_cloud_renderer.rs b/src/point_cloud/point_cloud_renderer.rs index 7b2cf547ae..310b7d6c0c 100644 --- a/src/point_cloud/point_cloud_renderer.rs +++ b/src/point_cloud/point_cloud_renderer.rs @@ -117,7 +117,8 @@ pub struct PointCloudRenderer { vertex_array_objects: Vec, vertex_color_buffer_objects: Vec, - vertex_attrib_locations: Vec, + /// 'in vec4 inColor' + color_vertex_attribute_location: GLint, renderable_objects: Vec, } @@ -172,7 +173,6 @@ const fn initial_projection_matrix_4x4() -> [f32; 16] { impl PointCloudRenderer { pub fn new(num_cameras: usize, arcball: Arc>) -> Self { - // Context Settings unsafe { gl::Enable(gl::PROGRAM_POINT_SIZE); } @@ -185,18 +185,6 @@ impl PointCloudRenderer { 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); - let ATTRIB_LOCATION_0 : CString = CString::new("inColor0").expect("string is correct"); - let ATTRIB_LOCATION_0_PTR : *const c_char = ATTRIB_LOCATION_0.as_ptr() as *const c_char; - - let ATTRIB_LOCATION_1 : CString = CString::new("inColor1").expect("string is correct"); - let ATTRIB_LOCATION_1_PTR : *const c_char = ATTRIB_LOCATION_1.as_ptr() as *const c_char; - - unsafe { - // NB: These calls aren't necessary. - //gl::BindAttribLocation(program_id, 1, ATTRIB_LOCATION_0_PTR); - //gl::BindAttribLocation(program_id, 2, ATTRIB_LOCATION_1_PTR); - } - link_shader_program(program_id, vertex_shader_id, fragment_shader_id); /// Uniform variable name in OpenGL shader program @@ -218,6 +206,9 @@ impl PointCloudRenderer { let POINT_CLOUD_1 : CString = CString::new("pointCloudTexture1").expect("string is correct"); let POINT_CLOUD_1_PTR : *const c_char = POINT_CLOUD_1.as_ptr() as *const c_char; + let COLOR_LOCATION : CString = CString::new("inColor").expect("string is correct"); + let COLOR_LOCATION_PTR : *const c_char = COLOR_LOCATION.as_ptr() as *const c_char; + let mut point_cloud_texture_indices = Vec::with_capacity(num_cameras); let mut view_index = 0; @@ -237,46 +228,22 @@ impl PointCloudRenderer { point_cloud_texture_indices.push(gl::GetUniformLocation(program_id, POINT_CLOUD_1_PTR)); } - // TODO: If this works, these could use grouping in a single struct. - let mut vertex_array_objects = Vec::with_capacity(num_cameras); - let mut vertex_color_buffer_objects = Vec::with_capacity(num_cameras); - let mut vertex_arrays_size_bytes = Vec::with_capacity(num_cameras); + let color_vertex_attribute_location = unsafe { + let location = gl::GetAttribLocation(program_id, COLOR_LOCATION_PTR); - // TODO: Holy crap, this might be the problem - not binding after create of VAO - // TODO: Holy crap, this might be the problem - not binding after create of VAO - // TODO: Holy crap, this might be the problem - not binding after create of VAO - // TODO: Holy crap, this might be the problem - not binding after create of VAO - for _ in 0 .. num_cameras { - let vao = VertexArray::new_initialized(); - vao.bind(); - vertex_array_objects.push(vao); - let buffer = Buffer::new_initialized(); - vertex_color_buffer_objects.push(buffer); - vertex_arrays_size_bytes.push(0); - } + gl::EnableVertexAttribArray(location as u32); - let mut vertex_attrib_locations = Vec::with_capacity(num_cameras); - - unsafe { - let location_0 = gl::GetAttribLocation(program_id, ATTRIB_LOCATION_0_PTR); - println!("Location0: {}", location_0); - vertex_attrib_locations.push(location_0); - - //let location_1 = gl::GetAttribLocation(program_id, ATTRIB_LOCATION_1_PTR); - //println!("Location1: {}", location_1); - //vertex_attrib_locations.push(location_1); - - // Perhaps it only needs to be configured once... - gl::EnableVertexAttribArray(location_0 as u32); gl::VertexAttribPointer( - location_0 as u32, + location as u32, gl::BGRA as i32, gl::UNSIGNED_BYTE, gl::TRUE, 0 as i32, 0 as *const c_void, ); - } + + location + }; let initial_view = [ [-1.0, 0.0, 8.74228e-08, 0.0], @@ -305,14 +272,14 @@ impl PointCloudRenderer { point_size: 1, enable_shading: false, renderable_objects: Vec::new(), - vertex_arrays_size_bytes, view_index, projection_index, enable_shading_index, point_cloud_texture_indices, - vertex_array_objects, - vertex_color_buffer_objects, - vertex_attrib_locations, + vertex_array_objects: Vec::with_capacity(num_cameras), + vertex_arrays_size_bytes : Vec::with_capacity(num_cameras), + vertex_color_buffer_objects: Vec::with_capacity(num_cameras), + color_vertex_attribute_location, } } @@ -320,35 +287,15 @@ impl PointCloudRenderer { /// Run once to set up initial rendering /// pub fn setup_rendering(&mut self) { + for _ in 0 .. self.num_cameras { + let vao = VertexArray::new_initialized(); + vao.bind(); + self.vertex_array_objects.push(vao); - /*unsafe { - gl::UseProgram(self.shader_program_id); - - for i in 0..self.num_cameras { - - let mut vao: u32 = 0; - gl::GenVertexArrays(1, &mut vao); - - println!("Gen Vao: {:?}", vao); - - gl::BindVertexArray(vao); - - let mut color_buffer: u32 = 0; - gl::GenBuffers(1, &mut color_buffer); - - println!("Gen Color Buffer: {:?}", color_buffer); - - let renderable_object = RenderableObject { - vao, - color_buffer, - buffered: false, - }; - - self.renderable_objects.push(renderable_object); - - gl::BindVertexArray(0); - } - }*/ + let buffer = Buffer::new_initialized(); + self.vertex_color_buffer_objects.push(buffer); + self.vertex_arrays_size_bytes.push(0); + } } /// @@ -376,92 +323,31 @@ impl PointCloudRenderer { /// pub fn update_point_clouds(&mut self, color_images: &Vec, - point_cloud_textures: &Vec - ) -> Result<()> { - - /* - for (i, obj) in self.renderable_objects.iter_mut().enumerate() { + point_cloud_textures: &Vec) -> Result<()> + { + for i in 0 .. self.num_cameras { let color_image_bytes = color_images.get(i).unwrap(); let color_image_size_bytes = color_image_bytes.len() as i32; - unsafe { - gl::BindVertexArray(obj.vao); - gl::BindBuffer(gl::ARRAY_BUFFER, obj.color_buffer); - - if !obj.buffered { - gl::BufferData( - gl::ARRAY_BUFFER, - color_image_size_bytes as isize, - null(), - gl::STREAM_DRAW - ); - - obj.buffered = true; - } - - 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 - }; - - std::ptr::copy_nonoverlapping::( - color_image_bytes.as_ptr(), - vertex_mapped_buffer, - color_image_size_bytes as usize); - - gl::UnmapBuffer(gl::ARRAY_BUFFER); - gl::BindBuffer(gl::ARRAY_BUFFER, 0); - gl::BindVertexArray(0); - } - } - */ - - let time = SystemTime::now(); - let time_since_epoch = time.duration_since(UNIX_EPOCH).unwrap(); - let seconds = time_since_epoch.as_secs(); - - let (lower_range, upper_range)= if seconds % 10 > 4 { - (1, 2) - } else { - (0, 1) - }; - - //let (lower_range, upper_range) = (1, 2); - - let (lower_range, upper_range) = (0, 2); - - //for i in 0 .. self.num_cameras { - for i in lower_range .. upper_range { - 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 vao = self.vertex_array_objects.get(i).unwrap(); + let vertex_color_buffer = self.vertex_color_buffer_objects.get(i).unwrap(); let mut vertex_array_size_bytes = self.vertex_arrays_size_bytes.get_mut(i).unwrap(); - let color_image_bytes = color_images.get(i).unwrap(); - let color_image_size_bytes = color_image_bytes.len() as i32; - - unsafe { - gl::BindVertexArray(vertex_array_object.id()); - // Vertex Colors - gl::BindBuffer(gl::ARRAY_BUFFER, vertex_color_buffer_object.id()); - } - - if *vertex_array_size_bytes != color_image_size_bytes { - println!("Establishing buffer"); - *vertex_array_size_bytes = color_image_size_bytes; + vao.bind(); + vertex_color_buffer.bind_as_array_buffer(); + //if *vertex_array_size_bytes != color_image_size_bytes { + //println!("Establishing buffer"); unsafe { gl::BufferData( gl::ARRAY_BUFFER, - *vertex_array_size_bytes as isize, + color_image_size_bytes as isize, null(), gl::STREAM_DRAW ); } - } + *vertex_array_size_bytes = color_image_size_bytes; + //} let vertex_mapped_buffer = unsafe { gl::MapBufferRange( @@ -472,19 +358,12 @@ impl PointCloudRenderer { ) 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)); - } + // 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 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::( color_image_bytes.as_ptr(), @@ -494,45 +373,17 @@ impl PointCloudRenderer { 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)); - } + // if result == gl::FALSE { + // let error = gl_get_error().expect_err("should be unmap buffer error"); + // return Err(PointCloudRendererError::OpenGlError(error)); + // } + // THIS IS THE POINT CLOUD 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. - //let i = j; // (SEE TABLE ABOVE) - //let i = 1 - j; // (SEE TABLE ABOVE) - //let i = if !swap { j } else { 1 - j }; // (in isolation) PUTS THE IMAGES ON BOTH POINTCLOUD GEOS!? - unsafe { - // NB: I believe these point cloud textures are the geometry itself. Not the color data. - // I think the code here is *fine* because the point cloud structures are in-tact. - - // NB: This changes the point cloud geometry index. - // Flipping them changes where in the scene the geometry winds up, since the 1st-indexed - // geometry is given an offset. - //if i == 1 { continue } - //let i = 1 - j; - //let i = if swap { j } else { 1 - j }; // swaps physical location of the geometry - - // // NB: it's okay to copy an i32, but this sucks - // let point_cloud_texture_index = self.point_cloud_texture_indices.get(i).unwrap().clone(); - // gl::Uniform1i(point_cloud_texture_index, i as i32); - - // Bind our point cloud texture (which was written by the compute shader) - //gl::ActiveTexture(gl::TEXTURE0 + i as GLuint + 2); - //gl::ActiveTexture(gl::TEXTURE0); - - // - // THIS IS THE POINT CLOUD - // gl::BindTexture(gl::TEXTURE_2D, point_cloud_texture.id()); gl::BindImageTexture( - // https://www.khronos.org/opengl/wiki/Sampler_(GLSL) ? - i as GLuint, // image unit (zero-indexed) // TODO - why? why does it work this way? + i as GLuint, // image unit (zero-indexed) // TODO - why does it work this way? point_cloud_texture.id(), // texture 0, // level gl::FALSE, // layered @@ -541,19 +392,18 @@ impl PointCloudRenderer { gl::RGBA32F, //POINT_CLOUD_TEXTURE_FORMAT, ); - let vertex_attrib_location = self.vertex_attrib_locations.get(0).unwrap(); + gl::ActiveTexture(gl::TEXTURE0); - gl::EnableVertexAttribArray(*vertex_attrib_location as u32); + gl::EnableVertexAttribArray(self.color_vertex_attribute_location as u32); gl::VertexAttribPointer( - *vertex_attrib_location as u32, + self.color_vertex_attribute_location as u32, gl::BGRA as i32, gl::UNSIGNED_BYTE, gl::TRUE, 0 as i32, 0 as *const c_void, ); - } } @@ -570,13 +420,13 @@ impl PointCloudRenderer { /// pub fn render(&self) -> Result<()> { unsafe { + gl::UseProgram(self.shader_program_id); + gl::Enable(gl::DEPTH_TEST); gl::Enable(gl::BLEND); gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA); gl::PointSize(self.point_size as f32); - gl::UseProgram(self.shader_program_id); - // Update view/projection matrices in shader let typed_projection = self.projection_matrix.as_ptr() as *const GLfloat; gl::UniformMatrix4fv(self.projection_index, 1, gl::FALSE, typed_projection); @@ -590,91 +440,17 @@ impl PointCloudRenderer { gl::Uniform1i(self.enable_shading_index, enable_shading); - let time = SystemTime::now(); - let time_since_epoch = time.duration_since(UNIX_EPOCH).unwrap(); - let seconds = time_since_epoch.as_secs(); - - let (lower_range, upper_range)= if seconds % 10 > 4 { - (1, 2) - } else { - (0, 1) - }; - - //let (lower_range, upper_range) = (0, 2); - - // Experiment: Only draw camera0_color (toggles between setup above) - // First image: blank - // Second image: perfect camera0 - // Third image: ZEBRA STRIPED camera1_geo, camera0_color - let (lower_range, upper_range) = (0, 1); - - // Experiment: Only draw camera1_color (toggles between setup above) - // First image blank - // Second image: ZEBRA STRIPED camera1_geo + camera1_color - // Third image: BLACK camera0_geo - let (lower_range, upper_range) = (1, 2); - - - // Experiment: Only draw camera1_color (both are setup above) - // Only image: camera0_geo is present, but black; camera1_geo + camera1_color are perfect - let (lower_range, upper_range) = (1, 2); - - - // Experiment: Only draw camera0_color (both are setup above) - // Only image: camera0_geo + camera0_color are perfect; camera1_geo is present, but black - let (lower_range, upper_range) = (0, 1); - - - // Experiment: Draw camera0_color and camera1_color (both are setup above) - // SAME RESULTS, DAMN IT. - let (lower_range, upper_range) = (0, 2); - - // Render point cloud - //for i in 0 .. self.num_cameras { - /*for i in lower_range .. upper_range { - // - // THIS IS THE COLOR IMAGE - // - let vertex_array_object = self.vertex_array_objects.get(i).unwrap(); + for i in 0 .. self.num_cameras { + let vao = self.vertex_array_objects.get(i).unwrap(); let vertex_array_size_bytes = self.vertex_arrays_size_bytes.get(i).unwrap(); - - // NB: Interesting experiment / behavior: - // The following experiment cuts down on the geometry being drawn! Not just the color! - // I wonder if this changes the length of whatever feeds gl_VertexID? - // let vertex_array_size_bytes = vertex_array_size_bytes / 5; - - gl::BindVertexArray(vertex_array_object.id()); let size = vertex_array_size_bytes / size_of::() as i32; + vao.bind(); gl::DrawArrays(gl::POINTS, 0, size); + } - gl::BindVertexArray(0); - }*/ - - let vertex_array_object = self.vertex_array_objects.get(0).unwrap(); - let vertex_array_size_bytes = self.vertex_arrays_size_bytes.get(0).unwrap(); - let size = vertex_array_size_bytes / size_of::() as i32; - - gl::BindVertexArray(vertex_array_object.id()); - gl::DrawArrays(gl::POINTS, 0, size); gl::BindVertexArray(0); - - let vertex_array_object = self.vertex_array_objects.get(1).unwrap(); - let vertex_array_size_bytes = self.vertex_arrays_size_bytes.get(1).unwrap(); - let size = vertex_array_size_bytes / size_of::() as i32; - - gl::BindVertexArray(vertex_array_object.id()); - gl::DrawArrays(gl::POINTS, 0, size); - gl::BindVertexArray(0); - - /*for obj in self.renderable_objects.iter() { - gl::BindVertexArray(obj.vao); - gl::DrawArrays(gl::POINTS, 0, size); - gl::BindVertexArray(0); - }*/ - - gl_get_error() .map_err(|err| PointCloudRendererError::OpenGlError(err)) } @@ -688,3 +464,8 @@ impl PointCloudRenderer { self.enable_shading = enable_shading; } } + +// TODO: This is useful to write solid colors instead of webcam color data +// 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); + diff --git a/src/point_cloud/shaders/point_cloud_vertex_shader.glsl b/src/point_cloud/shaders/point_cloud_vertex_shader.glsl index 75e2bd6a4e..5b41830ea0 100644 --- a/src/point_cloud/shaders/point_cloud_vertex_shader.glsl +++ b/src/point_cloud/shaders/point_cloud_vertex_shader.glsl @@ -3,7 +3,7 @@ #version 430 // NB: It appears that locations need to be wide enough apart, or the colors bleed across locations. -layout(location=0) in vec4 inColor0; +layout(location=0) in vec4 inColor; //layout(location=10) in vec4 inColor1; // TODO: Get rid of this! out vec4 vertexColor; @@ -53,8 +53,8 @@ void main() colorOut = vec4( 127, - inColor0.g, - inColor0.b, + inColor.g, + inColor.b, 255 ); } else { @@ -75,8 +75,8 @@ void main() vertexPosition = imageLoad(pointCloudTexture1, currentDepthPixelCoordinates).xyz; colorOut = vec4( - inColor0.r, - inColor0.g, + inColor.r, + inColor.g, 127, 255 );