Add Handle<T> support to uniform resource provider. Use Handle<StandardMaterial> instead of StandardMaterial
This commit is contained in:
parent
c1e66089cc
commit
5d99f3a7e8
10
.vscode/settings.json
vendored
Normal file
10
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"Wgpu",
|
||||||
|
"bools",
|
||||||
|
"chunkset",
|
||||||
|
"chunksets",
|
||||||
|
"multizip",
|
||||||
|
"passthrough"
|
||||||
|
]
|
||||||
|
}
|
@ -380,7 +380,7 @@ impl<'a, 'b, F: Filter<ArchetypeFilterData<'a>>> Iterator for FilterArchIter<'a,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator which yields the index of chuinks that match a filter.
|
/// An iterator which yields the index of chunks that match a filter.
|
||||||
pub struct FilterChunkIter<'a, 'b, F: Filter<ChunksetFilterData<'a>>> {
|
pub struct FilterChunkIter<'a, 'b, F: Filter<ChunksetFilterData<'a>>> {
|
||||||
filter: &'b F,
|
filter: &'b F,
|
||||||
chunks: Enumerate<F::Iter>,
|
chunks: Enumerate<F::Iter>,
|
||||||
@ -905,7 +905,7 @@ impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h,
|
|||||||
impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k);
|
impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k);
|
||||||
impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l);
|
impl_or_filter!(A => a, B => b, C => c, D => d, E => e, F => f, G => g, H => h, I => i, J => j, K => k, L => l);
|
||||||
|
|
||||||
/// A filter qhich requires that all chunks contain entity data components of type `T`.
|
/// A filter which requires that all chunks contain entity data components of type `T`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ComponentFilter<T>(PhantomData<T>);
|
pub struct ComponentFilter<T>(PhantomData<T>);
|
||||||
|
|
||||||
|
@ -117,24 +117,22 @@ fn create_entities_builder_add_component(
|
|||||||
fn create_entities_builder_archetype(
|
fn create_entities_builder_archetype(
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
plane_handle: Handle<Mesh>,
|
plane_handle: Handle<Mesh>,
|
||||||
|
plane_material_handle: Handle<StandardMaterial>,
|
||||||
cube_handle: Handle<Mesh>,
|
cube_handle: Handle<Mesh>,
|
||||||
|
cube_material_handle: Handle<StandardMaterial>,
|
||||||
) {
|
) {
|
||||||
world
|
world
|
||||||
.build()
|
.build()
|
||||||
// plane
|
// plane
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: plane_handle,
|
mesh: plane_handle,
|
||||||
material: StandardMaterial {
|
material: plane_material_handle,
|
||||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
// cube
|
// cube
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
material: StandardMaterial {
|
material: cube_material_handle,
|
||||||
albedo: Color::rgb(0.5, 0.3, 0.3).into(),
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
// light
|
// light
|
||||||
@ -162,9 +160,19 @@ fn create_entities_builder_archetype(
|
|||||||
|
|
||||||
fn setup(world: &mut World, resources: &mut Resources) {
|
fn setup(world: &mut World, resources: &mut Resources) {
|
||||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
|
let mut material_storage = resources
|
||||||
|
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||||
|
.unwrap();
|
||||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||||
|
|
||||||
|
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||||
|
albedo: Color::rgb(0.5, 0.3, 0.3).into(),
|
||||||
|
});
|
||||||
|
let plane_material_handle = material_storage.add(StandardMaterial {
|
||||||
|
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||||
|
});
|
||||||
|
|
||||||
// no-archetype precompile: 1.24 sec
|
// no-archetype precompile: 1.24 sec
|
||||||
// archetype precompile: 1.07 sec
|
// archetype precompile: 1.07 sec
|
||||||
// create_entities_insert_vec(world, plane_handle, cube_handle);
|
// create_entities_insert_vec(world, plane_handle, cube_handle);
|
||||||
@ -174,5 +182,11 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||||||
// create_entities_builder_add_component(world, plane_handle, cube_handle);
|
// create_entities_builder_add_component(world, plane_handle, cube_handle);
|
||||||
|
|
||||||
// archetype precompile: 0.65
|
// archetype precompile: 0.65
|
||||||
create_entities_builder_archetype(world, plane_handle, cube_handle);
|
create_entities_builder_archetype(
|
||||||
|
world,
|
||||||
|
plane_handle,
|
||||||
|
plane_material_handle,
|
||||||
|
cube_handle,
|
||||||
|
cube_material_handle,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -24,16 +24,21 @@ fn build_rotator_system() -> Box<dyn Schedulable> {
|
|||||||
|
|
||||||
fn setup(world: &mut World, resources: &mut Resources) {
|
fn setup(world: &mut World, resources: &mut Resources) {
|
||||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
|
let mut material_storage = resources
|
||||||
|
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||||
|
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||||
|
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
||||||
|
});
|
||||||
|
|
||||||
world
|
world
|
||||||
.build()
|
.build()
|
||||||
// parent cube
|
// parent cube
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
material: StandardMaterial {
|
material: cube_material_handle,
|
||||||
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
|
||||||
},
|
|
||||||
translation: Translation::new(0.0, 0.0, 1.0),
|
translation: Translation::new(0.0, 0.0, 1.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
@ -42,9 +47,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||||||
// cube
|
// cube
|
||||||
builder.add_entity(MeshEntity {
|
builder.add_entity(MeshEntity {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
material: StandardMaterial {
|
material: cube_material_handle,
|
||||||
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
|
||||||
},
|
|
||||||
translation: Translation::new(0.0, 0.0, 3.0),
|
translation: Translation::new(0.0, 0.0, 3.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
@ -6,25 +6,30 @@ fn main() {
|
|||||||
|
|
||||||
fn setup(world: &mut World, resources: &mut Resources) {
|
fn setup(world: &mut World, resources: &mut Resources) {
|
||||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
|
let mut material_storage = resources
|
||||||
|
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||||
|
.unwrap();
|
||||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||||
|
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||||
|
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
||||||
|
});
|
||||||
|
let plane_material_handle = material_storage.add(StandardMaterial {
|
||||||
|
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||||
|
});
|
||||||
|
|
||||||
world
|
world
|
||||||
.build()
|
.build()
|
||||||
// plane
|
// plane
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: plane_handle,
|
mesh: plane_handle,
|
||||||
material: StandardMaterial {
|
material: plane_material_handle,
|
||||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
// cube
|
// cube
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
material: StandardMaterial {
|
material: cube_material_handle,
|
||||||
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
|
||||||
},
|
|
||||||
translation: Translation::new(0.0, 0.0, 1.0),
|
translation: Translation::new(0.0, 0.0, 1.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
@ -13,14 +13,15 @@ fn main() {
|
|||||||
fn build_move_system() -> Box<dyn Schedulable> {
|
fn build_move_system() -> Box<dyn Schedulable> {
|
||||||
SystemBuilder::new("Move")
|
SystemBuilder::new("Move")
|
||||||
.read_resource::<Time>()
|
.read_resource::<Time>()
|
||||||
.with_query(<(Write<Translation>, Write<StandardMaterial>)>::query())
|
.write_resource::<AssetStorage<StandardMaterial>>()
|
||||||
.build(move |_, world, time, person_query| {
|
.with_query(<(Write<Translation>, Read<Handle<StandardMaterial>>)>::query())
|
||||||
for (mut translation, mut material) in person_query.iter_mut(world) {
|
.build(move |_, world, (time, material_storage), person_query| {
|
||||||
|
for (mut translation, material_handle) in person_query.iter_mut(world) {
|
||||||
|
let material = material_storage.get_mut(&material_handle).unwrap();
|
||||||
translation.0 += math::vec3(1.0, 0.0, 0.0) * time.delta_seconds;
|
translation.0 += math::vec3(1.0, 0.0, 0.0) * time.delta_seconds;
|
||||||
if let ColorSource::Color(color) = material.albedo {
|
if let ColorSource::Color(ref mut color) = material.albedo {
|
||||||
material.albedo = (color
|
*color = *color
|
||||||
+ Color::rgb(-time.delta_seconds, -time.delta_seconds, time.delta_seconds))
|
+ Color::rgb(-time.delta_seconds, -time.delta_seconds, time.delta_seconds);
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -28,36 +29,33 @@ fn build_move_system() -> Box<dyn Schedulable> {
|
|||||||
|
|
||||||
fn setup(world: &mut World, resources: &mut Resources) {
|
fn setup(world: &mut World, resources: &mut Resources) {
|
||||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
|
let mut material_storage = resources
|
||||||
|
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||||
|
.unwrap();
|
||||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||||
|
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||||
|
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
||||||
|
});
|
||||||
|
let plane_material_handle = material_storage.add(StandardMaterial {
|
||||||
|
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||||
|
});
|
||||||
|
|
||||||
let mut builder = world
|
let mut builder = world
|
||||||
.build()
|
.build()
|
||||||
// plane
|
// plane
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: plane_handle,
|
mesh: plane_handle,
|
||||||
material: StandardMaterial {
|
material: plane_material_handle,
|
||||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
// cube
|
// cube
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
material: StandardMaterial {
|
material: cube_material_handle,
|
||||||
albedo: Color::rgb(1.0, 1.0, 1.0).into(),
|
|
||||||
},
|
|
||||||
translation: Translation::new(0.0, 0.0, 1.0),
|
translation: Translation::new(0.0, 0.0, 1.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.add_entity(MeshEntity {
|
|
||||||
mesh: cube_handle,
|
|
||||||
material: StandardMaterial {
|
|
||||||
albedo: Color::rgb(0.0, 1.0, 0.0).into(),
|
|
||||||
},
|
|
||||||
translation: Translation::new(-2.0, 0.0, 1.0),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
// light
|
// light
|
||||||
.add_entity(LightEntity {
|
.add_entity(LightEntity {
|
||||||
translation: Translation::new(4.0, -4.0, 5.0),
|
translation: Translation::new(4.0, -4.0, 5.0),
|
||||||
@ -81,16 +79,17 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||||||
|
|
||||||
let mut rng = StdRng::from_entropy();
|
let mut rng = StdRng::from_entropy();
|
||||||
for _ in 0..10000 {
|
for _ in 0..10000 {
|
||||||
builder = builder.add_entity(MeshEntity {
|
let spawned_material_handle = material_storage.add(StandardMaterial {
|
||||||
mesh: cube_handle,
|
|
||||||
material: StandardMaterial {
|
|
||||||
albedo: Color::rgb(
|
albedo: Color::rgb(
|
||||||
rng.gen_range(0.0, 1.0),
|
rng.gen_range(0.0, 1.0),
|
||||||
rng.gen_range(0.0, 1.0),
|
rng.gen_range(0.0, 1.0),
|
||||||
rng.gen_range(0.0, 1.0),
|
rng.gen_range(0.0, 1.0),
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
},
|
});
|
||||||
|
builder = builder.add_entity(MeshEntity {
|
||||||
|
mesh: cube_handle,
|
||||||
|
material: spawned_material_handle,
|
||||||
translation: Translation::new(
|
translation: Translation::new(
|
||||||
rng.gen_range(-50.0, 50.0),
|
rng.gen_range(-50.0, 50.0),
|
||||||
rng.gen_range(-50.0, 50.0),
|
rng.gen_range(-50.0, 50.0),
|
||||||
|
@ -14,14 +14,20 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||||||
));
|
));
|
||||||
let texture_handle = texture_storage.add(texture);
|
let texture_handle = texture_storage.add(texture);
|
||||||
|
|
||||||
|
let mut material_storage = resources
|
||||||
|
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||||
|
albedo: texture_handle.into(),
|
||||||
|
});
|
||||||
|
|
||||||
world
|
world
|
||||||
.build()
|
.build()
|
||||||
// cube
|
// cube
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
material: StandardMaterial {
|
material: cube_material_handle,
|
||||||
albedo: texture_handle.into(),
|
|
||||||
},
|
|
||||||
translation: Translation::new(0.0, 0.0, 0.0),
|
translation: Translation::new(0.0, 0.0, 0.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
@ -6,16 +6,20 @@ fn main() {
|
|||||||
|
|
||||||
fn setup(world: &mut World, resources: &mut Resources) {
|
fn setup(world: &mut World, resources: &mut Resources) {
|
||||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
|
let mut material_storage = resources
|
||||||
|
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||||
|
.unwrap();
|
||||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||||
|
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||||
|
albedo: Color::rgb(0.5, 0.3, 0.3).into(),
|
||||||
|
});
|
||||||
|
|
||||||
world
|
world
|
||||||
.build()
|
.build()
|
||||||
// cube
|
// cube
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
material: StandardMaterial {
|
material: cube_material_handle,
|
||||||
albedo: Color::rgb(0.5, 0.3, 0.3).into(),
|
|
||||||
},
|
|
||||||
translation: Translation::new(0.0, 0.0, 1.0),
|
translation: Translation::new(0.0, 0.0, 1.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
@ -14,7 +14,7 @@ fn build_move_system() -> Box<dyn Schedulable> {
|
|||||||
.read_resource::<Time>()
|
.read_resource::<Time>()
|
||||||
.with_query(<Write<Node>>::query())
|
.with_query(<Write<Node>>::query())
|
||||||
.build(move |_, world, time, query| {
|
.build(move |_, world, time, query| {
|
||||||
for (i, mut node) in query.iter_mut(world).enumerate() {
|
for (_i, mut node) in query.iter_mut(world).enumerate() {
|
||||||
if node.color.r > 0.2 {
|
if node.color.r > 0.2 {
|
||||||
node.position += Vec2::new(0.1 * time.delta_seconds, 0.0);
|
node.position += Vec2::new(0.1 * time.delta_seconds, 0.0);
|
||||||
// println!("{}", node.position.x());
|
// println!("{}", node.position.x());
|
||||||
|
@ -125,6 +125,8 @@ impl AppBuilder {
|
|||||||
self.resources.insert(AssetStorage::<Mesh>::new());
|
self.resources.insert(AssetStorage::<Mesh>::new());
|
||||||
self.resources.insert(AssetStorage::<Texture>::new());
|
self.resources.insert(AssetStorage::<Texture>::new());
|
||||||
self.resources.insert(AssetStorage::<Shader>::new());
|
self.resources.insert(AssetStorage::<Shader>::new());
|
||||||
|
self.resources
|
||||||
|
.insert(AssetStorage::<StandardMaterial>::new());
|
||||||
self.resources
|
self.resources
|
||||||
.insert(AssetStorage::<PipelineDescriptor>::new());
|
.insert(AssetStorage::<PipelineDescriptor>::new());
|
||||||
self.resources.insert(ShaderPipelineAssignments::new());
|
self.resources.insert(ShaderPipelineAssignments::new());
|
||||||
|
@ -6,7 +6,7 @@ use bevy_derive::EntityArchetype;
|
|||||||
#[derive(EntityArchetype, Default)]
|
#[derive(EntityArchetype, Default)]
|
||||||
pub struct MeshEntity {
|
pub struct MeshEntity {
|
||||||
pub mesh: Handle<Mesh>,
|
pub mesh: Handle<Mesh>,
|
||||||
pub material: StandardMaterial,
|
pub material: Handle<StandardMaterial>,
|
||||||
pub renderable: Renderable,
|
pub renderable: Renderable,
|
||||||
pub local_to_world: LocalToWorld,
|
pub local_to_world: LocalToWorld,
|
||||||
pub translation: Translation,
|
pub translation: Translation,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
asset::AssetStorage,
|
asset::{AssetStorage, Handle},
|
||||||
render::{
|
render::{
|
||||||
pipeline::BindType,
|
pipeline::BindType,
|
||||||
render_resource::{BufferUsage, RenderResource, ResourceProvider},
|
render_resource::{BufferUsage, RenderResource, ResourceProvider},
|
||||||
@ -9,31 +9,313 @@ use crate::{
|
|||||||
Renderable,
|
Renderable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use legion::prelude::*;
|
use legion::{filter::*, prelude::*};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
};
|
};
|
||||||
pub const BIND_BUFFER_ALIGNMENT: u64 = 256;
|
pub const BIND_BUFFER_ALIGNMENT: u64 = 256;
|
||||||
|
|
||||||
pub struct UniformResourceProvider<T>
|
pub struct UniformResourceProvider<T>
|
||||||
where
|
where
|
||||||
T: AsUniforms + Send + Sync,
|
T: AsUniforms + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
_marker: PhantomData<T>,
|
_marker: PhantomData<T>,
|
||||||
// PERF: somehow remove this HashSet
|
// PERF: somehow remove this HashSet
|
||||||
uniform_buffer_info_resources:
|
uniform_buffer_info_resources:
|
||||||
HashMap<String, (Option<RenderResource>, usize, HashSet<Entity>)>,
|
HashMap<String, (Option<RenderResource>, usize, HashSet<Entity>)>,
|
||||||
|
asset_resources: HashMap<Handle<T>, HashMap<String, RenderResource>>,
|
||||||
|
resource_query: Query<
|
||||||
|
(Read<T>, Read<Renderable>),
|
||||||
|
EntityFilterTuple<
|
||||||
|
And<(ComponentFilter<T>, ComponentFilter<Renderable>)>,
|
||||||
|
And<(Passthrough, Passthrough)>,
|
||||||
|
And<(Passthrough, Passthrough)>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
handle_query: Option<
|
||||||
|
Query<
|
||||||
|
(Read<Handle<T>>, Read<Renderable>),
|
||||||
|
EntityFilterTuple<
|
||||||
|
And<(ComponentFilter<Handle<T>>, ComponentFilter<Renderable>)>,
|
||||||
|
And<(Passthrough, Passthrough)>,
|
||||||
|
And<(Passthrough, Passthrough)>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> UniformResourceProvider<T>
|
impl<T> UniformResourceProvider<T>
|
||||||
where
|
where
|
||||||
T: AsUniforms + Send + Sync,
|
T: AsUniforms + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
UniformResourceProvider {
|
UniformResourceProvider {
|
||||||
uniform_buffer_info_resources: HashMap::new(),
|
uniform_buffer_info_resources: Default::default(),
|
||||||
|
asset_resources: Default::default(),
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
|
resource_query: <(Read<T>, Read<Renderable>)>::query(),
|
||||||
|
handle_query: Some(<(Read<Handle<T>>, Read<Renderable>)>::query()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_asset_uniforms(
|
||||||
|
&mut self,
|
||||||
|
renderer: &mut dyn Renderer,
|
||||||
|
world: &World,
|
||||||
|
resources: &Resources,
|
||||||
|
) {
|
||||||
|
let handle_query = self.handle_query.take().unwrap();
|
||||||
|
// TODO: only update handle values when Asset value has changed
|
||||||
|
if let Some(asset_storage) = resources.get::<AssetStorage<T>>() {
|
||||||
|
for (entity, (handle, _renderable)) in handle_query.iter_entities(world) {
|
||||||
|
if let Some(uniforms) = asset_storage.get(&handle) {
|
||||||
|
self.setup_entity_uniform_resources(
|
||||||
|
entity,
|
||||||
|
uniforms,
|
||||||
|
renderer,
|
||||||
|
resources,
|
||||||
|
false,
|
||||||
|
Some(*handle),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.handle_query = Some(handle_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_entity_uniform_resources(
|
||||||
|
&mut self,
|
||||||
|
entity: Entity,
|
||||||
|
uniforms: &T,
|
||||||
|
renderer: &mut dyn Renderer,
|
||||||
|
resources: &Resources,
|
||||||
|
dynamic_unforms: bool,
|
||||||
|
asset_handle: Option<Handle<T>>,
|
||||||
|
) {
|
||||||
|
let field_infos = uniforms.get_field_infos();
|
||||||
|
for uniform_info in UniformInfoIter::new(field_infos, uniforms.deref()) {
|
||||||
|
match uniform_info.bind_type {
|
||||||
|
BindType::Uniform { .. } => {
|
||||||
|
if dynamic_unforms {
|
||||||
|
if let None = self.uniform_buffer_info_resources.get(uniform_info.name) {
|
||||||
|
self.uniform_buffer_info_resources
|
||||||
|
.insert(uniform_info.name.to_string(), (None, 0, HashSet::new()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let (_resource, counts, entities) = self
|
||||||
|
.uniform_buffer_info_resources
|
||||||
|
.get_mut(uniform_info.name)
|
||||||
|
.unwrap();
|
||||||
|
entities.insert(entity);
|
||||||
|
*counts += 1;
|
||||||
|
} else {
|
||||||
|
let handle = asset_handle.unwrap();
|
||||||
|
if let None = self.asset_resources.get(&handle) {
|
||||||
|
self.asset_resources.insert(handle, HashMap::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
let resources = self.asset_resources.get_mut(&handle).unwrap();
|
||||||
|
|
||||||
|
let render_resource = match resources.get(uniform_info.name) {
|
||||||
|
Some(render_resource) => *render_resource,
|
||||||
|
None => {
|
||||||
|
// let size = uniform_info.bind_type.get_uniform_size().unwrap();
|
||||||
|
let size = BIND_BUFFER_ALIGNMENT;
|
||||||
|
let resource = renderer.create_buffer(
|
||||||
|
size,
|
||||||
|
BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
||||||
|
);
|
||||||
|
resources.insert(uniform_info.name.to_string(), resource);
|
||||||
|
resource
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
renderer.set_entity_uniform_resource(
|
||||||
|
entity,
|
||||||
|
uniform_info.name,
|
||||||
|
render_resource,
|
||||||
|
);
|
||||||
|
|
||||||
|
let (tmp_buffer, tmp_buffer_size) = if let Some(uniform_bytes) =
|
||||||
|
uniforms.get_uniform_bytes_ref(uniform_info.name)
|
||||||
|
{
|
||||||
|
(
|
||||||
|
renderer.create_buffer_mapped(
|
||||||
|
uniform_bytes.len(),
|
||||||
|
BufferUsage::COPY_SRC,
|
||||||
|
&mut |mapped| {
|
||||||
|
mapped.copy_from_slice(uniform_bytes);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
uniform_bytes.len(),
|
||||||
|
)
|
||||||
|
} else if let Some(uniform_bytes) =
|
||||||
|
uniforms.get_uniform_bytes(uniform_info.name)
|
||||||
|
{
|
||||||
|
(
|
||||||
|
renderer.create_buffer_mapped(
|
||||||
|
uniform_bytes.len(),
|
||||||
|
BufferUsage::COPY_SRC,
|
||||||
|
&mut |mapped| {
|
||||||
|
mapped.copy_from_slice(&uniform_bytes);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
uniform_bytes.len(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
panic!("failed to get data from uniform: {}", uniform_info.name);
|
||||||
|
};
|
||||||
|
|
||||||
|
renderer.copy_buffer_to_buffer(
|
||||||
|
tmp_buffer,
|
||||||
|
0,
|
||||||
|
render_resource,
|
||||||
|
0,
|
||||||
|
tmp_buffer_size as u64,
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer.remove_buffer(tmp_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BindType::SampledTexture { .. } => {
|
||||||
|
let texture_handle = uniforms.get_uniform_texture(&uniform_info.name).unwrap();
|
||||||
|
let resource = match renderer
|
||||||
|
.get_render_resources()
|
||||||
|
.get_texture_resource(texture_handle)
|
||||||
|
{
|
||||||
|
Some(resource) => resource,
|
||||||
|
None => {
|
||||||
|
let storage = resources.get::<AssetStorage<Texture>>().unwrap();
|
||||||
|
let texture = storage.get(&texture_handle).unwrap();
|
||||||
|
let descriptor: TextureDescriptor = texture.into();
|
||||||
|
let resource =
|
||||||
|
renderer.create_texture(&descriptor, Some(&texture.data));
|
||||||
|
renderer
|
||||||
|
.get_render_resources_mut()
|
||||||
|
.set_texture_resource(texture_handle, resource);
|
||||||
|
resource
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
renderer.set_entity_uniform_resource(entity, uniform_info.name, resource);
|
||||||
|
}
|
||||||
|
BindType::Sampler { .. } => {
|
||||||
|
let texture_handle = uniforms.get_uniform_texture(&uniform_info.name).unwrap();
|
||||||
|
let resource = match renderer
|
||||||
|
.get_render_resources()
|
||||||
|
.get_texture_sampler_resource(texture_handle)
|
||||||
|
{
|
||||||
|
Some(resource) => resource,
|
||||||
|
None => {
|
||||||
|
let storage = resources.get::<AssetStorage<Texture>>().unwrap();
|
||||||
|
let texture = storage.get(&texture_handle).unwrap();
|
||||||
|
let descriptor: SamplerDescriptor = texture.into();
|
||||||
|
let resource = renderer.create_sampler(&descriptor);
|
||||||
|
renderer
|
||||||
|
.get_render_resources_mut()
|
||||||
|
.set_texture_sampler_resource(texture_handle, resource);
|
||||||
|
resource
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
renderer.set_entity_uniform_resource(entity, uniform_info.name, resource);
|
||||||
|
}
|
||||||
|
_ => panic!(
|
||||||
|
"encountered unsupported bind_type {:?}",
|
||||||
|
uniform_info.bind_type
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_dynamic_uniform_buffers(&mut self, renderer: &mut dyn Renderer, world: &World) {
|
||||||
|
// allocate uniform buffers
|
||||||
|
for (name, (resource, count, _entities)) in self.uniform_buffer_info_resources.iter_mut() {
|
||||||
|
let count = *count as u64;
|
||||||
|
if let Some(resource) = resource {
|
||||||
|
let mut info = renderer
|
||||||
|
.get_dynamic_uniform_buffer_info_mut(*resource)
|
||||||
|
.unwrap();
|
||||||
|
info.count = count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate enough space for twice as many entities as there are currently;
|
||||||
|
let capacity = count * 2;
|
||||||
|
let size = BIND_BUFFER_ALIGNMENT * capacity;
|
||||||
|
let created_resource =
|
||||||
|
renderer.create_buffer(size, BufferUsage::COPY_DST | BufferUsage::UNIFORM);
|
||||||
|
|
||||||
|
let mut info = DynamicUniformBufferInfo::new();
|
||||||
|
info.count = count;
|
||||||
|
info.capacity = capacity;
|
||||||
|
renderer.add_dynamic_uniform_buffer_info(created_resource, info);
|
||||||
|
*resource = Some(created_resource);
|
||||||
|
renderer
|
||||||
|
.get_render_resources_mut()
|
||||||
|
.set_named_resource(name, created_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy entity uniform data to buffers
|
||||||
|
for (name, (resource, _count, entities)) in self.uniform_buffer_info_resources.iter() {
|
||||||
|
let resource = resource.unwrap();
|
||||||
|
let size = {
|
||||||
|
// TODO: this lookup isn't needed anymore?
|
||||||
|
let info = renderer.get_dynamic_uniform_buffer_info(resource).unwrap();
|
||||||
|
BIND_BUFFER_ALIGNMENT * info.count
|
||||||
|
};
|
||||||
|
|
||||||
|
let alignment = BIND_BUFFER_ALIGNMENT as usize;
|
||||||
|
let mut offset = 0usize;
|
||||||
|
let info = renderer
|
||||||
|
.get_dynamic_uniform_buffer_info_mut(resource)
|
||||||
|
.unwrap();
|
||||||
|
for (entity, _) in self.resource_query.iter_entities(world) {
|
||||||
|
if !entities.contains(&entity) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// TODO: check if index has changed. if it has, then entity should be updated
|
||||||
|
// TODO: only mem-map entities if their data has changed
|
||||||
|
// PERF: These hashmap inserts are pretty expensive (10 fps for 10000 entities)
|
||||||
|
info.offsets.insert(entity, offset as u32);
|
||||||
|
// TODO: try getting ref first
|
||||||
|
offset += alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mapped_buffer_resource = renderer.create_buffer_mapped(
|
||||||
|
size as usize,
|
||||||
|
BufferUsage::COPY_SRC,
|
||||||
|
&mut |mapped| {
|
||||||
|
let alignment = BIND_BUFFER_ALIGNMENT as usize;
|
||||||
|
let mut offset = 0usize;
|
||||||
|
for (entity, (uniforms, _renderable)) in
|
||||||
|
self.resource_query.iter_entities(world)
|
||||||
|
{
|
||||||
|
if !entities.contains(&entity) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// TODO: check if index has changed. if it has, then entity should be updated
|
||||||
|
// TODO: only mem-map entities if their data has changed
|
||||||
|
if let Some(uniform_bytes) = uniforms.get_uniform_bytes_ref(&name) {
|
||||||
|
mapped[offset..(offset + uniform_bytes.len())]
|
||||||
|
.copy_from_slice(uniform_bytes);
|
||||||
|
offset += alignment;
|
||||||
|
} else if let Some(uniform_bytes) = uniforms.get_uniform_bytes(&name) {
|
||||||
|
mapped[offset..(offset + uniform_bytes.len())]
|
||||||
|
.copy_from_slice(uniform_bytes.as_slice());
|
||||||
|
offset += alignment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer.copy_buffer_to_buffer(mapped_buffer_resource, 0, resource, 0, size);
|
||||||
|
|
||||||
|
// TODO: uncomment this to free resource?
|
||||||
|
renderer.remove_buffer(mapped_buffer_resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,160 +348,13 @@ where
|
|||||||
*count = 0;
|
*count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.update_asset_uniforms(renderer, world, resources);
|
||||||
|
|
||||||
for (entity, (uniforms, _renderable)) in query.iter_entities(world) {
|
for (entity, (uniforms, _renderable)) in query.iter_entities(world) {
|
||||||
let field_infos = uniforms.get_field_infos();
|
self.setup_entity_uniform_resources(entity, &uniforms, renderer, resources, true, None);
|
||||||
for uniform_info in UniformInfoIter::new(field_infos, uniforms.deref()) {
|
|
||||||
match uniform_info.bind_type {
|
|
||||||
BindType::Uniform { .. } => {
|
|
||||||
// only add the first time a uniform info is processed
|
|
||||||
if let None = self.uniform_buffer_info_resources.get(uniform_info.name) {
|
|
||||||
self.uniform_buffer_info_resources
|
|
||||||
.insert(uniform_info.name.to_string(), (None, 0, HashSet::new()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_resource, counts, entities) = self
|
self.setup_dynamic_uniform_buffers(renderer, world);
|
||||||
.uniform_buffer_info_resources
|
|
||||||
.get_mut(uniform_info.name)
|
|
||||||
.unwrap();
|
|
||||||
entities.insert(entity);
|
|
||||||
*counts += 1;
|
|
||||||
}
|
|
||||||
BindType::SampledTexture { .. } => {
|
|
||||||
let texture_handle =
|
|
||||||
uniforms.get_uniform_texture(&uniform_info.name).unwrap();
|
|
||||||
let storage = resources.get::<AssetStorage<Texture>>().unwrap();
|
|
||||||
let texture = storage.get(&texture_handle).unwrap();
|
|
||||||
let resource = match renderer
|
|
||||||
.get_render_resources()
|
|
||||||
.get_texture_resource(texture_handle)
|
|
||||||
{
|
|
||||||
Some(resource) => resource,
|
|
||||||
None => {
|
|
||||||
let descriptor: TextureDescriptor = texture.into();
|
|
||||||
let resource =
|
|
||||||
renderer.create_texture(&descriptor, Some(&texture.data));
|
|
||||||
renderer
|
|
||||||
.get_render_resources_mut()
|
|
||||||
.set_texture_resource(texture_handle, resource);
|
|
||||||
resource
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
renderer.set_entity_uniform_resource(entity, uniform_info.name, resource);
|
|
||||||
}
|
|
||||||
BindType::Sampler { .. } => {
|
|
||||||
let texture_handle =
|
|
||||||
uniforms.get_uniform_texture(&uniform_info.name).unwrap();
|
|
||||||
let storage = resources.get::<AssetStorage<Texture>>().unwrap();
|
|
||||||
let texture = storage.get(&texture_handle).unwrap();
|
|
||||||
let resource = match renderer
|
|
||||||
.get_render_resources()
|
|
||||||
.get_texture_sampler_resource(texture_handle)
|
|
||||||
{
|
|
||||||
Some(resource) => resource,
|
|
||||||
None => {
|
|
||||||
let descriptor: SamplerDescriptor = texture.into();
|
|
||||||
let resource = renderer.create_sampler(&descriptor);
|
|
||||||
renderer
|
|
||||||
.get_render_resources_mut()
|
|
||||||
.set_texture_sampler_resource(texture_handle, resource);
|
|
||||||
resource
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
renderer.set_entity_uniform_resource(entity, uniform_info.name, resource);
|
|
||||||
}
|
|
||||||
_ => panic!(
|
|
||||||
"encountered unsupported bind_type {:?}",
|
|
||||||
uniform_info.bind_type
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate uniform buffers
|
|
||||||
for (name, (resource, count, _entities)) in self.uniform_buffer_info_resources.iter_mut() {
|
|
||||||
let count = *count as u64;
|
|
||||||
if let Some(resource) = resource {
|
|
||||||
let mut info = renderer
|
|
||||||
.get_dynamic_uniform_buffer_info_mut(*resource)
|
|
||||||
.unwrap();
|
|
||||||
info.count = count;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate enough space for twice as many entities as there are currently;
|
|
||||||
let capacity = count * 2;
|
|
||||||
let size = BIND_BUFFER_ALIGNMENT * capacity;
|
|
||||||
let created_resource =
|
|
||||||
renderer.create_buffer(size, BufferUsage::COPY_DST | BufferUsage::UNIFORM);
|
|
||||||
|
|
||||||
let mut info = DynamicUniformBufferInfo::new();
|
|
||||||
info.count = count;
|
|
||||||
info.capacity = capacity;
|
|
||||||
renderer.add_dynamic_uniform_buffer_info(created_resource, info);
|
|
||||||
*resource = Some(created_resource);
|
|
||||||
renderer
|
|
||||||
.get_render_resources_mut()
|
|
||||||
.set_named_resource(name, created_resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy entity uniform data to buffers
|
|
||||||
for (name, (resource, _count, entities)) in self.uniform_buffer_info_resources.iter() {
|
|
||||||
let resource = resource.unwrap();
|
|
||||||
let size = {
|
|
||||||
let info = renderer.get_dynamic_uniform_buffer_info(resource).unwrap();
|
|
||||||
BIND_BUFFER_ALIGNMENT * info.count
|
|
||||||
};
|
|
||||||
|
|
||||||
let alignment = BIND_BUFFER_ALIGNMENT as usize;
|
|
||||||
let mut offset = 0usize;
|
|
||||||
let info = renderer
|
|
||||||
.get_dynamic_uniform_buffer_info_mut(resource)
|
|
||||||
.unwrap();
|
|
||||||
for (entity, _) in query.iter_entities(world) {
|
|
||||||
if !entities.contains(&entity) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// TODO: check if index has changed. if it has, then entity should be updated
|
|
||||||
// TODO: only mem-map entities if their data has changed
|
|
||||||
// PERF: These hashmap inserts are pretty expensive (10 fps for 10000 entities)
|
|
||||||
info.offsets.insert(entity, offset as u32);
|
|
||||||
// TODO: try getting ref first
|
|
||||||
offset += alignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mapped_buffer_resource = renderer.create_buffer_mapped(
|
|
||||||
size as usize,
|
|
||||||
BufferUsage::COPY_SRC,
|
|
||||||
&mut |mapped| {
|
|
||||||
let alignment = BIND_BUFFER_ALIGNMENT as usize;
|
|
||||||
let mut offset = 0usize;
|
|
||||||
for (entity, (uniforms, _renderable)) in query.iter_entities(world) {
|
|
||||||
if !entities.contains(&entity) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// TODO: check if index has changed. if it has, then entity should be updated
|
|
||||||
// TODO: only mem-map entities if their data has changed
|
|
||||||
if let Some(uniform_bytes) = uniforms.get_uniform_bytes_ref(&name) {
|
|
||||||
mapped[offset..(offset + uniform_bytes.len())]
|
|
||||||
.copy_from_slice(uniform_bytes);
|
|
||||||
offset += alignment;
|
|
||||||
}
|
|
||||||
else if let Some(uniform_bytes) = uniforms.get_uniform_bytes(&name) {
|
|
||||||
mapped[offset..(offset + uniform_bytes.len())]
|
|
||||||
.copy_from_slice(uniform_bytes.as_slice());
|
|
||||||
offset += alignment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
renderer.copy_buffer_to_buffer(mapped_buffer_resource, 0, resource, 0, size);
|
|
||||||
|
|
||||||
// TODO: uncomment this to free resource?
|
|
||||||
renderer.remove_buffer(mapped_buffer_resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update shader assignments based on current macro defs
|
// update shader assignments based on current macro defs
|
||||||
for (uniforms, mut renderable) in <(Read<T>, Write<Renderable>)>::query().iter_mut(world) {
|
for (uniforms, mut renderable) in <(Read<T>, Write<Renderable>)>::query().iter_mut(world) {
|
||||||
@ -229,5 +364,18 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(asset_storage) = resources.get::<AssetStorage<T>>() {
|
||||||
|
for (handle, mut renderable) in
|
||||||
|
<(Read<Handle<T>>, Write<Renderable>)>::query().iter_mut(world)
|
||||||
|
{
|
||||||
|
let uniforms = asset_storage.get(&handle).unwrap();
|
||||||
|
if let Some(shader_defs) = uniforms.get_shader_defs() {
|
||||||
|
for shader_def in shader_defs {
|
||||||
|
renderable.shader_defs.insert(shader_def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// setup dynamic uniform instances
|
||||||
let mut dynamic_uniform_indices = Vec::new();
|
let mut dynamic_uniform_indices = Vec::new();
|
||||||
for binding in bind_group.bindings.iter() {
|
for binding in bind_group.bindings.iter() {
|
||||||
if let BindType::Uniform { dynamic, .. } = binding.bind_type {
|
if let BindType::Uniform { dynamic, .. } = binding.bind_type {
|
||||||
|
@ -11,7 +11,6 @@ use std::{borrow::Cow, collections::HashMap};
|
|||||||
|
|
||||||
pub struct BindGroupInfo {
|
pub struct BindGroupInfo {
|
||||||
pub bind_group: wgpu::BindGroup,
|
pub bind_group: wgpu::BindGroup,
|
||||||
pub unset_uniforms: Vec<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WgpuResources {
|
pub struct WgpuResources {
|
||||||
@ -53,38 +52,13 @@ impl WgpuResources {
|
|||||||
let bind_group_id = bind_group.get_hash().unwrap();
|
let bind_group_id = bind_group.get_hash().unwrap();
|
||||||
|
|
||||||
if let None = self.bind_groups.get(&bind_group_id) {
|
if let None = self.bind_groups.get(&bind_group_id) {
|
||||||
let mut unset_uniforms = Vec::new();
|
|
||||||
|
|
||||||
let mut binding_resources = Vec::new();
|
let mut binding_resources = Vec::new();
|
||||||
// if a uniform resource buffer doesn't exist, create a new empty one
|
// if a uniform resource buffer doesn't exist, create a new empty one
|
||||||
for binding in bind_group.bindings.iter() {
|
for binding in bind_group.bindings.iter() {
|
||||||
let resource = match self.render_resources.get_named_resource(&binding.name) {
|
let resource = match self.render_resources.get_named_resource(&binding.name) {
|
||||||
resource @ Some(_) => resource,
|
resource @ Some(_) => resource,
|
||||||
None => {
|
None => {
|
||||||
match binding.bind_type {
|
return
|
||||||
BindType::Uniform { .. } => {
|
|
||||||
// println!(
|
|
||||||
// "Warning: creating new empty buffer for uniform binding {} {:?}",
|
|
||||||
// binding.name, binding
|
|
||||||
// );
|
|
||||||
unset_uniforms.push(binding.name.to_string());
|
|
||||||
let size = binding.bind_type.get_uniform_size().unwrap();
|
|
||||||
let resource = self.create_buffer(
|
|
||||||
device,
|
|
||||||
size,
|
|
||||||
BufferUsage::UNIFORM | BufferUsage::COPY_DST,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.render_resources
|
|
||||||
.set_named_resource(&binding.name, resource);
|
|
||||||
Some(resource)
|
|
||||||
}
|
|
||||||
BindType::Sampler | BindType::SampledTexture { .. } => {
|
|
||||||
// textures and samplers are handled per-entity
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ => panic!("unsupported bind type: {:?}", binding),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -138,7 +112,6 @@ impl WgpuResources {
|
|||||||
bind_group_id,
|
bind_group_id,
|
||||||
BindGroupInfo {
|
BindGroupInfo {
|
||||||
bind_group,
|
bind_group,
|
||||||
unset_uniforms,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -184,6 +157,17 @@ impl WgpuResources {
|
|||||||
panic!("expected a Sampler resource");
|
panic!("expected a Sampler resource");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BindType::Uniform { .. } => {
|
||||||
|
if let ResourceInfo::Buffer { size, .. } = resource_info {
|
||||||
|
let buffer = self.buffers.get(&resource).unwrap();
|
||||||
|
wgpu::BindingResource::Buffer {
|
||||||
|
buffer,
|
||||||
|
range: 0..*size,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("expected a Buffer resource");
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => panic!("unsupported bind type"),
|
_ => panic!("unsupported bind type"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -207,7 +191,6 @@ impl WgpuResources {
|
|||||||
(entity, bind_group_id),
|
(entity, bind_group_id),
|
||||||
BindGroupInfo {
|
BindGroupInfo {
|
||||||
bind_group,
|
bind_group,
|
||||||
unset_uniforms: Vec::new(),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user