From e72ab7b00067d76cfea0d1b08e9f605a3e5ca959 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Sat, 23 May 2020 22:44:35 -0700 Subject: [PATCH] Draw commands are now built by a GuiNode traversing its children --- shaders/shader.frag | 4 ---- src/application.rs | 17 +++-------------- src/gui_node.rs | 19 +++++++++++++------ src/main.rs | 1 - src/window_uniform.rs | 18 ------------------ 5 files changed, 16 insertions(+), 43 deletions(-) delete mode 100644 src/window_uniform.rs diff --git a/shaders/shader.frag b/shaders/shader.frag index 0b49372a..329fc409 100644 --- a/shaders/shader.frag +++ b/shaders/shader.frag @@ -18,10 +18,6 @@ layout(set=0, binding=0) uniform GuiNodeUniform { }; layout(set=0, binding=1) uniform sampler2D t_texture; -// layout(set=1, binding=0) uniform WindowUniform { -// Dimensions_u32 window_dimensions; -// }; - void main() { f_color = fill_color * texture(t_texture, v_uv / textureSize(t_texture, 0) * 100); } diff --git a/src/application.rs b/src/application.rs index fdfaedd4..d1a1ad70 100644 --- a/src/application.rs +++ b/src/application.rs @@ -68,12 +68,7 @@ impl Application { // Temporary setup below, TODO: move to appropriate place in architecture - // Window uniform bind group layout - // let window_binding_types = vec![wgpu::BindingType::UniformBuffer { dynamic: false }]; - // let window_bind_group_layout = Pipeline::build_bind_group_layout(&device, &window_binding_types); - // Data structure maintaining the user interface - // let extra_layouts = vec![&window_bind_group_layout]; let gui_rect_pipeline = Pipeline::new(&device, swap_chain_descriptor.format, vec![], &mut shader_cache, ("shaders/shader.vert", "shaders/shader.frag")); pipeline_cache.set("gui_rect", gui_rect_pipeline); @@ -137,14 +132,8 @@ impl Application { // Generates a render pass that commands are applied to, then generates a command buffer when finished let mut command_encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Render Encoder") }); - // Build an array of draw commands - let mut nodes = vec![self.gui_root.borrow_mut()]; // TODO: Generate the DrawCommands as a list by recursively traversing the gui node tree - let mut commands = Vec::::with_capacity(nodes.len()); - for i in 0..nodes.len() { - let pipeline_name = nodes[i].get_pipeline_name(); - let pipeline = self.pipeline_cache.get(&pipeline_name[..]).unwrap(); - commands.push(nodes[i].build_draw_command(&mut self.device, &mut self.queue, pipeline, &mut self.texture_cache)); - } + // Build an array of draw commands by traversing the GUI element tree + let commands = GuiNode::build_draw_commands_recursive(&self.gui_root, &self.device, &mut self.queue, &self.pipeline_cache, &mut self.texture_cache); // Recording of commands while in "rendering mode" that go into a command buffer let mut render_pass = command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { @@ -159,7 +148,7 @@ impl Application { ], depth_stencil_attachment: None, }); - + // Prepare a variable to reuse the pipeline based on its name let mut pipeline_name = String::new(); diff --git a/src/gui_node.rs b/src/gui_node.rs index 5d25b2f7..bc0bd03f 100644 --- a/src/gui_node.rs +++ b/src/gui_node.rs @@ -7,21 +7,28 @@ use crate::gui_attributes::*; pub struct GuiNode { pub form_factor: GuiNodeUniform, + pub pipeline_name: String, } impl GuiNode { pub fn new(width: u32, height: u32, color: Color) -> Self { Self { form_factor: GuiNodeUniform::new(width, height, color), + pipeline_name: String::from("gui_rect"), } } - // pub fn get_pipeline(&self, pipeline_cache: &ResourceCache) -> &Pipeline { - // pipeline_cache.get("gui_rect").unwrap() - // } + pub fn build_draw_commands_recursive(node: &rctree::Node, device: &wgpu::Device, queue: &mut wgpu::Queue, pipeline_cache: &ResourceCache, texture_cache: &mut ResourceCache) -> Vec { + let mut draw_commands: Vec = Vec::new(); - pub fn get_pipeline_name(&self) -> String { - String::from("gui_rect") + for mut subnode in node.descendants() { + let mut subnode_data = subnode.borrow_mut(); + let pipeline = pipeline_cache.get(&subnode_data.pipeline_name[..]).unwrap(); + let command = subnode_data.build_draw_command(device, queue, pipeline, texture_cache); + draw_commands.push(command); + } + + draw_commands } pub fn build_draw_command(&mut self, device: &wgpu::Device, queue: &mut wgpu::Queue, pipeline: &Pipeline, texture_cache: &mut ResourceCache) -> DrawCommand { @@ -39,7 +46,7 @@ impl GuiNode { let bind_groups = self.build_bind_groups(device, queue, pipeline, texture_cache); // Create a draw command with the vertex data then push it to the GPU command queue - DrawCommand::new(device, self.get_pipeline_name(), bind_groups, VERTICES, INDICES) + DrawCommand::new(device, self.pipeline_name.clone(), bind_groups, VERTICES, INDICES) } pub fn build_bind_groups(&mut self, device: &wgpu::Device, queue: &mut wgpu::Queue, pipeline: &Pipeline, texture_cache: &mut ResourceCache) -> Vec { diff --git a/src/main.rs b/src/main.rs index 1b717619..6d692dff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,6 @@ mod draw_command; mod gui_node; mod gui_attributes; mod window_events; -mod window_uniform; use application::Application; use winit::event_loop::EventLoop; diff --git a/src/window_uniform.rs b/src/window_uniform.rs deleted file mode 100644 index 69c3cc11..00000000 --- a/src/window_uniform.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::gui_attributes::*; - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct WindowUniform { - pub dimensions: Dimensions, -} - -impl WindowUniform { - pub fn new(width: u32, height: u32) -> Self { - Self { - dimensions: Dimensions::new(width, height), - } - } -} - -unsafe impl bytemuck::Zeroable for WindowUniform {} -unsafe impl bytemuck::Pod for WindowUniform {}