fix ui draw target

This commit is contained in:
Carter Anderson 2020-03-08 20:27:07 -07:00
parent e0a1a83bc9
commit c5f781b4e5
7 changed files with 76 additions and 84 deletions

View File

@ -6,15 +6,7 @@ use crate::{
use legion::prelude::World; use legion::prelude::World;
// A set of draw calls. ex: get + draw meshes, get + draw instanced meshes, draw ui meshes, etc // A set of draw calls. ex: get + draw meshes, get + draw instanced meshes, draw ui meshes, etc
pub trait DrawTarget {
// TODO: consider swapping out dyn RenderPass for explicit WgpuRenderPass type to avoid dynamic dispatch
pub type DrawTarget = fn(
world: &World,
render_pass: &mut dyn RenderPass,
pipeline_handle: Handle<PipelineDescriptor>,
);
pub trait NewDrawTarget {
fn draw( fn draw(
&self, &self,
world: &World, world: &World,

View File

@ -2,7 +2,7 @@ use crate::{
asset::{AssetStorage, Handle, Mesh}, asset::{AssetStorage, Handle, Mesh},
legion::prelude::*, legion::prelude::*,
render::render_graph::{ render::render_graph::{
resource_name, NewDrawTarget, PipelineDescriptor, RenderPass, Renderable, ResourceInfo, resource_name, DrawTarget, PipelineDescriptor, RenderPass, Renderable, ResourceInfo,
ShaderPipelineAssignments, ShaderPipelineAssignments,
}, },
}; };
@ -10,7 +10,7 @@ use crate::{
#[derive(Default)] #[derive(Default)]
pub struct AssignedMeshesDrawTarget; pub struct AssignedMeshesDrawTarget;
impl NewDrawTarget for AssignedMeshesDrawTarget { impl DrawTarget for AssignedMeshesDrawTarget {
fn draw( fn draw(
&self, &self,
world: &World, world: &World,

View File

@ -3,7 +3,7 @@ use crate::{
legion::prelude::*, legion::prelude::*,
render::{ render::{
render_graph::{ render_graph::{
resource_name, NewDrawTarget, PipelineDescriptor, RenderPass, Renderable, ResourceInfo, resource_name, DrawTarget, PipelineDescriptor, RenderPass, Renderable, ResourceInfo,
}, },
Instanced, Instanced,
}, },
@ -12,7 +12,7 @@ use crate::{
#[derive(Default)] #[derive(Default)]
pub struct MeshesDrawTarget; pub struct MeshesDrawTarget;
impl NewDrawTarget for MeshesDrawTarget { impl DrawTarget for MeshesDrawTarget {
fn draw( fn draw(
&self, &self,
world: &World, world: &World,

View File

@ -2,92 +2,92 @@ use crate::{
asset::{AssetStorage, Handle, Mesh}, asset::{AssetStorage, Handle, Mesh},
legion::prelude::*, legion::prelude::*,
render::render_graph::{ render::render_graph::{
resource_name, NewDrawTarget, PipelineDescriptor, RenderPass, ResourceInfo, resource_name, DrawTarget, PipelineDescriptor, RenderPass, RenderResource, ResourceInfo,
}, },
}; };
use zerocopy::AsBytes; use zerocopy::AsBytes;
#[derive(Default)] #[derive(Default)]
pub struct UiDrawTarget; pub struct UiDrawTarget {
pub mesh_vertex_buffer: Option<RenderResource>,
pub mesh_index_buffer: Option<RenderResource>,
pub mesh_index_length: usize,
}
impl NewDrawTarget for UiDrawTarget { impl DrawTarget for UiDrawTarget {
fn draw( fn draw(
&self, &self,
_world: &World, _world: &World,
_render_pass: &mut dyn RenderPass, render_pass: &mut dyn RenderPass,
_pipeline_handle: Handle<PipelineDescriptor>, _pipeline_handle: Handle<PipelineDescriptor>,
) { ) {
// TODO: re-add support for this let ui_instances_buffer = {
// let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap(); let renderer = render_pass.get_renderer();
// let mut current_mesh_vertex_buffer = None; match renderer
// let mut current_mesh_index_buffer = None; .get_render_resources()
// let ui_instances_buffer = { .get_named_resource(resource_name::buffer::UI_INSTANCES)
// let renderer = render_pass.get_renderer(); {
// match renderer.get_render_resources().get_named_resource(resource_name::buffer::UI_INSTANCES) { Some(buffer) => buffer,
// Some(buffer) => buffer, None => return,
// None => return, }
// } };
// };
// // NOTE: this is ugly and borrowing is stupid
// let result = {
// let renderer = render_pass.get_renderer();
// let result = if let Some(ResourceInfo::InstanceBuffer { count, mesh_id, .. }) =
// renderer.get_resource_info(ui_instances_buffer)
// {
// Some((*count, *mesh_id))
// } else {
// None
// };
// if let Some((instance_count, mesh_id)) = result { let index_count = {
// if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) { let renderer = render_pass.get_renderer();
// if let Some(buffer) = current_mesh_vertex_buffer { if let Some(ResourceInfo::InstanceBuffer { count, .. }) =
// renderer.remove_buffer(buffer); renderer.get_resource_info(ui_instances_buffer)
// } {
Some(*count)
} else {
None
}
};
// if let Some(buffer) = current_mesh_index_buffer { render_pass.set_bind_groups(None);
// renderer.remove_buffer(buffer); render_pass.set_index_buffer(self.mesh_index_buffer.unwrap(), 0);
// } render_pass.set_vertex_buffer(0, self.mesh_vertex_buffer.unwrap(), 0);
// current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data( render_pass.set_vertex_buffer(1, ui_instances_buffer, 0);
// mesh_asset.vertices.as_bytes(), render_pass.draw_indexed(0..self.mesh_index_length as u32, 0, 0..(index_count.unwrap() as u32));
// wgpu::BufferUsage::VERTEX,
// ));
// current_mesh_index_buffer = Some(renderer.create_buffer_with_data(
// mesh_asset.indices.as_bytes(),
// wgpu::BufferUsage::INDEX,
// ));
// Some((instance_count, mesh_asset.indices.len()))
// } else {
// None
// }
// } else {
// None
// }
// };
// if let Some((instance_count, indices_length)) = result {
// render_pass.setup_bind_groups(None);
// render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0);
// render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0);
// render_pass.set_vertex_buffer(1, ui_instances_buffer, 0);
// render_pass.draw_indexed(0..indices_length as u32, 0, 0..(instance_count as u32));
// }
// let renderer = render_pass.get_renderer();
// if let Some(buffer) = current_mesh_vertex_buffer {
// renderer.remove_buffer(buffer);
// }
// if let Some(buffer) = current_mesh_index_buffer {
// renderer.remove_buffer(buffer);
// }
} }
fn setup( fn setup(
&mut self, &mut self,
_world: &World, world: &World,
_renderer: &mut dyn crate::render::render_graph::Renderer, renderer: &mut dyn crate::render::render_graph::Renderer,
_pipeline_handle: Handle<PipelineDescriptor>, _pipeline_handle: Handle<PipelineDescriptor>,
) { ) {
// don't create meshes if they have already been created
if let Some(_) = self.mesh_vertex_buffer {
return;
}
let ui_instances_buffer = {
match renderer
.get_render_resources()
.get_named_resource(resource_name::buffer::UI_INSTANCES)
{
Some(buffer) => buffer,
None => return,
}
};
if let ResourceInfo::InstanceBuffer { mesh_id, .. } =
renderer.get_resource_info(ui_instances_buffer).unwrap()
{
let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
if let Some(mesh_asset) = mesh_storage.get_id(*mesh_id) {
self.mesh_vertex_buffer = Some(renderer.create_buffer_with_data(
mesh_asset.vertices.as_bytes(),
wgpu::BufferUsage::VERTEX,
));
self.mesh_index_buffer = Some(renderer.create_buffer_with_data(
mesh_asset.indices.as_bytes(),
wgpu::BufferUsage::INDEX,
));
self.mesh_index_length = mesh_asset.indices.len();
};
}
} }
fn get_name(&self) -> String { fn get_name(&self) -> String {
resource_name::draw_target::UI.to_string() resource_name::draw_target::UI.to_string()

View File

@ -1,5 +1,5 @@
use super::{ use super::{
NewDrawTarget, PassDescriptor, PipelineDescriptor, ResourceProvider, TextureDescriptor, DrawTarget, PassDescriptor, PipelineDescriptor, ResourceProvider, TextureDescriptor,
}; };
use crate::asset::{AssetStorage, Handle}; use crate::asset::{AssetStorage, Handle};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@ -11,7 +11,7 @@ pub struct RenderGraph {
pub pass_pipelines: HashMap<String, Vec<Handle<PipelineDescriptor>>>, pub pass_pipelines: HashMap<String, Vec<Handle<PipelineDescriptor>>>,
pub resource_providers: Vec<Box<dyn ResourceProvider>>, pub resource_providers: Vec<Box<dyn ResourceProvider>>,
pub queued_textures: Vec<(String, TextureDescriptor)>, pub queued_textures: Vec<(String, TextureDescriptor)>,
pub draw_targets: HashMap<String, Box<dyn NewDrawTarget>>, pub draw_targets: HashMap<String, Box<dyn DrawTarget>>,
} }
impl Default for RenderGraph { impl Default for RenderGraph {
@ -102,7 +102,7 @@ impl RenderGraphBuilder {
pub fn add_draw_target<T>(mut self, draw_target: T) -> Self pub fn add_draw_target<T>(mut self, draw_target: T) -> Self
where where
T: NewDrawTarget + 'static, T: DrawTarget + 'static,
{ {
self.render_graph self.render_graph
.draw_targets .draw_targets

View File

@ -100,7 +100,7 @@ pub trait Renderer {
pub trait RenderPass { pub trait RenderPass {
// TODO: consider using static dispatch for the renderer: Renderer<WgpuBackend>. compare compile times // TODO: consider using static dispatch for the renderer: Renderer<WgpuBackend>. compare compile times
fn get_renderer(&mut self) -> &dyn Renderer; fn get_renderer(&self) -> &dyn Renderer;
fn get_pipeline_descriptor(&self) -> &PipelineDescriptor; fn get_pipeline_descriptor(&self) -> &PipelineDescriptor;
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64); fn set_index_buffer(&mut self, resource: RenderResource, offset: u64);
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64); fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64);

View File

@ -12,7 +12,7 @@ pub struct WgpuRenderPass<'a, 'b, 'c, 'd> {
} }
impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> { impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
fn get_renderer(&mut self) -> &dyn Renderer { fn get_renderer(&self) -> &dyn Renderer {
self.renderer self.renderer
} }