mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 14:10:19 +00:00
everything is a plugin
... well almost everything
This commit is contained in:
parent
5db5f6de9c
commit
ec84a33b43
29 changed files with 331 additions and 289 deletions
|
@ -1,5 +1,9 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::build().add_defaults().setup(setup).run();
|
||||
}
|
||||
|
||||
#[derive(Uniforms, Default)]
|
||||
struct MyMaterial {
|
||||
pub color: Color,
|
||||
|
@ -7,58 +11,54 @@ struct MyMaterial {
|
|||
pub always_red: bool,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
App::build()
|
||||
.add_defaults()
|
||||
.setup_render_graph(|render_graph_builder| {
|
||||
render_graph_builder
|
||||
.add_resource_provider(UniformResourceProvider::<MyMaterial>::new(true))
|
||||
.add_pipeline_to_pass(resource_name::pass::MAIN, "MyMaterial", |builder| {
|
||||
builder
|
||||
.with_vertex_shader(Shader::from_glsl(
|
||||
ShaderStage::Vertex,
|
||||
r#"
|
||||
#version 450
|
||||
layout(location = 0) in vec4 Vertex_Position;
|
||||
layout(location = 0) out vec4 v_Position;
|
||||
layout(set = 0, binding = 0) uniform Camera {
|
||||
mat4 ViewProj;
|
||||
};
|
||||
layout(set = 1, binding = 0) uniform Object {
|
||||
mat4 Model;
|
||||
};
|
||||
void main() {
|
||||
v_Position = Model * Vertex_Position;
|
||||
gl_Position = ViewProj * v_Position;
|
||||
}
|
||||
"#,
|
||||
))
|
||||
.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;
|
||||
layout(set = 1, binding = 1) uniform MyMaterial_color {
|
||||
vec4 color;
|
||||
};
|
||||
void main() {
|
||||
o_Target = color;
|
||||
|
||||
# ifdef MYMATERIAL_ALWAYS_RED
|
||||
o_Target = vec4(0.8, 0.0, 0.0, 1.0);
|
||||
# endif
|
||||
}
|
||||
"#,
|
||||
))
|
||||
.with_default_config();
|
||||
});
|
||||
})
|
||||
.setup_world(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
fn setup(world: &mut World, resources: &mut Resources) {
|
||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||
let mut pipelines = resources.get_mut::<AssetStorage<PipelineDescriptor>>().unwrap();
|
||||
let mut shaders = resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
||||
render_graph
|
||||
.build(&mut pipelines, &mut shaders)
|
||||
.add_resource_provider(UniformResourceProvider::<MyMaterial>::new(true))
|
||||
.add_pipeline_to_pass(resource_name::pass::MAIN, "MyMaterial", |builder| {
|
||||
builder
|
||||
.with_vertex_shader(Shader::from_glsl(
|
||||
ShaderStage::Vertex,
|
||||
r#"
|
||||
#version 450
|
||||
layout(location = 0) in vec4 Vertex_Position;
|
||||
layout(location = 0) out vec4 v_Position;
|
||||
layout(set = 0, binding = 0) uniform Camera {
|
||||
mat4 ViewProj;
|
||||
};
|
||||
layout(set = 1, binding = 0) uniform Object {
|
||||
mat4 Model;
|
||||
};
|
||||
void main() {
|
||||
v_Position = Model * Vertex_Position;
|
||||
gl_Position = ViewProj * v_Position;
|
||||
}
|
||||
"#,
|
||||
))
|
||||
.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;
|
||||
layout(set = 1, binding = 1) uniform MyMaterial_color {
|
||||
vec4 color;
|
||||
};
|
||||
void main() {
|
||||
o_Target = color;
|
||||
|
||||
# ifdef MYMATERIAL_ALWAYS_RED
|
||||
o_Target = vec4(0.8, 0.0, 0.0, 1.0);
|
||||
# endif
|
||||
}
|
||||
"#,
|
||||
))
|
||||
.with_default_config();
|
||||
});
|
||||
|
||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::build().add_defaults().setup_world(setup).run();
|
||||
App::build().add_defaults().setup(setup).run();
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
|
|
@ -5,9 +5,11 @@ fn main() {
|
|||
App::build()
|
||||
.add_defaults()
|
||||
.add_system(build_move_system())
|
||||
.add_default_diagnostics()
|
||||
.print_diagnostics()
|
||||
.setup_world(setup)
|
||||
.add_plugin(DiagnosticsPlugin {
|
||||
print_diagnostics: true,
|
||||
..Default::default()
|
||||
})
|
||||
.setup(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ struct Wander {
|
|||
|
||||
fn main() {
|
||||
App::build()
|
||||
.setup_world(setup)
|
||||
.setup(setup)
|
||||
.add_system(build_wander_system())
|
||||
.add_system(build_navigate_system())
|
||||
.add_system(build_move_system())
|
||||
|
|
|
@ -5,7 +5,7 @@ struct Rotator;
|
|||
fn main() {
|
||||
App::build()
|
||||
.add_defaults()
|
||||
.setup_world(setup)
|
||||
.setup(setup)
|
||||
.add_system(build_rotator_system())
|
||||
.run();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ pub struct ExamplePlugin;
|
|||
|
||||
impl AppPlugin for ExamplePlugin {
|
||||
fn build(&self, app_builder: AppBuilder) -> AppBuilder {
|
||||
app_builder.setup_world(setup)
|
||||
app_builder.setup(setup)
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
|
@ -2,7 +2,7 @@ use bevy::{prelude::*, serialization::*};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use type_uuid::TypeUuid;
|
||||
fn main() {
|
||||
let app = App::build().add_defaults().setup_world(setup).build();
|
||||
let app = App::build().add_defaults().setup(setup).build();
|
||||
|
||||
let comp_registrations = [ComponentRegistration::of::<Test>()];
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::build().add_defaults().setup_world(setup).run();
|
||||
App::build().add_defaults().setup(setup).run();
|
||||
}
|
||||
|
||||
fn setup(world: &mut World, resources: &mut Resources) {
|
||||
|
|
|
@ -5,9 +5,11 @@ fn main() {
|
|||
App::build()
|
||||
.add_defaults()
|
||||
.add_system(build_move_system())
|
||||
.add_default_diagnostics()
|
||||
.print_diagnostics()
|
||||
.setup_world(setup)
|
||||
.add_plugin(DiagnosticsPlugin {
|
||||
print_diagnostics: true,
|
||||
..Default::default()
|
||||
})
|
||||
.setup(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::build().add_defaults().setup_world(setup).run();
|
||||
App::build().add_defaults().setup(setup).run();
|
||||
}
|
||||
|
||||
fn setup(world: &mut World, resources: &mut Resources) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::build().add_defaults().setup_world(setup).run();
|
||||
App::build().add_defaults().setup(setup).run();
|
||||
}
|
||||
|
||||
fn setup(world: &mut World, resources: &mut Resources) {
|
||||
|
|
|
@ -3,10 +3,12 @@ use bevy::prelude::*;
|
|||
fn main() {
|
||||
App::build()
|
||||
.add_defaults()
|
||||
.setup_world(setup)
|
||||
.setup(setup)
|
||||
.add_system(build_move_system())
|
||||
.add_default_diagnostics()
|
||||
.print_diagnostics()
|
||||
.add_plugin(DiagnosticsPlugin {
|
||||
print_diagnostics: true,
|
||||
..Default::default()
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ impl App {
|
|||
pub fn new(
|
||||
universe: Universe,
|
||||
world: World,
|
||||
schedule: Schedule,
|
||||
resources: Resources,
|
||||
schedule: Schedule,
|
||||
run: Option<Box<dyn Fn(App)>>,
|
||||
renderer: Option<Box<dyn Renderer>>,
|
||||
) -> App {
|
||||
|
|
|
@ -1,35 +1,22 @@
|
|||
use crate::{
|
||||
app::{system_stage, App},
|
||||
asset::*,
|
||||
core::{window::winit::get_winit_run, Time, Window},
|
||||
diagnostic::{diagnostics, Diagnostics},
|
||||
core::{window::winit::get_winit_run, CorePlugin},
|
||||
legion::prelude::{Resources, Runnable, Schedulable, Schedule, Universe, World},
|
||||
plugin::load_plugin,
|
||||
prelude::StandardMaterial,
|
||||
render::{
|
||||
draw_target::draw_targets::*, mesh::Mesh, pass::passes::*, pipeline::pipelines::*,
|
||||
render_resource::resource_providers::*, renderer::Renderer, texture::Texture, *,
|
||||
},
|
||||
plugin::{load_plugin, AppPlugin},
|
||||
render::{renderer::Renderer, *},
|
||||
ui,
|
||||
};
|
||||
|
||||
use bevy_transform::{prelude::LocalToWorld, transform_system_bundle};
|
||||
use pipeline::{PipelineCompiler, PipelineDescriptor, ShaderPipelineAssignments};
|
||||
use render_graph::{RenderGraph, RenderGraphBuilder};
|
||||
use render_resource::{
|
||||
build_entity_render_resource_assignments_system, AssetBatchers,
|
||||
EntityRenderResourceAssignments, RenderResourceAssignments,
|
||||
};
|
||||
use shader::Shader;
|
||||
use std::{collections::HashMap, time::Duration};
|
||||
use bevy_transform::transform_system_bundle;
|
||||
use render_resource::build_entity_render_resource_assignments_system;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct AppBuilder {
|
||||
pub world: Option<World>,
|
||||
pub resources: Option<Resources>,
|
||||
pub universe: Option<Universe>,
|
||||
pub world: World,
|
||||
pub resources: Resources,
|
||||
pub universe: Universe,
|
||||
pub renderer: Option<Box<dyn Renderer>>,
|
||||
pub run: Option<Box<dyn Fn(App)>>,
|
||||
pub render_graph: Option<RenderGraph>,
|
||||
pub setup_systems: Vec<Box<dyn Schedulable>>,
|
||||
pub system_stages: HashMap<String, Vec<Box<dyn Schedulable>>>,
|
||||
pub runnable_stages: HashMap<String, Vec<Box<dyn Runnable>>>,
|
||||
|
@ -42,10 +29,9 @@ impl AppBuilder {
|
|||
let world = universe.create_world();
|
||||
let resources = Resources::default();
|
||||
AppBuilder {
|
||||
universe: Some(universe),
|
||||
world: Some(world),
|
||||
resources: Some(resources),
|
||||
render_graph: Some(RenderGraph::default()),
|
||||
universe,
|
||||
world,
|
||||
resources,
|
||||
renderer: None,
|
||||
run: None,
|
||||
setup_systems: Vec::new(),
|
||||
|
@ -55,17 +41,14 @@ 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.drain(..) {
|
||||
setup_schedule_builder = setup_schedule_builder.add_system(setup_system);
|
||||
}
|
||||
|
||||
let mut setup_schedule = setup_schedule_builder.build();
|
||||
setup_schedule.execute(
|
||||
self.world.as_mut().unwrap(),
|
||||
self.resources.as_mut().unwrap(),
|
||||
);
|
||||
setup_schedule.execute(&mut self.world, &mut self.resources);
|
||||
|
||||
let mut schedule_builder = Schedule::builder();
|
||||
for stage_name in self.stage_order.iter() {
|
||||
|
@ -86,52 +69,40 @@ impl AppBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
self.resources
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.insert(self.render_graph.take().unwrap());
|
||||
|
||||
App::new(
|
||||
self.universe.take().unwrap(),
|
||||
self.world.take().unwrap(),
|
||||
self.universe,
|
||||
self.world,
|
||||
self.resources,
|
||||
schedule_builder.build(),
|
||||
self.resources.take().unwrap(),
|
||||
self.run.take(),
|
||||
self.renderer.take(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
pub fn run(self) {
|
||||
self.build().run();
|
||||
}
|
||||
|
||||
pub fn with_world(&mut self, world: World) -> &mut Self {
|
||||
self.world = Some(world);
|
||||
pub fn with_world(mut self, world: World) -> Self {
|
||||
self.world = world;
|
||||
self
|
||||
}
|
||||
|
||||
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(),
|
||||
);
|
||||
pub fn setup(mut self, setup: impl Fn(&mut World, &mut Resources)) -> Self {
|
||||
setup(&mut self.world, &mut self.resources);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_system(&mut self, system: Box<dyn Schedulable>) -> &mut Self {
|
||||
pub fn add_system(self, system: Box<dyn Schedulable>) -> Self {
|
||||
self.add_system_to_stage(system_stage::UPDATE, system)
|
||||
}
|
||||
|
||||
pub fn add_setup_system(&mut self, system: Box<dyn Schedulable>) -> &mut Self {
|
||||
pub fn add_setup_system(mut self, system: Box<dyn Schedulable>) -> Self {
|
||||
self.setup_systems.push(system);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_system_to_stage(
|
||||
&mut self,
|
||||
stage_name: &str,
|
||||
system: Box<dyn Schedulable>,
|
||||
) -> &mut Self {
|
||||
pub fn add_system_to_stage(mut self, stage_name: &str, system: Box<dyn Schedulable>) -> Self {
|
||||
if let None = self.system_stages.get(stage_name) {
|
||||
self.system_stages
|
||||
.insert(stage_name.to_string(), Vec::new());
|
||||
|
@ -144,11 +115,7 @@ impl AppBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_runnable_to_stage(
|
||||
&mut self,
|
||||
stage_name: &str,
|
||||
system: Box<dyn Runnable>,
|
||||
) -> &mut Self {
|
||||
pub fn add_runnable_to_stage(mut self, stage_name: &str, system: Box<dyn Runnable>) -> Self {
|
||||
if let None = self.runnable_stages.get(stage_name) {
|
||||
self.runnable_stages
|
||||
.insert(stage_name.to_string(), Vec::new());
|
||||
|
@ -161,111 +128,27 @@ impl AppBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_default_resources(&mut self) -> &mut Self {
|
||||
let resources = self.resources.as_mut().unwrap();
|
||||
resources.insert(Window::default());
|
||||
resources.insert(Time::new());
|
||||
resources.insert(Diagnostics::default());
|
||||
resources.insert(AssetStorage::<Mesh>::new());
|
||||
resources.insert(AssetStorage::<Texture>::new());
|
||||
resources.insert(AssetStorage::<Shader>::new());
|
||||
resources.insert(AssetStorage::<StandardMaterial>::new());
|
||||
resources.insert(AssetStorage::<PipelineDescriptor>::new());
|
||||
resources.insert(ShaderPipelineAssignments::new());
|
||||
resources.insert(PipelineCompiler::new());
|
||||
resources.insert(RenderResourceAssignments::default());
|
||||
resources.insert(EntityRenderResourceAssignments::default());
|
||||
self.batch_types2::<Mesh, StandardMaterial>();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_default_diagnostics(&mut self) -> &mut Self {
|
||||
let frame_time_diagnostic_system = {
|
||||
let resources = self.resources.as_mut().unwrap();
|
||||
diagnostics::frame_time_diagnostic_system(resources, 10)
|
||||
};
|
||||
self.add_system(frame_time_diagnostic_system)
|
||||
}
|
||||
|
||||
pub fn print_diagnostics(&mut self) -> &mut Self {
|
||||
self.add_system(diagnostics::print_diagnostics_system(
|
||||
Duration::from_secs_f64(1.0),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn print_diagnostics_with_wait(&mut self, wait: Duration) -> &mut Self {
|
||||
self.add_system(diagnostics::print_diagnostics_system(wait))
|
||||
}
|
||||
|
||||
pub fn batch_types2<T1, T2>(&mut self) -> &mut Self
|
||||
pub fn add_resource<T>(mut self, resource: T) -> Self
|
||||
where
|
||||
T1: 'static,
|
||||
T2: 'static,
|
||||
T: Send + Sync + 'static,
|
||||
{
|
||||
{
|
||||
let resources = self.resources.as_mut().unwrap();
|
||||
let mut asset_batchers = resources
|
||||
.get_mut_or_insert_with(|| AssetBatchers::default())
|
||||
.unwrap();
|
||||
|
||||
asset_batchers.batch_types2::<T1, T2>();
|
||||
}
|
||||
|
||||
self.resources.insert(resource);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_default_systems(&mut self) -> &mut Self {
|
||||
self.add_system(build_entity_render_resource_assignments_system());
|
||||
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(&mut self) -> &mut Self {
|
||||
self.setup_render_graph(|builder| {
|
||||
builder
|
||||
.add_draw_target(MeshesDrawTarget::default())
|
||||
.add_draw_target(AssignedBatchesDrawTarget::default())
|
||||
.add_draw_target(AssignedMeshesDrawTarget::default())
|
||||
.add_draw_target(UiDrawTarget::default())
|
||||
.add_resource_provider(CameraResourceProvider::default())
|
||||
.add_resource_provider(Camera2dResourceProvider::default())
|
||||
.add_resource_provider(LightResourceProvider::new(10))
|
||||
.add_resource_provider(UiResourceProvider::new())
|
||||
.add_resource_provider(MeshResourceProvider::new())
|
||||
.add_resource_provider(UniformResourceProvider::<StandardMaterial>::new(true))
|
||||
.add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true))
|
||||
.add_forward_pass()
|
||||
.add_forward_pipeline();
|
||||
// .add_ui_pipeline();
|
||||
})
|
||||
}
|
||||
|
||||
pub fn setup_render_graph<'a>(
|
||||
&'a mut self,
|
||||
setup: impl Fn(&'_ mut RenderGraphBuilder<'_>),
|
||||
) -> &'a mut Self {
|
||||
{
|
||||
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());
|
||||
pub fn add_default_systems(mut self) -> Self {
|
||||
self = self
|
||||
.add_system(build_entity_render_resource_assignments_system())
|
||||
.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);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "wgpu")]
|
||||
pub fn add_wgpu_renderer(&mut self) -> &mut Self {
|
||||
pub fn add_wgpu_renderer(mut self) -> Self {
|
||||
self.renderer = Some(Box::new(
|
||||
renderer::renderers::wgpu_renderer::WgpuRenderer::new(),
|
||||
));
|
||||
|
@ -273,32 +156,42 @@ impl AppBuilder {
|
|||
}
|
||||
|
||||
#[cfg(not(feature = "wgpu"))]
|
||||
fn add_wgpu_renderer(&mut self) -> &mut Self {
|
||||
fn add_wgpu_renderer(mut self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "winit")]
|
||||
pub fn add_winit(&mut self) -> &mut Self {
|
||||
pub fn add_winit(mut self) -> Self {
|
||||
self.run = Some(get_winit_run());
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "winit"))]
|
||||
pub fn add_winit(&mut self) -> &mut Self {
|
||||
pub fn add_winit(mut self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_defaults(&mut self) -> &mut Self {
|
||||
self.add_winit()
|
||||
.add_default_resources()
|
||||
pub fn add_defaults(mut self) -> Self {
|
||||
self = self
|
||||
.add_winit()
|
||||
.add_default_systems()
|
||||
.add_render_graph_defaults()
|
||||
.add_wgpu_renderer()
|
||||
.add_plugin(CorePlugin::default())
|
||||
.add_plugin(RenderPlugin::default())
|
||||
.add_wgpu_renderer();
|
||||
#[cfg(feature = "winit")]
|
||||
{}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn load_plugin(&mut self, path: &str) -> &mut Self {
|
||||
pub fn load_plugin(self, path: &str) -> Self {
|
||||
let (_lib, plugin) = load_plugin(path);
|
||||
plugin.build(self);
|
||||
self
|
||||
plugin.build(self)
|
||||
}
|
||||
|
||||
pub fn add_plugin<T>(self, plugin: T) -> Self
|
||||
where
|
||||
T: AppPlugin,
|
||||
{
|
||||
plugin.build(self)
|
||||
}
|
||||
}
|
||||
|
|
15
src/core/core_plugin.rs
Normal file
15
src/core/core_plugin.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use super::{Time, Window};
|
||||
use crate::{app::AppBuilder, plugin::AppPlugin};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CorePlugin;
|
||||
|
||||
impl AppPlugin for CorePlugin {
|
||||
fn build(&self, app: AppBuilder) -> AppBuilder {
|
||||
app.add_resource(Window::default())
|
||||
.add_resource(Time::new())
|
||||
}
|
||||
fn name(&self) -> &'static str {
|
||||
"Core"
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
pub mod bytes;
|
||||
pub mod time;
|
||||
pub mod window;
|
||||
mod core_plugin;
|
||||
|
||||
pub use bytes::GetBytes;
|
||||
pub use time::Time;
|
||||
pub use window::Window;
|
||||
pub use core_plugin::*;
|
||||
|
|
43
src/diagnostic/diagnostic_plugin.rs
Normal file
43
src/diagnostic/diagnostic_plugin.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use super::{
|
||||
diagnostics::{frame_time_diagnostic_system, print_diagnostics_system},
|
||||
Diagnostics,
|
||||
};
|
||||
use crate::{app::AppBuilder, plugin::AppPlugin};
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct DiagnosticsPlugin {
|
||||
pub print_wait_duration: Duration,
|
||||
pub print_diagnostics: bool,
|
||||
pub add_defaults: bool,
|
||||
}
|
||||
|
||||
impl Default for DiagnosticsPlugin {
|
||||
fn default() -> Self {
|
||||
DiagnosticsPlugin {
|
||||
print_wait_duration: Duration::from_secs_f64(1.0),
|
||||
print_diagnostics: false,
|
||||
add_defaults: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AppPlugin for DiagnosticsPlugin {
|
||||
fn build(&self, mut app: AppBuilder) -> AppBuilder {
|
||||
app = app.add_resource(Diagnostics::default());
|
||||
if self.add_defaults {
|
||||
let frame_time_diagnostic_system = {
|
||||
frame_time_diagnostic_system(&mut app.resources, 10)
|
||||
};
|
||||
app = app.add_system(frame_time_diagnostic_system)
|
||||
}
|
||||
|
||||
if self.print_diagnostics {
|
||||
app = app.add_system(print_diagnostics_system(self.print_wait_duration));
|
||||
}
|
||||
|
||||
app
|
||||
}
|
||||
fn name(&self) -> &'static str {
|
||||
"Diagnostics"
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
pub mod diagnostics;
|
||||
mod diagnostic_plugin;
|
||||
pub use diagnostic_plugin::*;
|
||||
|
||||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
|
|
|
@ -3,7 +3,7 @@ use libloading::{Library, Symbol};
|
|||
use std::any::Any;
|
||||
|
||||
pub trait AppPlugin: Any + Send + Sync {
|
||||
fn build(&self, app_builder: &mut AppBuilder) -> &mut AppBuilder;
|
||||
fn build(&self, app: AppBuilder) -> AppBuilder;
|
||||
fn name(&self) -> &'static str;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,13 @@ pub use crate::{
|
|||
mesh::{Mesh, MeshType},
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{resource_name, resource_providers::UniformResourceProvider},
|
||||
render_graph::RenderGraph,
|
||||
shader::{uniforms::StandardMaterial, Shader, ShaderDefSuffixProvider, ShaderStage},
|
||||
texture::{Texture, TextureType},
|
||||
ActiveCamera, ActiveCamera2d, Camera, CameraType, Color, ColorSource, Light, Renderable,
|
||||
},
|
||||
ui::{Anchors, Margins, Node},
|
||||
diagnostic::DiagnosticsPlugin,
|
||||
};
|
||||
pub use bevy_derive::*;
|
||||
pub use bevy_transform::prelude::*;
|
||||
|
|
|
@ -2,6 +2,7 @@ mod camera;
|
|||
pub mod mesh;
|
||||
pub mod render_graph;
|
||||
pub mod shader;
|
||||
mod render_plugin;
|
||||
|
||||
mod color;
|
||||
mod light;
|
||||
|
@ -11,6 +12,7 @@ pub use camera::*;
|
|||
pub use color::*;
|
||||
pub use light::*;
|
||||
pub use renderable::*;
|
||||
pub use render_plugin::*;
|
||||
|
||||
pub use vertex::Vertex;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ pub trait ForwardPassBuilder {
|
|||
fn add_forward_pass(&mut self) -> &mut Self;
|
||||
}
|
||||
|
||||
impl<'a> ForwardPassBuilder for RenderGraphBuilder<'a> {
|
||||
impl<'a, 'b, 'c> ForwardPassBuilder for RenderGraphBuilder<'a, 'b, 'c> {
|
||||
fn add_forward_pass(&mut self) -> &mut Self {
|
||||
self.add_resource_provider(FrameTextureResourceProvider::new(
|
||||
resource_name::texture::DEPTH,
|
||||
|
|
|
@ -13,7 +13,7 @@ pub trait ForwardPipelineBuilder {
|
|||
fn add_forward_pipeline(&mut self) -> &mut Self;
|
||||
}
|
||||
|
||||
impl<'a> ForwardPipelineBuilder for RenderGraphBuilder<'a> {
|
||||
impl<'a, 'b, 'c> ForwardPipelineBuilder for RenderGraphBuilder<'a, 'b, 'c> {
|
||||
fn add_forward_pipeline(&mut self) -> &mut Self {
|
||||
self.add_pipeline(resource_name::pipeline::FORWARD, |builder| {
|
||||
builder
|
||||
|
|
|
@ -14,7 +14,7 @@ pub trait ForwardFlatPipelineBuilder {
|
|||
fn add_forward_flat_pipeline(&mut self) -> &mut Self;
|
||||
}
|
||||
|
||||
impl<'a> ForwardFlatPipelineBuilder for RenderGraphBuilder<'a> {
|
||||
impl<'a, 'b, 'c> ForwardFlatPipelineBuilder for RenderGraphBuilder<'a, 'b, 'c> {
|
||||
fn add_forward_flat_pipeline(&mut self) -> &mut Self {
|
||||
self.add_pipeline(resource_name::pipeline::FORWARD_FLAT, |builder| {
|
||||
builder
|
||||
|
|
|
@ -13,7 +13,7 @@ pub trait UiPipelineBuilder {
|
|||
fn add_ui_pipeline(&mut self) -> &mut Self;
|
||||
}
|
||||
|
||||
impl<'a> UiPipelineBuilder for RenderGraphBuilder<'a> {
|
||||
impl<'a, 'b, 'c> UiPipelineBuilder for RenderGraphBuilder<'a, 'b, 'c> {
|
||||
fn add_ui_pipeline(&mut self) -> &mut Self {
|
||||
self.add_pipeline(resource_name::pipeline::UI, |builder| {
|
||||
builder
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::RenderGraphBuilder;
|
||||
use crate::{
|
||||
asset::Handle,
|
||||
prelude::Resources,
|
||||
asset::{AssetStorage, Handle},
|
||||
prelude::Shader,
|
||||
render::{
|
||||
draw_target::DrawTarget,
|
||||
pass::PassDescriptor,
|
||||
|
@ -25,11 +25,16 @@ pub struct RenderGraph {
|
|||
}
|
||||
|
||||
impl RenderGraph {
|
||||
pub fn build(self, resources: &mut Resources) -> RenderGraphBuilder {
|
||||
pub fn build<'a, 'b, 'c>(
|
||||
&'c mut self,
|
||||
pipelines: &'a mut AssetStorage<PipelineDescriptor>,
|
||||
shaders: &'b mut AssetStorage<Shader>,
|
||||
) -> RenderGraphBuilder<'a, 'b, 'c> {
|
||||
RenderGraphBuilder {
|
||||
resources,
|
||||
pipelines,
|
||||
shaders,
|
||||
current_pass: None,
|
||||
render_graph: Some(self),
|
||||
render_graph: self,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::RenderGraph;
|
||||
use crate::{
|
||||
asset::AssetStorage,
|
||||
prelude::{Resources, Shader},
|
||||
prelude::Shader,
|
||||
render::{
|
||||
draw_target::DrawTarget,
|
||||
pass::PassDescriptor,
|
||||
|
@ -11,18 +11,17 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
pub struct RenderGraphBuilder<'a> {
|
||||
pub render_graph: Option<RenderGraph>,
|
||||
pub resources: &'a mut Resources,
|
||||
pub struct RenderGraphBuilder<'a, 'b, 'c> {
|
||||
pub pipelines: &'a mut AssetStorage<PipelineDescriptor>,
|
||||
pub shaders: &'b mut AssetStorage<Shader>,
|
||||
pub render_graph: &'c mut RenderGraph,
|
||||
pub current_pass: Option<String>,
|
||||
}
|
||||
|
||||
impl<'a> RenderGraphBuilder<'a> {
|
||||
impl<'a, 'b, 'c> RenderGraphBuilder<'a, 'b, 'c> {
|
||||
pub fn add_pass(&mut self, name: &str, pass: PassDescriptor) -> &mut Self {
|
||||
self.current_pass = Some(name.to_string());
|
||||
self.render_graph
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.pass_descriptors
|
||||
.insert(name.to_string(), pass);
|
||||
self
|
||||
|
@ -30,19 +29,12 @@ impl<'a> RenderGraphBuilder<'a> {
|
|||
|
||||
pub fn add_pipeline(&mut self, name: &str, build: impl Fn(&mut PipelineBuilder)) -> &mut Self {
|
||||
if let Some(ref pass) = self.current_pass {
|
||||
let mut pipeline_descriptor_storage = self
|
||||
.resources
|
||||
.get_mut::<AssetStorage<PipelineDescriptor>>()
|
||||
.unwrap();
|
||||
let mut shader_storage = self.resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
||||
let mut builder = PipelineBuilder::new(name, &mut shader_storage);
|
||||
let mut builder = PipelineBuilder::new(name, &mut self.shaders);
|
||||
build(&mut builder);
|
||||
let pipeline = builder.finish();
|
||||
let pipeline_descriptor_handle = pipeline_descriptor_storage.add(pipeline);
|
||||
pipeline_descriptor_storage.set_name(name, pipeline_descriptor_handle);
|
||||
let pipeline_descriptor_handle = self.pipelines.add(pipeline);
|
||||
self.pipelines.set_name(name, pipeline_descriptor_handle);
|
||||
self.render_graph
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.add_pipeline(&pass, pipeline_descriptor_handle);
|
||||
}
|
||||
|
||||
|
@ -56,19 +48,12 @@ impl<'a> RenderGraphBuilder<'a> {
|
|||
build: impl Fn(&mut PipelineBuilder),
|
||||
) -> &mut Self {
|
||||
{
|
||||
let mut pipeline_descriptor_storage = self
|
||||
.resources
|
||||
.get_mut::<AssetStorage<PipelineDescriptor>>()
|
||||
.unwrap();
|
||||
let mut shader_storage = self.resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
||||
let mut builder = PipelineBuilder::new(name, &mut shader_storage);
|
||||
let mut builder = PipelineBuilder::new(name, &mut self.shaders);
|
||||
build(&mut builder);
|
||||
let pipeline = builder.finish();
|
||||
let pipeline_descriptor_handle = pipeline_descriptor_storage.add(pipeline);
|
||||
pipeline_descriptor_storage.set_name(name, pipeline_descriptor_handle);
|
||||
let pipeline_descriptor_handle = self.pipelines.add(pipeline);
|
||||
self.pipelines.set_name(name, pipeline_descriptor_handle);
|
||||
self.render_graph
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.add_pipeline(pass, pipeline_descriptor_handle);
|
||||
}
|
||||
|
||||
|
@ -80,8 +65,6 @@ impl<'a> RenderGraphBuilder<'a> {
|
|||
T: ResourceProvider + Send + Sync + 'static,
|
||||
{
|
||||
self.render_graph
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.resource_providers
|
||||
.push(Box::new(resource_provider));
|
||||
self
|
||||
|
@ -89,8 +72,6 @@ impl<'a> RenderGraphBuilder<'a> {
|
|||
|
||||
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
|
||||
|
@ -101,14 +82,8 @@ impl<'a> RenderGraphBuilder<'a> {
|
|||
T: DrawTarget + Send + Sync + 'static,
|
||||
{
|
||||
self.render_graph
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.draw_targets
|
||||
.insert(draw_target.get_name(), Box::new(draw_target));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn finish(&mut self) -> RenderGraph {
|
||||
self.render_graph.take().unwrap()
|
||||
}
|
||||
}
|
||||
|
|
78
src/render/render_plugin.rs
Normal file
78
src/render/render_plugin.rs
Normal file
|
@ -0,0 +1,78 @@
|
|||
use super::{
|
||||
draw_target::draw_targets::{
|
||||
AssignedBatchesDrawTarget, AssignedMeshesDrawTarget, MeshesDrawTarget, UiDrawTarget,
|
||||
},
|
||||
pass::passes::ForwardPassBuilder,
|
||||
pipeline::{pipelines::ForwardPipelineBuilder, PipelineCompiler, ShaderPipelineAssignments},
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{
|
||||
resource_providers::{
|
||||
Camera2dResourceProvider, CameraResourceProvider, LightResourceProvider,
|
||||
MeshResourceProvider, UiResourceProvider,
|
||||
},
|
||||
AssetBatchers, EntityRenderResourceAssignments, RenderResourceAssignments,
|
||||
},
|
||||
};
|
||||
use crate::{
|
||||
app::AppBuilder,
|
||||
asset::AssetStorage,
|
||||
plugin::AppPlugin,
|
||||
prelude::{
|
||||
LocalToWorld, Mesh, PipelineDescriptor, Shader, StandardMaterial, Texture,
|
||||
UniformResourceProvider,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RenderPlugin;
|
||||
|
||||
impl RenderPlugin {
|
||||
pub fn setup_render_graph_defaults(app: &mut AppBuilder) {
|
||||
let mut pipelines = app
|
||||
.resources
|
||||
.get_mut::<AssetStorage<PipelineDescriptor>>()
|
||||
.unwrap();
|
||||
let mut shaders = app.resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
||||
let mut render_graph = app.resources.get_mut::<RenderGraph>().unwrap();
|
||||
render_graph
|
||||
.build(&mut pipelines, &mut shaders)
|
||||
.add_draw_target(MeshesDrawTarget::default())
|
||||
.add_draw_target(AssignedBatchesDrawTarget::default())
|
||||
.add_draw_target(AssignedMeshesDrawTarget::default())
|
||||
.add_draw_target(UiDrawTarget::default())
|
||||
.add_resource_provider(CameraResourceProvider::default())
|
||||
.add_resource_provider(Camera2dResourceProvider::default())
|
||||
.add_resource_provider(LightResourceProvider::new(10))
|
||||
.add_resource_provider(UiResourceProvider::new())
|
||||
.add_resource_provider(MeshResourceProvider::new())
|
||||
.add_resource_provider(UniformResourceProvider::<StandardMaterial>::new(true))
|
||||
.add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true))
|
||||
.add_forward_pass()
|
||||
.add_forward_pipeline();
|
||||
}
|
||||
}
|
||||
|
||||
impl AppPlugin for RenderPlugin {
|
||||
fn build(&self, mut app: AppBuilder) -> AppBuilder {
|
||||
let mut asset_batchers = AssetBatchers::default();
|
||||
asset_batchers.batch_types2::<Mesh, StandardMaterial>();
|
||||
app = app
|
||||
.add_resource(RenderGraph::default())
|
||||
.add_resource(AssetStorage::<Mesh>::new())
|
||||
.add_resource(AssetStorage::<Texture>::new())
|
||||
.add_resource(AssetStorage::<Shader>::new())
|
||||
.add_resource(AssetStorage::<StandardMaterial>::new())
|
||||
.add_resource(AssetStorage::<PipelineDescriptor>::new())
|
||||
.add_resource(ShaderPipelineAssignments::new())
|
||||
.add_resource(PipelineCompiler::new())
|
||||
.add_resource(RenderResourceAssignments::default())
|
||||
.add_resource(EntityRenderResourceAssignments::default())
|
||||
.add_resource(asset_batchers);
|
||||
RenderPlugin::setup_render_graph_defaults(&mut app);
|
||||
app
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"Render"
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
use super::{WgpuRenderer, WgpuResources};
|
||||
use crate::render::{
|
||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
||||
render_resource::{RenderResource, RenderResourceAssignments, ResourceInfo, RenderResourceSetId},
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{
|
||||
RenderResource, RenderResourceAssignments, RenderResourceSetId, ResourceInfo,
|
||||
},
|
||||
renderer::{RenderPass, Renderer},
|
||||
};
|
||||
use std::{collections::HashMap, ops::Range};
|
||||
|
@ -11,7 +13,7 @@ pub struct WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
pub pipeline_descriptor: &'c PipelineDescriptor,
|
||||
pub wgpu_resources: &'a WgpuResources,
|
||||
pub renderer: &'d WgpuRenderer,
|
||||
pub bound_bind_groups: HashMap<u32, (RenderResourceSetId)>,
|
||||
pub bound_bind_groups: HashMap<u32, RenderResourceSetId>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
||||
|
@ -53,10 +55,19 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
if let Some((vertex_buffer, index_buffer)) =
|
||||
render_resource_assignments.get_vertex_buffer(&vertex_buffer_descriptor.name)
|
||||
{
|
||||
log::trace!("set vertex buffer {}: {} ({:?})", i, vertex_buffer_descriptor.name, vertex_buffer);
|
||||
log::trace!(
|
||||
"set vertex buffer {}: {} ({:?})",
|
||||
i,
|
||||
vertex_buffer_descriptor.name,
|
||||
vertex_buffer
|
||||
);
|
||||
self.set_vertex_buffer(i as u32, vertex_buffer, 0);
|
||||
if let Some(index_buffer) = index_buffer {
|
||||
log::trace!("set index buffer: {} ({:?})", vertex_buffer_descriptor.name, index_buffer);
|
||||
log::trace!(
|
||||
"set index buffer: {} ({:?})",
|
||||
vertex_buffer_descriptor.name,
|
||||
index_buffer
|
||||
);
|
||||
self.set_index_buffer(index_buffer, 0);
|
||||
match self.renderer.get_resource_info(index_buffer).unwrap() {
|
||||
ResourceInfo::Buffer(buffer_info) => {
|
||||
|
@ -86,8 +97,11 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
|
||||
// don't bind bind groups if they are already set
|
||||
// TODO: these checks come at a performance cost. make sure its worth it!
|
||||
if let Some(bound_render_resource_set) = self.bound_bind_groups.get(&bind_group.index) {
|
||||
if *bound_render_resource_set == *render_resource_set_id && dynamic_uniform_indices.len() == 0
|
||||
if let Some(bound_render_resource_set) =
|
||||
self.bound_bind_groups.get(&bind_group.index)
|
||||
{
|
||||
if *bound_render_resource_set == *render_resource_set_id
|
||||
&& dynamic_uniform_indices.len() == 0
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -99,8 +113,13 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
} else {
|
||||
self.bound_bind_groups.remove(&bind_group.index);
|
||||
}
|
||||
|
||||
log::trace!("set bind group {} {:?}: {:?}", bind_group.index, dynamic_uniform_indices, render_resource_set_id);
|
||||
|
||||
log::trace!(
|
||||
"set bind group {} {:?}: {:?}",
|
||||
bind_group.index,
|
||||
dynamic_uniform_indices,
|
||||
render_resource_set_id
|
||||
);
|
||||
self.render_pass.set_bind_group(
|
||||
bind_group.index,
|
||||
&wgpu_bind_group,
|
||||
|
|
Loading…
Reference in a new issue