mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 12:13:25 +00:00
wander spawner
This commit is contained in:
parent
21ce87ba45
commit
816d0c9bdd
8 changed files with 279 additions and 73 deletions
|
@ -13,4 +13,5 @@ winit = "0.20.0-alpha4"
|
|||
glsl-to-spirv = "0.1"
|
||||
zerocopy = "0.2"
|
||||
log = "0.4"
|
||||
env_logger = "0.7"
|
||||
env_logger = "0.7"
|
||||
rand = "0.7.2"
|
|
@ -1,28 +1,149 @@
|
|||
use bevy::*;
|
||||
use bevy::{render::*, asset::{Asset, AssetStorage}, math};
|
||||
use bevy::{render::*, asset::{Asset, AssetStorage, Handle}, math, Schedulable};
|
||||
use rand::{rngs::StdRng, Rng, SeedableRng, random};
|
||||
|
||||
// fn build_move_system() -> Box<dyn Scheduleable> {
|
||||
// SystemBuilder::new("MoveSystem")
|
||||
// .with_query(<>)
|
||||
// }
|
||||
fn build_wander_system(world: &mut World) -> Box<dyn Schedulable> {
|
||||
let mut rng = StdRng::from_entropy();
|
||||
|
||||
SystemBuilder::new("Wander")
|
||||
.read_resource::<Time>()
|
||||
.with_query(<(
|
||||
Read<Person>,
|
||||
Read<Translation>,
|
||||
Write<Wander>,
|
||||
Write<NavigationPoint>,
|
||||
)>::query())
|
||||
.build(move |_, world, time , person_query| {
|
||||
for (_, translation, mut wander, mut navigation_point) in person_query.iter(world) {
|
||||
wander.elapsed += time.delta_seconds;
|
||||
if wander.elapsed >= wander.duration {
|
||||
let direction = math::vec3(
|
||||
rng.gen_range(-1.0, 1.0),
|
||||
rng.gen_range(-1.0, 1.0),
|
||||
rng.gen_range(0.0, 0.001),
|
||||
).normalize();
|
||||
let distance = rng.gen_range(wander.distance_bounds.x, wander.distance_bounds.y);
|
||||
navigation_point.target = translation.vector + direction * distance;
|
||||
wander.elapsed = 0.0;
|
||||
wander.duration = rng.gen_range(wander.duration_bounds.x, wander.duration_bounds.y);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn build_navigate_system(world: &mut World) -> Box<dyn Schedulable> {
|
||||
SystemBuilder::new("Navigate")
|
||||
.with_query(<(
|
||||
Read<Person>,
|
||||
Write<Translation>,
|
||||
Write<Velocity>,
|
||||
Write<NavigationPoint>,
|
||||
)>::query())
|
||||
.build(move |_, world, _, person_query| {
|
||||
for (_, mut translation, mut velocity, mut navigation_point) in person_query.iter(world) {
|
||||
let distance = navigation_point.target - translation.vector;
|
||||
if math::length(&distance) > 0.01 {
|
||||
let direction = distance.normalize();
|
||||
velocity.value = direction * 2.0;
|
||||
} else {
|
||||
velocity.value = math::vec3(0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn build_move_system(world: &mut World) -> Box<dyn Schedulable> {
|
||||
SystemBuilder::new("Move")
|
||||
.read_resource::<Time>()
|
||||
.with_query(<(
|
||||
Write<Translation>,
|
||||
Read<Velocity>,
|
||||
)>::query())
|
||||
.build(move |_, world, time , person_query| {
|
||||
for (mut translation, velocity) in person_query.iter(world) {
|
||||
translation.vector += velocity.value * time.delta_seconds;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn build_print_status_system(world: &mut World) -> Box<dyn Schedulable> {
|
||||
let mut elapsed = 0.0;
|
||||
SystemBuilder::new("PrintStatus")
|
||||
.read_resource::<Time>()
|
||||
.with_query(<(
|
||||
Read<Person>,
|
||||
)>::query())
|
||||
.build(move |_, world, time , person_query| {
|
||||
elapsed += time.delta_seconds;
|
||||
if elapsed > 1.0 {
|
||||
println!("fps: {}", if time.delta_seconds == 0.0 { 0.0 } else { 1.0 / time.delta_seconds });
|
||||
println!("peeps: {}", person_query.iter(world).count());
|
||||
elapsed = 0.0;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn build_spawner_system(world: &mut World) -> Box<dyn Schedulable> {
|
||||
let mesh_handle = {
|
||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh, MeshType>>().unwrap();
|
||||
mesh_storage.get_named("cube").unwrap()
|
||||
};
|
||||
let mut elapsed = 0.0;
|
||||
SystemBuilder::new("Spawner")
|
||||
.read_resource::<Time>()
|
||||
.with_query(<(
|
||||
Read<Person>,
|
||||
)>::query())
|
||||
.build(move |command_buffer, world, time , person_query| {
|
||||
elapsed += time.delta_seconds;
|
||||
if elapsed > 0.5 {
|
||||
for i in 0..20 {
|
||||
spawn_person(command_buffer, mesh_handle.clone());
|
||||
}
|
||||
elapsed = 0.0;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
struct Person {
|
||||
}
|
||||
|
||||
struct Velocity {
|
||||
pub value: math::Vec3,
|
||||
}
|
||||
|
||||
struct NavigationPoint {
|
||||
pub target: math::Vec3,
|
||||
}
|
||||
|
||||
struct Wander {
|
||||
pub duration_bounds: math::Vec2,
|
||||
pub distance_bounds: math::Vec2,
|
||||
pub duration: f32,
|
||||
pub elapsed: f32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let universe = Universe::new();
|
||||
let mut world = universe.create_world();
|
||||
let mut scheduler = SystemScheduler::<ApplicationStage>::new();
|
||||
let transform_system_bundle = transform_system_bundle::build(&mut world);
|
||||
scheduler.add_systems(ApplicationStage::Update, transform_system_bundle);
|
||||
// Create a query which finds all `Position` and `Velocity` components
|
||||
// let mut query = Read::<Transform>::query();
|
||||
|
||||
let cube = Mesh::load(MeshType::Cube);
|
||||
let plane = Mesh::load(MeshType::Plane{ size: 10 });
|
||||
let plane = Mesh::load(MeshType::Plane{ size: 25 });
|
||||
let mut mesh_storage = AssetStorage::<Mesh, MeshType>::new();
|
||||
|
||||
// this currently breaks because Arcs cant be modified after they are cloned :(
|
||||
let mesh_handle = mesh_storage.add(cube);
|
||||
let plane_handle = mesh_storage.add(plane);
|
||||
let mesh_handle = mesh_storage.add(cube, "cube");
|
||||
let plane_handle = mesh_storage.add(plane, "plane");
|
||||
world.resources.insert(mesh_storage);
|
||||
|
||||
let transform_system_bundle = transform_system_bundle::build(&mut world);
|
||||
scheduler.add_systems(ApplicationStage::Update, transform_system_bundle);
|
||||
scheduler.add_system(ApplicationStage::Update, build_wander_system(&mut world));
|
||||
scheduler.add_system(ApplicationStage::Update, build_navigate_system(&mut world));
|
||||
scheduler.add_system(ApplicationStage::Update, build_move_system(&mut world));
|
||||
scheduler.add_system(ApplicationStage::Update, build_spawner_system(&mut world));
|
||||
scheduler.add_system(ApplicationStage::Update, build_print_status_system(&mut world));
|
||||
|
||||
world.insert((), vec![
|
||||
// plane
|
||||
(
|
||||
|
@ -31,20 +152,8 @@ fn main() {
|
|||
LocalToWorld::identity(),
|
||||
Translation::new(0.0, 0.0, 0.0)
|
||||
),
|
||||
// cubes
|
||||
(
|
||||
Material::new(math::vec4(0.1, 0.1, 0.6, 1.0)),
|
||||
mesh_handle.clone(),
|
||||
LocalToWorld::identity(),
|
||||
Translation::new(1.5, 0.0, 1.0)
|
||||
),
|
||||
(
|
||||
Material::new(math::vec4(0.6, 0.1, 0.1, 1.0)),
|
||||
mesh_handle,
|
||||
LocalToWorld::identity(),
|
||||
Translation::new(-1.5, 0.0, 1.0)
|
||||
),
|
||||
]);
|
||||
|
||||
world.insert((), vec![
|
||||
// lights
|
||||
(
|
||||
|
@ -80,6 +189,7 @@ fn main() {
|
|||
Translation::new(-5.0, 7.0, 10.0)
|
||||
),
|
||||
]);
|
||||
|
||||
world.insert((), vec![
|
||||
// camera
|
||||
(
|
||||
|
@ -90,7 +200,7 @@ fn main() {
|
|||
aspect_ratio: 1.0,
|
||||
}),
|
||||
LocalToWorld(math::look_at_rh(
|
||||
&math::vec3(3.0, -10.0, 6.0),
|
||||
&math::vec3(6.0, -40.0, 20.0),
|
||||
&math::vec3(0.0, 0.0, 0.0),
|
||||
&math::vec3(0.0, 0.0, 1.0),)),
|
||||
// Translation::new(0.0, 0.0, 0.0),
|
||||
|
@ -98,4 +208,29 @@ fn main() {
|
|||
]);
|
||||
|
||||
Application::run(universe, world, scheduler);
|
||||
}
|
||||
|
||||
|
||||
fn spawn_person(command_buffer: &mut CommandBuffer, mesh_handle: Handle<Mesh>) {
|
||||
command_buffer.insert((), vec![
|
||||
(
|
||||
Person{},
|
||||
Wander {
|
||||
duration_bounds: math::vec2(3.0, 10.0),
|
||||
distance_bounds: math::vec2(-50.0, 50.0),
|
||||
elapsed: 0.0,
|
||||
duration: 0.0,
|
||||
},
|
||||
NavigationPoint {
|
||||
target: math::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
Velocity {
|
||||
value: math::vec3(0.0, 0.0, 0.0),
|
||||
},
|
||||
Material::new(math::vec4(0.5, 0.3, 0.3, 1.0) * random::<f32>()),
|
||||
mesh_handle.clone(),
|
||||
LocalToWorld::identity(),
|
||||
Translation::new(0.0, 0.0, 1.0)
|
||||
),
|
||||
]);
|
||||
}
|
|
@ -9,11 +9,12 @@ use zerocopy::AsBytes;
|
|||
use legion::prelude::*;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::rc::Rc;
|
||||
use std::mem;
|
||||
|
||||
use wgpu::{Surface, Device, Queue, SwapChain, SwapChainDescriptor};
|
||||
|
||||
use crate::{vertex::*, render::*, math, LocalToWorld, ApplicationStage};
|
||||
use crate::{vertex::*, render::*, math, LocalToWorld, ApplicationStage, Time};
|
||||
|
||||
pub struct Application
|
||||
{
|
||||
|
@ -37,13 +38,13 @@ impl Application {
|
|||
(Self::MAX_LIGHTS * mem::size_of::<LightRaw>()) as wgpu::BufferAddress;
|
||||
|
||||
let local_bind_group_layout =
|
||||
self.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
Rc::new(self.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: &[wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
|
||||
}],
|
||||
});
|
||||
}));
|
||||
|
||||
let light_uniform_buffer = Arc::new(UniformBuffer {
|
||||
buffer: self.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
|
@ -55,29 +56,6 @@ impl Application {
|
|||
size: light_uniform_size,
|
||||
});
|
||||
|
||||
let mut materials = <Write<Material>>::query();
|
||||
for mut material in materials.iter(&mut self.world) {
|
||||
let entity_uniform_size = mem::size_of::<MaterialUniforms>() as wgpu::BufferAddress;
|
||||
let uniform_buf = self.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: entity_uniform_size,
|
||||
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||
});
|
||||
|
||||
let bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
layout: &local_bind_group_layout,
|
||||
bindings: &[wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &uniform_buf,
|
||||
range: 0 .. entity_uniform_size,
|
||||
},
|
||||
}],
|
||||
});
|
||||
|
||||
material.bind_group = Some(bind_group);
|
||||
material.uniform_buf = Some(uniform_buf);
|
||||
}
|
||||
|
||||
let light_count = <Read<Light>>::query().iter(&mut self.world).count();
|
||||
let forward_uniforms = ForwardUniforms {
|
||||
proj: math::Mat4::identity().into(),
|
||||
|
@ -103,12 +81,25 @@ impl Application {
|
|||
],
|
||||
};
|
||||
|
||||
let shadow_pass = ShadowPass::new(&mut self.device, &mut self.world, light_uniform_buffer.clone(), vb_desc.clone(), &local_bind_group_layout, Self::MAX_LIGHTS as u32);
|
||||
let shadow_pass = ShadowPass::new(&mut self.device, &mut self.world, light_uniform_buffer.clone(), vb_desc.clone(), local_bind_group_layout.clone(), Self::MAX_LIGHTS as u32);
|
||||
let forward_pass = ForwardPass::new(&mut self.device, forward_uniforms, light_uniform_buffer.clone(), &shadow_pass, vb_desc, &local_bind_group_layout, &self.swap_chain_descriptor);
|
||||
self.render_passes.push(Box::new(shadow_pass));
|
||||
self.render_passes.push(Box::new(forward_pass));
|
||||
}
|
||||
|
||||
fn update(&mut self) {
|
||||
{
|
||||
let mut time = self.world.resources.get_mut::<Time>().unwrap();
|
||||
time.start();
|
||||
}
|
||||
self.scheduler.execute(&mut self.world);
|
||||
self.render();
|
||||
{
|
||||
let mut time = self.world.resources.get_mut::<Time>().unwrap();
|
||||
time.stop();
|
||||
}
|
||||
}
|
||||
|
||||
fn resize(&mut self, width: u32, height: u32)
|
||||
{
|
||||
self.swap_chain_descriptor.width = width;
|
||||
|
@ -137,7 +128,7 @@ impl Application {
|
|||
self.queue.submit(&[command_buffer]);
|
||||
}
|
||||
|
||||
fn update(&mut self, _: WindowEvent)
|
||||
fn handle_event(&mut self, _: WindowEvent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -150,7 +141,7 @@ impl Application {
|
|||
let mut encoder =
|
||||
self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
|
||||
let mut entities = <(Read<Material>, Read<LocalToWorld>)>::query();
|
||||
let mut entities = <(Write<Material>, Read<LocalToWorld>)>::query();
|
||||
let entities_count = entities.iter(&mut self.world).count();
|
||||
let size = mem::size_of::<MaterialUniforms>();
|
||||
let temp_buf_data = self.device
|
||||
|
@ -174,7 +165,12 @@ impl Application {
|
|||
}
|
||||
|
||||
let temp_buf = temp_buf_data.finish();
|
||||
|
||||
for pass in self.render_passes.iter_mut() {
|
||||
pass.render(&mut self.device, &mut frame, &mut encoder, &mut self.world);
|
||||
}
|
||||
|
||||
// TODO: this should happen before rendering
|
||||
for (i, (entity, _)) in entities.iter(&mut self.world).enumerate() {
|
||||
encoder.copy_buffer_to_buffer(
|
||||
&temp_buf,
|
||||
|
@ -185,16 +181,12 @@ impl Application {
|
|||
);
|
||||
}
|
||||
|
||||
for pass in self.render_passes.iter_mut() {
|
||||
pass.render(&mut self.device, &mut frame, &mut encoder, &mut self.world);
|
||||
}
|
||||
|
||||
let command_buffer = encoder.finish();
|
||||
self.queue.submit(&[command_buffer]);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn run(universe: Universe, world: World, system_scheduler: SystemScheduler<ApplicationStage>) {
|
||||
pub fn run(universe: Universe, mut world: World, system_scheduler: SystemScheduler<ApplicationStage>) {
|
||||
env_logger::init();
|
||||
let event_loop = EventLoop::new();
|
||||
log::info!("Initializing the window...");
|
||||
|
@ -217,6 +209,7 @@ impl Application {
|
|||
let (window, hidpi_factor, size, surface) = {
|
||||
let window = winit::window::Window::new(&event_loop).unwrap();
|
||||
window.set_title("bevy");
|
||||
window.set_inner_size((1920, 1080).into());
|
||||
let hidpi_factor = window.hidpi_factor();
|
||||
let size = window.inner_size().to_physical(hidpi_factor);
|
||||
let surface = wgpu::Surface::create(&window);
|
||||
|
@ -231,7 +224,9 @@ impl Application {
|
|||
present_mode: wgpu::PresentMode::Vsync,
|
||||
};
|
||||
let swap_chain = device.create_swap_chain(&surface, &swap_chain_descriptor);
|
||||
|
||||
|
||||
world.resources.insert(Time::new());
|
||||
|
||||
log::info!("Initializing the example...");
|
||||
let mut app = Application {
|
||||
universe,
|
||||
|
@ -280,12 +275,11 @@ impl Application {
|
|||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
_ => {
|
||||
app.update(event);
|
||||
app.handle_event(event);
|
||||
}
|
||||
},
|
||||
event::Event::EventsCleared => {
|
||||
app.scheduler.execute(&mut app.world);
|
||||
app.render();
|
||||
app.update();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::{sync::{Arc, RwLock}, marker::PhantomData, ops::Drop};
|
||||
use std::{sync::{Arc, RwLock}, marker::PhantomData, ops::Drop, collections::HashMap};
|
||||
|
||||
pub struct Handle<T>
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ pub trait Asset<D> {
|
|||
pub struct AssetStorage<T, D> where T: Asset<D> {
|
||||
assets: Vec<Option<T>>,
|
||||
free_indices: Arc<RwLock<Vec<usize>>>,
|
||||
names: HashMap<String, Arc<RwLock<usize>>>,
|
||||
marker: PhantomData<D>,
|
||||
}
|
||||
|
||||
|
@ -43,24 +44,43 @@ impl<T, D> AssetStorage<T, D> where T: Asset<D> {
|
|||
AssetStorage {
|
||||
assets: Vec::new(),
|
||||
free_indices: Arc::new(RwLock::new(Vec::new())),
|
||||
names: HashMap::new(),
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(&mut self, asset: T) -> Handle<T> {
|
||||
pub fn get_named(&self, name: &str) -> Option<Handle<T>> {
|
||||
match self.names.get(name) {
|
||||
Some(id) => {
|
||||
Some(Handle {
|
||||
id: id.clone(),
|
||||
marker: PhantomData,
|
||||
free_indices: self.free_indices.clone()
|
||||
})
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(&mut self, asset: T, name: &str) -> Handle<T> {
|
||||
match self.free_indices.write().unwrap().pop() {
|
||||
Some(id) => {
|
||||
self.assets[id as usize] = Some(asset);
|
||||
let handle = Arc::new(RwLock::new(id));
|
||||
self.names.insert(name.to_string(), handle.clone());
|
||||
Handle {
|
||||
id: Arc::new(RwLock::new(id)),
|
||||
id: handle,
|
||||
marker: PhantomData,
|
||||
free_indices: self.free_indices.clone()
|
||||
}
|
||||
},
|
||||
None => {
|
||||
self.assets.push(Some(asset));
|
||||
let id = self.assets.len() - 1;
|
||||
let handle = Arc::new(RwLock::new(id));
|
||||
self.names.insert(name.to_string(), handle.clone());
|
||||
Handle {
|
||||
id: Arc::new(RwLock::new(self.assets.len() - 1)),
|
||||
id: handle,
|
||||
marker: PhantomData,
|
||||
free_indices: self.free_indices.clone()
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use legion::schedule::Stage;
|
||||
|
||||
pub mod time;
|
||||
pub use time::Time;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum ApplicationStage {
|
||||
Update,
|
||||
|
|
26
src/core/time.rs
Normal file
26
src/core/time.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use std::time::{Duration, Instant};
|
||||
|
||||
pub struct Time {
|
||||
pub delta: Duration,
|
||||
pub instant: Instant,
|
||||
pub delta_seconds: f32
|
||||
}
|
||||
|
||||
impl Time {
|
||||
pub fn new() -> Time {
|
||||
Time {
|
||||
delta: Duration::from_secs(0),
|
||||
instant: Instant::now(),
|
||||
delta_seconds: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&mut self) {
|
||||
self.instant = Instant::now();
|
||||
}
|
||||
|
||||
pub fn stop(&mut self) {
|
||||
self.delta = Instant::now() - self.instant;
|
||||
self.delta_seconds = self.delta.as_secs() as f32 + (self.delta.subsec_nanos() as f32 / 1.0e9);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ use crate::{render::*, asset::*, LocalToWorld};
|
|||
use wgpu::{BindGroupLayout, Buffer, CommandEncoder, Device, VertexBufferDescriptor, SwapChainOutput, SwapChainDescriptor};
|
||||
use legion::prelude::*;
|
||||
use zerocopy::AsBytes;
|
||||
use std::{mem, sync::Arc};
|
||||
use std::{mem, sync::Arc, rc::Rc};
|
||||
|
||||
pub struct ShadowPass {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
|
@ -11,6 +11,7 @@ pub struct ShadowPass {
|
|||
pub shadow_texture: wgpu::Texture,
|
||||
pub shadow_view: wgpu::TextureView,
|
||||
pub shadow_sampler: wgpu::Sampler,
|
||||
pub local_bind_group_layout: Rc<BindGroupLayout>,
|
||||
pub light_uniform_buffer: Arc::<UniformBuffer>,
|
||||
pub lights_are_dirty: bool,
|
||||
}
|
||||
|
@ -47,6 +48,30 @@ impl Pass for ShadowPass {
|
|||
);
|
||||
}
|
||||
|
||||
for mut material in <Write<Material>>::query().iter(world) {
|
||||
if let None = material.bind_group {
|
||||
let entity_uniform_size = mem::size_of::<MaterialUniforms>() as wgpu::BufferAddress;
|
||||
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: entity_uniform_size,
|
||||
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||
});
|
||||
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
layout: &self.local_bind_group_layout,
|
||||
bindings: &[wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &uniform_buf,
|
||||
range: 0 .. entity_uniform_size,
|
||||
},
|
||||
}],
|
||||
});
|
||||
|
||||
material.bind_group = Some(bind_group);
|
||||
material.uniform_buf = Some(uniform_buf);
|
||||
}
|
||||
}
|
||||
|
||||
for (i, (mut light, _)) in <(Write<Light>, Read<LocalToWorld>)>::query().iter(world).enumerate() {
|
||||
if let None = light.target_view {
|
||||
light.target_view = Some(self.shadow_texture.create_view(&wgpu::TextureViewDescriptor {
|
||||
|
@ -114,7 +139,7 @@ impl ShadowPass {
|
|||
depth: 1,
|
||||
};
|
||||
|
||||
pub fn new(device: &Device, _: &World, light_uniform_buffer: Arc::<UniformBuffer>, vertex_buffer_descriptor: VertexBufferDescriptor, local_bind_group_layout: &BindGroupLayout, max_lights: u32) -> ShadowPass {
|
||||
pub fn new(device: &Device, _: &World, light_uniform_buffer: Arc::<UniformBuffer>, vertex_buffer_descriptor: VertexBufferDescriptor, local_bind_group_layout: Rc<BindGroupLayout>, max_lights: u32) -> ShadowPass {
|
||||
// Create pipeline layout
|
||||
let bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
|
@ -222,6 +247,7 @@ impl ShadowPass {
|
|||
shadow_view,
|
||||
shadow_sampler,
|
||||
light_uniform_buffer,
|
||||
local_bind_group_layout,
|
||||
lights_are_dirty: true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
# run using one of these commands
|
||||
# lld linker makes compiles faster
|
||||
# rust backtrace gives you a nice backtrace on panics
|
||||
# -Zshare-generics=y makes generics slightly faster for some reason
|
||||
env RUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo run --release
|
||||
env RUSTFLAGS="-C link-arg=-fuse-ld=lld" RUST_BACKTRACE=1 cargo run --release
|
||||
env RUSTFLAGS="-C link-arg=-fuse-ld=lld -Zshare-generics=y" RUST_BACKTRACE=1 cargo run --release
|
||||
```
|
Loading…
Reference in a new issue