diff --git a/examples/custom_shader.rs b/examples/custom_shader.rs index b6016a9093..b7815857fc 100644 --- a/examples/custom_shader.rs +++ b/examples/custom_shader.rs @@ -10,16 +10,12 @@ struct MyMaterial { fn main() { App::build() .add_defaults() - .setup_render_graph(|builder, pipeline_storage, shader_storage| { - builder + .setup_render_graph(|render_graph_builder| { + render_graph_builder .add_resource_provider(UniformResourceProvider::::new()) - .add_pipeline_to_pass( - resource_name::pass::MAIN, - pipeline_storage, - PipelineDescriptor::build( - "MyMaterial", - shader_storage, - Shader::from_glsl( + .add_pipeline_to_pass(resource_name::pass::MAIN, "MyMaterial", |builder| { + builder + .with_vertex_shader(Shader::from_glsl( ShaderStage::Vertex, r#" #version 450 @@ -36,11 +32,10 @@ fn main() { gl_Position = ViewProj * v_Position; } "#, - ), - ) - .with_fragment_shader(Shader::from_glsl( - ShaderStage::Fragment, - r#" + )) + .with_fragment_shader(Shader::from_glsl( + ShaderStage::Fragment, + r#" #version 450 layout(location = 0) in vec4 v_Position; layout(location = 0) out vec4 o_Target; @@ -55,10 +50,9 @@ fn main() { # endif } "#, - )) - .with_standard_config() - .finish(), - ) + )) + .with_standard_config(); + }); }) .setup_world(setup) .run(); diff --git a/src/app/app_builder.rs b/src/app/app_builder.rs index 1c13cd94e7..e97abfdf50 100644 --- a/src/app/app_builder.rs +++ b/src/app/app_builder.rs @@ -14,7 +14,7 @@ use crate::{ use bevy_transform::{prelude::LocalToWorld, transform_system_bundle}; use pipeline::PipelineDescriptor; -use render_graph::RenderGraphBuilder; +use render_graph::{RenderGraph, RenderGraphBuilder}; use render_resource::{ AssetBatchers, EntityRenderResourceAssignments, RenderResourceAssignmentsProvider, }; @@ -22,11 +22,11 @@ use shader::Shader; use std::collections::HashMap; pub struct AppBuilder { - pub world: World, - pub resources: Resources, - pub universe: Universe, + pub world: Option, + pub resources: Option, + pub universe: Option, pub renderer: Option>, - pub render_graph_builder: RenderGraphBuilder, + pub render_graph: Option, pub setup_systems: Vec>, pub system_stages: HashMap>>, pub runnable_stages: HashMap>>, @@ -39,10 +39,10 @@ impl AppBuilder { let world = universe.create_world(); let resources = Resources::default(); AppBuilder { - universe, - world, - resources, - render_graph_builder: RenderGraphBuilder::new(), + universe: Some(universe), + world: Some(world), + resources: Some(resources), + render_graph: Some(RenderGraph::default()), renderer: None, setup_systems: Vec::new(), system_stages: HashMap::new(), @@ -51,14 +51,17 @@ impl AppBuilder { } } - pub fn build(mut self) -> App { + pub fn build(&mut self) -> App { let mut setup_schedule_builder = Schedule::builder(); - for setup_system in self.setup_systems { - setup_schedule_builder = setup_schedule_builder.add_system(setup_system); + for setup_system in self.setup_systems.drain(..) { + setup_schedule_builder = setup_schedule_builder.add_system(setup_system); } let mut setup_schedule = setup_schedule_builder.build(); - setup_schedule.execute(&mut self.world, &mut self.resources); + setup_schedule.execute( + self.world.as_mut().unwrap(), + self.resources.as_mut().unwrap(), + ); let mut schedule_builder = Schedule::builder(); for stage_name in self.stage_order.iter() { @@ -79,42 +82,51 @@ impl AppBuilder { } } - let render_graph = self.render_graph_builder.build(); - self.resources.insert(render_graph); + self.resources + .as_mut() + .unwrap() + .insert(self.render_graph.take().unwrap()); App::new( - self.universe, - self.world, + self.universe.take().unwrap(), + self.world.take().unwrap(), schedule_builder.build(), - self.resources, - self.renderer, + self.resources.take().unwrap(), + self.renderer.take(), ) } - pub fn run(self) { + pub fn run(&mut self) { self.build().run(); } - pub fn with_world(mut self, world: World) -> Self { - self.world = world; + pub fn with_world(&mut self, world: World) -> &mut Self { + self.world = Some(world); self } - pub fn setup_world(mut self, setup: impl Fn(&mut World, &mut Resources)) -> Self { - setup(&mut self.world, &mut self.resources); + pub fn setup_world(&mut self, setup: impl Fn(&mut World, &mut Resources)) -> &mut Self { + setup( + self.world.as_mut().unwrap(), + self.resources.as_mut().unwrap(), + ); self } - pub fn add_system(self, system: Box) -> Self { + pub fn add_system(&mut self, system: Box) -> &mut Self { self.add_system_to_stage(system_stage::UPDATE, system) } - pub fn add_setup_system(mut self, system: Box) -> Self { + pub fn add_setup_system(&mut self, system: Box) -> &mut Self { self.setup_systems.push(system); self } - pub fn add_system_to_stage(mut self, stage_name: &str, system: Box) -> Self { + pub fn add_system_to_stage( + &mut self, + stage_name: &str, + system: Box, + ) -> &mut Self { if let None = self.system_stages.get(stage_name) { self.system_stages .insert(stage_name.to_string(), Vec::new()); @@ -127,7 +139,11 @@ impl AppBuilder { self } - pub fn add_runnable_to_stage(mut self, stage_name: &str, system: Box) -> Self { + pub fn add_runnable_to_stage( + &mut self, + stage_name: &str, + system: Box, + ) -> &mut Self { if let None = self.runnable_stages.get(stage_name) { self.runnable_stages .insert(stage_name.to_string(), Vec::new()); @@ -140,38 +156,37 @@ impl AppBuilder { self } - pub fn add_default_resources(mut self) -> Self { + pub fn add_default_resources(&mut self) -> &mut Self { let mut asset_batchers = AssetBatchers::default(); asset_batchers.batch_types2::(); - self.resources.insert(Time::new()); - self.resources.insert(AssetStorage::::new()); - self.resources.insert(AssetStorage::::new()); - self.resources.insert(AssetStorage::::new()); - self.resources - .insert(AssetStorage::::new()); - self.resources - .insert(AssetStorage::::new()); - self.resources.insert(ShaderPipelineAssignments::new()); - self.resources.insert(CompiledShaderMap::new()); - self.resources - .insert(RenderResourceAssignmentsProvider::default()); - self.resources - .insert(EntityRenderResourceAssignments::default()); - self.resources.insert(asset_batchers); + let resources = self.resources.as_mut().unwrap(); + resources.insert(Time::new()); + resources.insert(AssetStorage::::new()); + resources.insert(AssetStorage::::new()); + resources.insert(AssetStorage::::new()); + resources.insert(AssetStorage::::new()); + resources.insert(AssetStorage::::new()); + resources.insert(ShaderPipelineAssignments::new()); + resources.insert(CompiledShaderMap::new()); + resources.insert(RenderResourceAssignmentsProvider::default()); + resources.insert(EntityRenderResourceAssignments::default()); + resources.insert(asset_batchers); self } - pub fn add_default_systems(mut self) -> Self { - self = self.add_system(ui::ui_update_system::build_ui_update_system()); - for transform_system in transform_system_bundle::build(&mut self.world).drain(..) { - self = self.add_system(transform_system); + pub fn add_default_systems(&mut self) -> &mut Self { + self.add_system(ui::ui_update_system::build_ui_update_system()); + for transform_system in + transform_system_bundle::build(self.world.as_mut().unwrap()).drain(..) + { + self.add_system(transform_system); } self } - pub fn add_render_graph_defaults(self) -> Self { - self.setup_render_graph(|builder, pipeline_storage, shader_storage| { + pub fn add_render_graph_defaults(&mut self) -> &mut Self { + self.setup_render_graph(|builder| { builder .add_draw_target(MeshesDrawTarget::default()) .add_draw_target(AssignedBatchesDrawTarget::default()) @@ -185,37 +200,31 @@ impl AppBuilder { .add_resource_provider(UniformResourceProvider::::new()) .add_resource_provider(UniformResourceProvider::::new()) .add_forward_pass() - .add_forward_pipeline(pipeline_storage, shader_storage) - .add_ui_pipeline(pipeline_storage, shader_storage) + .add_forward_pipeline() + .add_ui_pipeline(); }) } - pub fn setup_render_graph( - mut self, - setup: impl Fn( - RenderGraphBuilder, - &mut AssetStorage, - &mut AssetStorage, - ) -> RenderGraphBuilder, - ) -> Self { + pub fn setup_render_graph<'a>( + &'a mut self, + setup: impl Fn(&'_ mut RenderGraphBuilder<'_>), + ) -> &'a mut Self { { - let mut pipeline_storage = self - .resources - .get_mut::>() - .unwrap(); - let mut shader_storage = self.resources.get_mut::>().unwrap(); - self.render_graph_builder = setup( - self.render_graph_builder, - &mut pipeline_storage, - &mut shader_storage, - ); + let mut render_graph_builder = self + .render_graph + .take() + .unwrap() + .build(self.resources.as_mut().unwrap()); + setup(&mut render_graph_builder); + + self.render_graph = Some(render_graph_builder.finish()); } self } #[cfg(feature = "wgpu")] - pub fn add_wgpu_renderer(mut self) -> Self { + pub fn add_wgpu_renderer(&mut self) -> &mut Self { self.renderer = Some(Box::new( renderer::renderers::wgpu_renderer::WgpuRenderer::new(), )); @@ -223,20 +232,20 @@ impl AppBuilder { } #[cfg(not(feature = "wgpu"))] - fn add_wgpu_renderer(self) -> Self { + fn add_wgpu_renderer(&mut self) -> &mut Self { self } - pub fn add_defaults(self) -> Self { + pub fn add_defaults(&mut self) -> &mut Self { self.add_default_resources() .add_default_systems() .add_render_graph_defaults() .add_wgpu_renderer() } - pub fn load_plugin(mut self, path: &str) -> Self { + pub fn load_plugin(&mut self, path: &str) -> &mut Self { let (_lib, plugin) = load_plugin(path); - self = plugin.build(self); + plugin.build(self); self } } diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index a2f5e7b2fb..35b1791e92 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -3,7 +3,7 @@ use libloading::{Library, Symbol}; use std::any::Any; pub trait AppPlugin: Any + Send + Sync { - fn build(&self, app_builder: AppBuilder) -> AppBuilder; + fn build(&self, app_builder: &mut AppBuilder) -> &mut AppBuilder; fn name(&self) -> &'static str; } diff --git a/src/render/pass/passes/forward.rs b/src/render/pass/passes/forward.rs index 5b4eec75c4..e11dc3f8ba 100644 --- a/src/render/pass/passes/forward.rs +++ b/src/render/pass/passes/forward.rs @@ -10,11 +10,11 @@ use crate::render::{ }; pub trait ForwardPassBuilder { - fn add_forward_pass(self) -> Self; + fn add_forward_pass(&mut self) -> &mut Self; } -impl ForwardPassBuilder for RenderGraphBuilder { - fn add_forward_pass(self) -> Self { +impl<'a> ForwardPassBuilder for RenderGraphBuilder<'a> { + fn add_forward_pass(&mut self) -> &mut Self { self.add_resource_provider(FrameTextureResourceProvider::new( resource_name::texture::DEPTH, TextureDescriptor { diff --git a/src/render/pipeline/pipeline.rs b/src/render/pipeline/pipeline.rs index d31a75d56a..f54f631f80 100644 --- a/src/render/pipeline/pipeline.rs +++ b/src/render/pipeline/pipeline.rs @@ -108,64 +108,69 @@ impl PipelineDescriptor { impl PipelineDescriptor { pub fn build<'a>( - name: &str, + name: &'a str, shader_storage: &'a mut AssetStorage, - vertex_shader: Shader, ) -> PipelineBuilder<'a> { - PipelineBuilder::new(name, shader_storage, vertex_shader) + PipelineBuilder::new(name, shader_storage) } } pub struct PipelineBuilder<'a> { - pipeline: PipelineDescriptor, + pipeline: Option, shader_storage: &'a mut AssetStorage, + name: &'a str, } impl<'a> PipelineBuilder<'a> { pub fn new( - name: &str, + name: &'a str, shader_storage: &'a mut AssetStorage, - vertex_shader: Shader, ) -> Self { - let vertex_shader_handle = shader_storage.add(vertex_shader); PipelineBuilder { - pipeline: PipelineDescriptor::new(Some(name), vertex_shader_handle), + pipeline: None, shader_storage, + name, } } - pub fn finish(self) -> PipelineDescriptor { - self.pipeline + pub fn finish(&mut self) -> PipelineDescriptor { + self.pipeline.take().unwrap() } - pub fn with_fragment_shader(mut self, fragment_shader: Shader) -> Self { - let fragment_shader_handle = self.shader_storage.add(fragment_shader); - self.pipeline.shader_stages.fragment = Some(fragment_shader_handle); + pub fn with_vertex_shader(&mut self, vertex_shader: Shader) -> &mut Self { + let vertex_shader_handle = self.shader_storage.add(vertex_shader); + self.pipeline = Some(PipelineDescriptor::new(Some(&self.name), vertex_shader_handle)); self } - pub fn add_color_state(mut self, color_state_descriptor: ColorStateDescriptor) -> Self { - self.pipeline.color_states.push(color_state_descriptor); + pub fn with_fragment_shader(&mut self, fragment_shader: Shader) -> &mut Self { + let fragment_shader_handle = self.shader_storage.add(fragment_shader); + self.pipeline.as_mut().unwrap().shader_stages.fragment = Some(fragment_shader_handle); + self + } + + pub fn add_color_state(&mut self, color_state_descriptor: ColorStateDescriptor) -> &mut Self { + self.pipeline.as_mut().unwrap().color_states.push(color_state_descriptor); self } pub fn with_depth_stencil_state( - mut self, + &mut self, depth_stencil_state: DepthStencilStateDescriptor, - ) -> Self { - if let Some(_) = self.pipeline.depth_stencil_state { + ) -> &mut Self { + if let Some(_) = self.pipeline.as_ref().unwrap().depth_stencil_state { panic!("Depth stencil state has already been set"); } - self.pipeline.depth_stencil_state = Some(depth_stencil_state); + self.pipeline.as_mut().unwrap().depth_stencil_state = Some(depth_stencil_state); self } - pub fn add_bind_group(mut self, bind_group: BindGroup) -> Self { - if let PipelineLayoutType::Reflected(_) = self.pipeline.layout { - self.pipeline.layout = PipelineLayoutType::Manual(PipelineLayout::new()); + pub fn add_bind_group(&mut self, bind_group: BindGroup) -> &mut Self { + if let PipelineLayoutType::Reflected(_) = self.pipeline.as_ref().unwrap().layout { + self.pipeline.as_mut().unwrap().layout = PipelineLayoutType::Manual(PipelineLayout::new()); } - if let PipelineLayoutType::Manual(ref mut layout) = self.pipeline.layout { + if let PipelineLayoutType::Manual(ref mut layout) = self.pipeline.as_mut().unwrap().layout { layout.bind_groups.push(bind_group); } @@ -173,55 +178,55 @@ impl<'a> PipelineBuilder<'a> { } pub fn add_vertex_buffer_descriptor( - mut self, + &mut self, vertex_buffer_descriptor: VertexBufferDescriptor, - ) -> Self { - self.pipeline.reflect_vertex_buffer_descriptors = false; - self.pipeline + ) -> &mut Self { + self.pipeline.as_mut().unwrap().reflect_vertex_buffer_descriptors = false; + self.pipeline.as_mut().unwrap() .vertex_buffer_descriptors .push(vertex_buffer_descriptor); self } - pub fn with_index_format(mut self, index_format: IndexFormat) -> Self { - self.pipeline.index_format = index_format; + pub fn with_index_format(&mut self, index_format: IndexFormat) -> &mut Self { + self.pipeline.as_mut().unwrap().index_format = index_format; self } - pub fn add_draw_target(mut self, name: &str) -> Self { - self.pipeline.draw_targets.push(name.to_string()); + pub fn add_draw_target(&mut self, name: &str) -> &mut Self { + self.pipeline.as_mut().unwrap().draw_targets.push(name.to_string()); self } pub fn with_rasterization_state( - mut self, + &mut self, rasterization_state: RasterizationStateDescriptor, - ) -> Self { - self.pipeline.rasterization_state = Some(rasterization_state); + ) -> &mut Self { + self.pipeline.as_mut().unwrap().rasterization_state = Some(rasterization_state); self } - pub fn with_primitive_topology(mut self, primitive_topology: PrimitiveTopology) -> Self { - self.pipeline.primitive_topology = primitive_topology; + pub fn with_primitive_topology(&mut self, primitive_topology: PrimitiveTopology) -> &mut Self { + self.pipeline.as_mut().unwrap().primitive_topology = primitive_topology; self } - pub fn with_sample_count(mut self, sample_count: u32) -> Self { - self.pipeline.sample_count = sample_count; + pub fn with_sample_count(&mut self, sample_count: u32) -> &mut Self { + self.pipeline.as_mut().unwrap().sample_count = sample_count; self } - pub fn with_alpha_to_coverage_enabled(mut self, alpha_to_coverage_enabled: bool) -> Self { - self.pipeline.alpha_to_coverage_enabled = alpha_to_coverage_enabled; + pub fn with_alpha_to_coverage_enabled(&mut self, alpha_to_coverage_enabled: bool) -> &mut Self { + self.pipeline.as_mut().unwrap().alpha_to_coverage_enabled = alpha_to_coverage_enabled; self } - pub fn with_sample_mask(mut self, sample_mask: u32) -> Self { - self.pipeline.sample_mask = sample_mask; + pub fn with_sample_mask(&mut self, sample_mask: u32) -> &mut Self { + self.pipeline.as_mut().unwrap().sample_mask = sample_mask; self } - pub fn with_standard_config(self) -> Self { + pub fn with_standard_config(&mut self) -> &mut Self { self.with_depth_stencil_state(DepthStencilStateDescriptor { format: TextureFormat::Depth32Float, depth_write_enabled: true, diff --git a/src/render/pipeline/pipelines/forward/mod.rs b/src/render/pipeline/pipelines/forward/mod.rs index fdc6dab262..8de964e0ea 100644 --- a/src/render/pipeline/pipelines/forward/mod.rs +++ b/src/render/pipeline/pipelines/forward/mod.rs @@ -1,78 +1,62 @@ -use crate::{ - asset::AssetStorage, - render::{ - pipeline::{ - state_descriptors::{ - BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite, - CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, - RasterizationStateDescriptor, StencilStateFaceDescriptor, - }, - PipelineDescriptor, - }, - render_graph::RenderGraphBuilder, - render_resource::resource_name, - shader::{Shader, ShaderStage}, - texture::TextureFormat, +use crate::render::{ + pipeline::state_descriptors::{ + BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite, + CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, + RasterizationStateDescriptor, StencilStateFaceDescriptor, }, + render_graph::RenderGraphBuilder, + render_resource::resource_name, + shader::{Shader, ShaderStage}, + texture::TextureFormat, }; pub trait ForwardPipelineBuilder { - fn add_forward_pipeline( - self, - pipeline_descriptor_storage: &mut AssetStorage, - shader_storage: &mut AssetStorage, - ) -> Self; + fn add_forward_pipeline(&mut self) -> &mut Self; } -impl ForwardPipelineBuilder for RenderGraphBuilder { - fn add_forward_pipeline( - self, - pipeline_descriptor_storage: &mut AssetStorage, - shader_storage: &mut AssetStorage, - ) -> Self { - self.add_pipeline( - pipeline_descriptor_storage, - PipelineDescriptor::build( - resource_name::pipeline::FORWARD, - shader_storage, - Shader::from_glsl(ShaderStage::Vertex, include_str!("forward.vert")), - ) - .with_fragment_shader(Shader::from_glsl( - ShaderStage::Fragment, - include_str!("forward.frag"), - )) - .with_rasterization_state(RasterizationStateDescriptor { - front_face: FrontFace::Ccw, - cull_mode: CullMode::Back, - depth_bias: 0, - depth_bias_slope_scale: 0.0, - depth_bias_clamp: 0.0, - }) - .with_depth_stencil_state(DepthStencilStateDescriptor { - format: TextureFormat::Depth32Float, - depth_write_enabled: true, - depth_compare: CompareFunction::Less, - stencil_front: StencilStateFaceDescriptor::IGNORE, - stencil_back: StencilStateFaceDescriptor::IGNORE, - stencil_read_mask: 0, - stencil_write_mask: 0, - }) - .add_color_state(ColorStateDescriptor { - format: TextureFormat::Bgra8UnormSrgb, - color_blend: BlendDescriptor { - src_factor: BlendFactor::SrcAlpha, - dst_factor: BlendFactor::OneMinusSrcAlpha, - operation: BlendOperation::Add, - }, - alpha_blend: BlendDescriptor { - src_factor: BlendFactor::One, - dst_factor: BlendFactor::One, - operation: BlendOperation::Add, - }, - write_mask: ColorWrite::ALL, - }) - .add_draw_target(resource_name::draw_target::ASSIGNED_MESHES) - .add_draw_target(resource_name::draw_target::ASSIGNED_BATCHES) - .finish(), - ) +impl<'a> ForwardPipelineBuilder for RenderGraphBuilder<'a> { + fn add_forward_pipeline(&mut self) -> &mut Self { + self.add_pipeline(resource_name::pipeline::FORWARD, |builder| { + builder + .with_vertex_shader(Shader::from_glsl( + ShaderStage::Vertex, + include_str!("forward.vert"), + )) + .with_fragment_shader(Shader::from_glsl( + ShaderStage::Fragment, + include_str!("forward.frag"), + )) + .with_rasterization_state(RasterizationStateDescriptor { + front_face: FrontFace::Ccw, + cull_mode: CullMode::Back, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }) + .with_depth_stencil_state(DepthStencilStateDescriptor { + format: TextureFormat::Depth32Float, + depth_write_enabled: true, + depth_compare: CompareFunction::Less, + stencil_front: StencilStateFaceDescriptor::IGNORE, + stencil_back: StencilStateFaceDescriptor::IGNORE, + stencil_read_mask: 0, + stencil_write_mask: 0, + }) + .add_color_state(ColorStateDescriptor { + format: TextureFormat::Bgra8UnormSrgb, + color_blend: BlendDescriptor { + src_factor: BlendFactor::SrcAlpha, + dst_factor: BlendFactor::OneMinusSrcAlpha, + operation: BlendOperation::Add, + }, + alpha_blend: BlendDescriptor { + src_factor: BlendFactor::One, + dst_factor: BlendFactor::One, + operation: BlendOperation::Add, + }, + write_mask: ColorWrite::ALL, + }) + .add_draw_target(resource_name::draw_target::ASSIGNED_MESHES) + .add_draw_target(resource_name::draw_target::ASSIGNED_BATCHES); + }) } } diff --git a/src/render/pipeline/pipelines/forward_flat/mod.rs b/src/render/pipeline/pipelines/forward_flat/mod.rs index 351c489797..1d420cefe7 100644 --- a/src/render/pipeline/pipelines/forward_flat/mod.rs +++ b/src/render/pipeline/pipelines/forward_flat/mod.rs @@ -1,5 +1,4 @@ use crate::{ - asset::AssetStorage, render::{ pipeline::{ state_descriptors::{ @@ -7,7 +6,6 @@ use crate::{ DepthStencilStateDescriptor, FrontFace, RasterizationStateDescriptor, StencilStateFaceDescriptor, }, - PipelineDescriptor, }, render_graph::RenderGraphBuilder, render_resource::resource_name, @@ -17,54 +15,44 @@ use crate::{ }; pub trait ForwardFlatPipelineBuilder { - fn add_forward_flat_pipeline( - self, - pipeline_descriptor_storage: &mut AssetStorage, - shader_storage: &mut AssetStorage, - ) -> Self; + fn add_forward_flat_pipeline(&mut self) -> &mut Self; } -impl ForwardFlatPipelineBuilder for RenderGraphBuilder { - fn add_forward_flat_pipeline( - self, - pipeline_descriptor_storage: &mut AssetStorage, - shader_storage: &mut AssetStorage, - ) -> Self { - self.add_pipeline( - pipeline_descriptor_storage, - PipelineDescriptor::build( - resource_name::pipeline::FORWARD_FLAT, - shader_storage, - Shader::from_glsl(ShaderStage::Vertex, include_str!("forward_flat.vert")), - ) - .with_fragment_shader(Shader::from_glsl( - ShaderStage::Fragment, - include_str!("forward_flat.frag"), - )) - .with_rasterization_state(RasterizationStateDescriptor { - front_face: FrontFace::Ccw, - cull_mode: CullMode::Back, - depth_bias: 0, - depth_bias_slope_scale: 0.0, - depth_bias_clamp: 0.0, - }) - .with_depth_stencil_state(DepthStencilStateDescriptor { - format: TextureFormat::Depth32Float, - depth_write_enabled: true, - depth_compare: CompareFunction::Less, - stencil_front: StencilStateFaceDescriptor::IGNORE, - stencil_back: StencilStateFaceDescriptor::IGNORE, - stencil_read_mask: 0, - stencil_write_mask: 0, - }) - .add_color_state(ColorStateDescriptor { - format: TextureFormat::Bgra8UnormSrgb, - color_blend: BlendDescriptor::REPLACE, - alpha_blend: BlendDescriptor::REPLACE, - write_mask: ColorWrite::ALL, - }) - .add_draw_target(resource_name::draw_target::MESHES) - .finish(), - ) +impl<'a> ForwardFlatPipelineBuilder for RenderGraphBuilder<'a> { + fn add_forward_flat_pipeline(&mut self) -> &mut Self { + self.add_pipeline(resource_name::pipeline::FORWARD_FLAT, |builder| { + builder + .with_vertex_shader(Shader::from_glsl( + ShaderStage::Vertex, + include_str!("forward_flat.vert"), + )) + .with_fragment_shader(Shader::from_glsl( + ShaderStage::Fragment, + include_str!("forward_flat.frag"), + )) + .with_rasterization_state(RasterizationStateDescriptor { + front_face: FrontFace::Ccw, + cull_mode: CullMode::Back, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }) + .with_depth_stencil_state(DepthStencilStateDescriptor { + format: TextureFormat::Depth32Float, + depth_write_enabled: true, + depth_compare: CompareFunction::Less, + stencil_front: StencilStateFaceDescriptor::IGNORE, + stencil_back: StencilStateFaceDescriptor::IGNORE, + stencil_read_mask: 0, + stencil_write_mask: 0, + }) + .add_color_state(ColorStateDescriptor { + format: TextureFormat::Bgra8UnormSrgb, + color_blend: BlendDescriptor::REPLACE, + alpha_blend: BlendDescriptor::REPLACE, + write_mask: ColorWrite::ALL, + }) + .add_draw_target(resource_name::draw_target::MESHES); + }) } } diff --git a/src/render/pipeline/pipelines/ui/mod.rs b/src/render/pipeline/pipelines/ui/mod.rs index b8692a4d8f..4389347021 100644 --- a/src/render/pipeline/pipelines/ui/mod.rs +++ b/src/render/pipeline/pipelines/ui/mod.rs @@ -1,77 +1,61 @@ -use crate::{ - asset::AssetStorage, - render::{ - pipeline::{ - state_descriptors::{ - BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite, - CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, - RasterizationStateDescriptor, StencilStateFaceDescriptor, - }, - PipelineDescriptor, - }, - render_graph::RenderGraphBuilder, - render_resource::resource_name, - shader::{Shader, ShaderStage}, - texture::TextureFormat, +use crate::render::{ + pipeline::state_descriptors::{ + BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite, + CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, + RasterizationStateDescriptor, StencilStateFaceDescriptor, }, + render_graph::RenderGraphBuilder, + render_resource::resource_name, + shader::{Shader, ShaderStage}, + texture::TextureFormat, }; pub trait UiPipelineBuilder { - fn add_ui_pipeline( - self, - pipeline_descriptor_storage: &mut AssetStorage, - shader_storage: &mut AssetStorage, - ) -> Self; + fn add_ui_pipeline(&mut self) -> &mut Self; } -impl UiPipelineBuilder for RenderGraphBuilder { - fn add_ui_pipeline( - self, - pipeline_descriptor_storage: &mut AssetStorage, - shader_storage: &mut AssetStorage, - ) -> Self { - self.add_pipeline( - pipeline_descriptor_storage, - PipelineDescriptor::build( - resource_name::pipeline::UI, - shader_storage, - Shader::from_glsl(ShaderStage::Vertex, include_str!("ui.vert")), - ) - .with_fragment_shader(Shader::from_glsl( - ShaderStage::Fragment, - include_str!("ui.frag"), - )) - .with_rasterization_state(RasterizationStateDescriptor { - front_face: FrontFace::Ccw, - cull_mode: CullMode::None, - depth_bias: 0, - depth_bias_slope_scale: 0.0, - depth_bias_clamp: 0.0, - }) - .with_depth_stencil_state(DepthStencilStateDescriptor { - format: TextureFormat::Depth32Float, - depth_write_enabled: false, - depth_compare: CompareFunction::Always, - stencil_front: StencilStateFaceDescriptor::IGNORE, - stencil_back: StencilStateFaceDescriptor::IGNORE, - stencil_read_mask: 0, - stencil_write_mask: 0, - }) - .add_color_state(ColorStateDescriptor { - format: TextureFormat::Bgra8UnormSrgb, - color_blend: BlendDescriptor { - src_factor: BlendFactor::SrcAlpha, - dst_factor: BlendFactor::OneMinusSrcAlpha, - operation: BlendOperation::Add, - }, - alpha_blend: BlendDescriptor { - src_factor: BlendFactor::One, - dst_factor: BlendFactor::One, - operation: BlendOperation::Add, - }, - write_mask: ColorWrite::ALL, - }) - .add_draw_target(resource_name::draw_target::UI) - .finish(), - ) +impl<'a> UiPipelineBuilder for RenderGraphBuilder<'a> { + fn add_ui_pipeline(&mut self) -> &mut Self { + self.add_pipeline(resource_name::pipeline::UI, |builder| { + builder + .with_vertex_shader(Shader::from_glsl( + ShaderStage::Vertex, + include_str!("ui.vert"), + )) + .with_fragment_shader(Shader::from_glsl( + ShaderStage::Fragment, + include_str!("ui.frag"), + )) + .with_rasterization_state(RasterizationStateDescriptor { + front_face: FrontFace::Ccw, + cull_mode: CullMode::None, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }) + .with_depth_stencil_state(DepthStencilStateDescriptor { + format: TextureFormat::Depth32Float, + depth_write_enabled: false, + depth_compare: CompareFunction::Always, + stencil_front: StencilStateFaceDescriptor::IGNORE, + stencil_back: StencilStateFaceDescriptor::IGNORE, + stencil_read_mask: 0, + stencil_write_mask: 0, + }) + .add_color_state(ColorStateDescriptor { + format: TextureFormat::Bgra8UnormSrgb, + color_blend: BlendDescriptor { + src_factor: BlendFactor::SrcAlpha, + dst_factor: BlendFactor::OneMinusSrcAlpha, + operation: BlendOperation::Add, + }, + alpha_blend: BlendDescriptor { + src_factor: BlendFactor::One, + dst_factor: BlendFactor::One, + operation: BlendOperation::Add, + }, + write_mask: ColorWrite::ALL, + }) + .add_draw_target(resource_name::draw_target::UI); + }) } } diff --git a/src/render/render_graph/render_graph.rs b/src/render/render_graph/render_graph.rs index c35ebd0eb7..0fe41af673 100644 --- a/src/render/render_graph/render_graph.rs +++ b/src/render/render_graph/render_graph.rs @@ -1,5 +1,6 @@ use crate::{ asset::Handle, + prelude::Resources, render::{ draw_target::DrawTarget, pass::PassDescriptor, @@ -9,6 +10,7 @@ use crate::{ }, }; use std::collections::{HashMap, HashSet}; +use super::RenderGraphBuilder; #[derive(Default)] pub struct RenderGraph { @@ -23,6 +25,14 @@ pub struct RenderGraph { } impl RenderGraph { + pub fn build(self, resources: &mut Resources) -> RenderGraphBuilder { + RenderGraphBuilder { + resources, + current_pass: None, + render_graph: Some(self), + } + } + pub fn add_pipeline(&mut self, pass: &str, pipeline: Handle) { self.pipeline_descriptors.insert(pipeline.clone()); diff --git a/src/render/render_graph/render_graph_builder.rs b/src/render/render_graph/render_graph_builder.rs index 4e9c95ea45..d8a32a4f51 100644 --- a/src/render/render_graph/render_graph_builder.rs +++ b/src/render/render_graph/render_graph_builder.rs @@ -2,43 +2,41 @@ use super::RenderGraph; use crate::{ asset::AssetStorage, render::{ - draw_target::DrawTarget, pass::PassDescriptor, pipeline::PipelineDescriptor, + draw_target::DrawTarget, pass::PassDescriptor, pipeline::{PipelineBuilder, PipelineDescriptor}, render_resource::ResourceProvider, texture::TextureDescriptor, - }, + }, prelude::{Shader, Resources}, }; -pub struct RenderGraphBuilder { - render_graph: RenderGraph, - current_pass: Option, +pub struct RenderGraphBuilder<'a> { + pub render_graph: Option, + pub resources: &'a mut Resources, + pub current_pass: Option, } -impl RenderGraphBuilder { - pub fn new() -> Self { - RenderGraphBuilder { - render_graph: RenderGraph::default(), - current_pass: None, - } - } - - pub fn add_pass(mut self, name: &str, pass: PassDescriptor) -> Self { +impl<'a> RenderGraphBuilder<'a> { + pub fn add_pass(&mut self, name: &str, pass: PassDescriptor) -> &mut Self { self.current_pass = Some(name.to_string()); - self.render_graph + self.render_graph.as_mut().unwrap() .pass_descriptors .insert(name.to_string(), pass); self } pub fn add_pipeline( - mut self, - pipeline_descriptor_storage: &mut AssetStorage, - pipeline: PipelineDescriptor, - ) -> Self { + &mut self, + name: &str, + build: impl Fn(&mut PipelineBuilder), + ) -> &mut Self { + let mut pipeline_descriptor_storage = self.resources.get_mut::>().unwrap(); + let mut shader_storage = self.resources.get_mut::>().unwrap(); if let Some(ref pass) = self.current_pass { - let name = pipeline.name.clone(); + let mut builder = PipelineBuilder::new(name, &mut shader_storage); + build(&mut builder); + let pipeline = builder.finish(); let pipeline_descriptor_handle = pipeline_descriptor_storage.add(pipeline); pipeline_descriptor_storage - .set_name(name.unwrap().as_str(), pipeline_descriptor_handle); - self.render_graph + .set_name(name, pipeline_descriptor_handle); + self.render_graph.as_mut().unwrap() .add_pipeline(&pass, pipeline_descriptor_handle); } @@ -46,48 +44,52 @@ impl RenderGraphBuilder { } pub fn add_pipeline_to_pass( - mut self, + &mut self, pass: &str, - pipeline_descriptor_storage: &mut AssetStorage, - pipeline: PipelineDescriptor, - ) -> Self { - let name = pipeline.name.clone(); + name: &str, + build: impl Fn(&mut PipelineBuilder), + ) -> &mut Self { + let mut pipeline_descriptor_storage = self.resources.get_mut::>().unwrap(); + let mut shader_storage = self.resources.get_mut::>().unwrap(); + let mut builder = PipelineBuilder::new(name, &mut shader_storage); + build(&mut builder); + let pipeline = builder.finish(); let pipeline_descriptor_handle = pipeline_descriptor_storage.add(pipeline); - pipeline_descriptor_storage.set_name(name.unwrap().as_str(), pipeline_descriptor_handle); - self.render_graph + pipeline_descriptor_storage.set_name(name, pipeline_descriptor_handle); + self.render_graph.as_mut().unwrap() .add_pipeline(pass, pipeline_descriptor_handle); self } - pub fn add_resource_provider(mut self, resource_provider: T) -> Self + pub fn add_resource_provider(&mut self, resource_provider: T) -> &mut Self where T: ResourceProvider + Send + Sync + 'static, { - self.render_graph + self.render_graph.as_mut().unwrap() .resource_providers .push(Box::new(resource_provider)); self } - pub fn add_texture(mut self, name: &str, texture_descriptor: TextureDescriptor) -> Self { - self.render_graph + pub fn add_texture(&mut self, name: &str, texture_descriptor: TextureDescriptor) -> &mut Self { + self.render_graph.as_mut().unwrap() .queued_textures .push((name.to_string(), texture_descriptor)); self } - pub fn add_draw_target(mut self, draw_target: T) -> Self + pub fn add_draw_target(&mut self, draw_target: T) -> &mut Self where T: DrawTarget + Send + Sync + 'static, { - self.render_graph + self.render_graph.as_mut().unwrap() .draw_targets .insert(draw_target.get_name(), Box::new(draw_target)); self } - pub fn build(self) -> RenderGraph { - self.render_graph + pub fn finish(&mut self) -> RenderGraph { + self.render_graph.take().unwrap() } }