entities with renderable.is_instanced are now removed from normal rendering

This commit is contained in:
Carter Anderson 2020-03-20 16:58:21 -07:00
parent cbba656f16
commit 71d091e10c
6 changed files with 46 additions and 32 deletions

View file

@ -96,7 +96,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
0.0,
),
renderable: Renderable {
instanced: true,
is_instanced: true,
..Default::default()
},
..Default::default()

View file

@ -162,7 +162,7 @@ fn create_person(world: &mut World, mesh_handle: Handle<Mesh>, translation: Tran
..Default::default()
},
Renderable {
instanced: true,
is_instanced: true,
..Default::default()
},
mesh_handle,

View file

@ -34,11 +34,11 @@ impl DrawTarget for AssignedMeshesDrawTarget {
for entity in assigned_entities.iter() {
// TODO: hopefully legion has better random access apis that are more like queries?
let renderable = world.get_component::<Renderable>(*entity).unwrap();
let mesh = *world.get_component::<Handle<Mesh>>(*entity).unwrap();
if !renderable.is_visible {
if !renderable.is_visible || renderable.is_instanced {
continue;
}
let mesh = *world.get_component::<Handle<Mesh>>(*entity).unwrap();
let renderer = render_pass.get_renderer();
let render_resources = renderer.get_render_resources();
if current_mesh_handle != Some(mesh) {
@ -85,7 +85,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
for entity in assigned_entities.iter() {
// TODO: hopefully legion has better random access apis that are more like queries?
let renderable = world.get_component::<Renderable>(*entity).unwrap();
if !renderable.is_visible {
if !renderable.is_visible || renderable.is_instanced {
continue;
}

View file

@ -27,7 +27,7 @@ impl DrawTarget for MeshesDrawTarget {
let mesh_query = <(Read<Handle<Mesh>>, Read<Renderable>)>::query();
for (entity, (mesh, renderable)) in mesh_query.iter_entities(world) {
if !renderable.is_visible {
if !renderable.is_visible || renderable.is_instanced {
continue;
}

View file

@ -71,19 +71,22 @@ where
let mut entity_render_resource_assignments = resources.get_mut::<EntityRenderResourceAssignments>().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) {
asset_batchers.set_entity_handle(entity, *handle);
let render_resource_assignments = entity_render_resource_assignments.get_mut_or_create(entity);
if let Some(uniforms) = asset_storage.get(&handle) {
self.setup_entity_uniform_resources(
entity,
uniforms,
renderer,
resources,
render_resource_assignments,
true,
Some(*handle),
)
for (entity, (handle, renderable)) in handle_query.iter_entities(world) {
if renderable.is_instanced {
asset_batchers.set_entity_handle(entity, *handle);
} else {
let render_resource_assignments = entity_render_resource_assignments.get_mut_or_create(entity);
if let Some(uniforms) = asset_storage.get(&handle) {
self.setup_entity_uniform_resources(
entity,
uniforms,
renderer,
resources,
render_resource_assignments,
true,
Some(*handle),
)
}
}
}
}
@ -273,6 +276,7 @@ where
}
// copy entity uniform data to buffers
// PERF: consider iter_chunks here and calling get_bytes() on each chunk?
for (name, (resource, _count, entities)) in self.uniform_buffer_info_resources.iter() {
let resource = resource.unwrap();
let size = {
@ -290,15 +294,20 @@ where
// 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)
for (entity, _) in self.resource_query.iter_entities(world) {
if !entities.contains(&entity) {
for (entity, (_, renderable)) in self.resource_query.iter_entities(world) {
if renderable.is_instanced || !entities.contains(&entity) {
continue;
}
info.offsets.insert(entity, offset as u32);
offset += alignment;
}
for (entity, _) in self.handle_query.as_ref().unwrap().iter_entities(world) {
for (entity, (_, renderable)) in self.handle_query.as_ref().unwrap().iter_entities(world) {
if renderable.is_instanced {
continue;
}
info.offsets.insert(entity, offset as u32);
offset += alignment;
}
@ -311,10 +320,10 @@ where
&mut |mapped| {
let alignment = BIND_BUFFER_ALIGNMENT as usize;
let mut offset = 0usize;
for (entity, (uniforms, _renderable)) in
for (entity, (uniforms, renderable)) in
self.resource_query.iter_entities(world)
{
if !entities.contains(&entity) {
if renderable.is_instanced || !entities.contains(&entity) {
continue;
}
if let Some(uniform_bytes) = uniforms.get_uniform_bytes_ref(&name) {
@ -329,13 +338,14 @@ where
}
if let Some(asset_storage) = resources.get::<AssetStorage<T>>() {
for (entity, (handle, _renderable)) in
for (entity, (handle, renderable)) in
self.handle_query.as_ref().unwrap().iter_entities(world)
{
let uniforms = asset_storage.get(&handle).unwrap();
if !entities.contains(&entity) {
if renderable.is_instanced ||!entities.contains(&entity) {
continue;
}
let uniforms = asset_storage.get(&handle).unwrap();
if let Some(uniform_bytes) = uniforms.get_uniform_bytes_ref(&name) {
mapped[offset..(offset + uniform_bytes.len())]
.copy_from_slice(uniform_bytes);
@ -398,7 +408,11 @@ where
self.update_asset_uniforms(renderer, world, resources);
let mut entity_render_resource_assignments = resources.get_mut::<EntityRenderResourceAssignments>().unwrap();
for (entity, (uniforms, _renderable)) in query.iter_entities(world) {
for (entity, (uniforms, renderable)) in query.iter_entities(world) {
if renderable.is_instanced {
continue;
}
let render_resource_assignments = entity_render_resource_assignments.get_mut_or_create(entity);
self.setup_entity_uniform_resources(entity, &uniforms, renderer, resources, render_resource_assignments, true, None);
}

View file

@ -11,15 +11,15 @@ use std::collections::{HashMap, HashSet};
pub struct Renderable {
pub is_visible: bool,
pub is_instanced: bool,
pub pipelines: Vec<Handle<PipelineDescriptor>>,
pub shader_defs: HashSet<String>,
pub instanced: bool,
}
impl Renderable {
pub fn instanced() -> Self {
Renderable {
instanced: false,
is_instanced: true,
..Default::default()
}
}
@ -33,7 +33,7 @@ impl Default for Renderable {
Handle::new(0), // TODO: this could be better
],
shader_defs: HashSet::new(),
instanced: false,
is_instanced: false,
}
}
}
@ -127,7 +127,7 @@ pub fn update_shader_assignments(
for (entity, mut renderable) in <Write<Renderable>>::query().iter_entities_mut(world) {
// if instancing is enabled, set the def here
if renderable.instanced {
if renderable.is_instanced {
renderable.shader_defs.insert("INSTANCING".to_string());
}