mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
more renderer work
This commit is contained in:
parent
7b89531268
commit
bcd7dae0ec
8 changed files with 126 additions and 90 deletions
|
@ -7,10 +7,14 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// A set of draw calls. ex: get + draw meshes, get + draw instanced meshes, draw ui meshes, etc
|
||||
pub type DrawTarget = fn(world: &World, render_pass: &mut dyn RenderPass);
|
||||
|
||||
pub fn mesh_draw_target(world: &World, _render_pass: &mut dyn RenderPass) {
|
||||
const MESH_VERTEX_BUFFER_NAME: &str = "TempMeshVertexBuffer";
|
||||
const MESH_INDEX_BUFFER_NAME: &str = "TempMeshIndexBuffer";
|
||||
pub fn mesh_draw_target(world: &World, render_pass: &mut dyn RenderPass) {
|
||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||
let mut last_mesh_id = None;
|
||||
let mesh_query =
|
||||
|
@ -24,18 +28,27 @@ pub fn mesh_draw_target(world: &World, _render_pass: &mut dyn RenderPass) {
|
|||
}
|
||||
|
||||
if should_load_mesh {
|
||||
if let Some(_mesh_asset) = mesh_storage.get(mesh.id) {
|
||||
// render_pass.load_mesh(mesh.id, mesh_asset);
|
||||
// render_pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
||||
// render_pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
||||
if let Some(mesh_asset) = mesh_storage.get(mesh.id) {
|
||||
let renderer = render_pass.get_renderer();
|
||||
renderer.create_buffer_with_data(MESH_VERTEX_BUFFER_NAME, mesh_asset.vertices.as_bytes(), wgpu::BufferUsage::VERTEX);
|
||||
renderer.create_buffer_with_data(MESH_INDEX_BUFFER_NAME, mesh_asset.indices.as_bytes(), wgpu::BufferUsage::INDEX);
|
||||
|
||||
// TODO: Verify buffer format matches render pass
|
||||
render_pass.set_index_buffer(MESH_INDEX_BUFFER_NAME, 0);
|
||||
render_pass.set_vertex_buffer(0, MESH_VERTEX_BUFFER_NAME, 0);
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(ref _mesh_asset) = mesh_storage.get(mesh.id) {
|
||||
if let Some(mesh_asset) = mesh_storage.get(mesh.id) {
|
||||
// pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
|
||||
// pass.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1);
|
||||
render_pass.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1);
|
||||
};
|
||||
|
||||
last_mesh_id = Some(current_mesh_id);
|
||||
}
|
||||
|
||||
// cleanup buffers
|
||||
let renderer = render_pass.get_renderer();
|
||||
renderer.remove_buffer(MESH_VERTEX_BUFFER_NAME);
|
||||
renderer.remove_buffer(MESH_INDEX_BUFFER_NAME);
|
||||
}
|
|
@ -3,6 +3,7 @@ use std::collections::HashMap;
|
|||
|
||||
pub struct RenderGraph {
|
||||
pub pipeline_descriptors: HashMap<String, PipelineDescriptor>,
|
||||
// TODO: make this ordered
|
||||
pub pass_descriptors: HashMap<String, PassDescriptor>,
|
||||
pub pass_pipelines: HashMap<String, Vec<String>>,
|
||||
pub resource_providers: Vec<Box<dyn ResourceProvider>>,
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
use crate::{asset::Mesh, legion::prelude::*, render::render_graph_2::{RenderGraph, Buffer, ResourceId}};
|
||||
use crate::{legion::prelude::*, render::render_graph_2::{RenderGraph, BufferInfo, PipelineDescriptor}};
|
||||
use std::ops::Range;
|
||||
|
||||
pub trait Renderer {
|
||||
fn initialize(&mut self, world: &mut World);
|
||||
fn resize(&mut self, world: &mut World, width: u32, height: u32);
|
||||
fn process_render_graph(&mut self, render_graph: &RenderGraph, world: &mut World);
|
||||
// TODO: swap out wgpu::BufferUsage for custom type
|
||||
fn create_buffer_with_data(&mut self, data: &[u8], buffer_usage: wgpu::BufferUsage) -> Buffer;
|
||||
fn free_buffer(&mut self, id: ResourceId) -> Buffer;
|
||||
fn create_buffer_with_data(&mut self, name: &str, data: &[u8], buffer_usage: wgpu::BufferUsage);
|
||||
fn remove_buffer(&mut self, name: &str);
|
||||
fn get_buffer_info(&self, name: &str) -> Option<&BufferInfo>;
|
||||
}
|
||||
|
||||
pub trait RenderPass {
|
||||
fn set_index_buffer(&mut self, buffer: &wgpu::Buffer, offset: wgpu::BufferAddress);
|
||||
fn get_renderer(&mut self) -> &mut dyn Renderer;
|
||||
fn get_pipeline_descriptor(&self) -> &PipelineDescriptor;
|
||||
fn set_index_buffer(&mut self, name: &str, offset: u64);
|
||||
fn set_vertex_buffer(&mut self, start_slot: u32, name: &str, offset: u64);
|
||||
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
pub type ResourceId = u64;
|
||||
// pub type ResourceId = u64;
|
||||
|
||||
pub struct Buffer {
|
||||
pub id: ResourceId,
|
||||
pub struct BufferInfo {
|
||||
pub size: u64,
|
||||
pub buffer_usage: wgpu::BufferUsage,
|
||||
// pub layout: Option<
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
pub mod texture {
|
||||
pub const SWAP_CHAIN: &str = "SwapChain";
|
||||
}
|
||||
|
||||
pub mod uniform {
|
||||
pub const CAMERA: &str = "Camera";
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
use crate::render::{render_graph_2::Renderer, ActiveCamera, Camera};
|
||||
use crate::render::{
|
||||
render_graph_2::{resource_name, Renderer},
|
||||
ActiveCamera, Camera,
|
||||
};
|
||||
use bevy_transform::prelude::LocalToWorld;
|
||||
use legion::prelude::*;
|
||||
use std::mem;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
pub trait ResourceProvider {
|
||||
|
@ -12,7 +14,7 @@ pub trait ResourceProvider {
|
|||
pub struct CameraResourceProvider;
|
||||
|
||||
impl ResourceProvider for CameraResourceProvider {
|
||||
fn update(&self, renderer: &mut dyn Renderer, world: &mut World) {}
|
||||
fn update(&self, _renderer: &mut dyn Renderer, _world: &mut World) {}
|
||||
fn resize(&self, renderer: &mut dyn Renderer, world: &mut World, width: u32, height: u32) {
|
||||
for (mut camera, local_to_world, _) in
|
||||
<(Write<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query().iter_mut(world)
|
||||
|
@ -20,23 +22,12 @@ impl ResourceProvider for CameraResourceProvider {
|
|||
camera.update(width, height);
|
||||
let camera_matrix: [[f32; 4]; 4] =
|
||||
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
||||
let matrix_size = mem::size_of::<[[f32; 4]; 4]>() as u64;
|
||||
// TODO: use staging buffer?
|
||||
let buffer = renderer
|
||||
.create_buffer_with_data(camera_matrix.as_bytes(), wgpu::BufferUsage::UNIFORM);
|
||||
// let temp_camera_buffer = render_graph
|
||||
// .device
|
||||
// .create_buffer_with_data(camera_matrix.as_bytes(), wgpu::BufferUsage::COPY_SRC);
|
||||
// let forward_uniform_buffer = render_graph
|
||||
// .get_uniform_buffer(FORWARD_UNIFORM_BUFFER_NAME)
|
||||
// .unwrap();
|
||||
// encoder.copy_buffer_to_buffer(
|
||||
// &temp_camera_buffer,
|
||||
// 0,
|
||||
// &forward_uniform_buffer.buffer,
|
||||
// 0,
|
||||
// matrix_size,
|
||||
// );
|
||||
renderer.create_buffer_with_data(
|
||||
resource_name::uniform::CAMERA,
|
||||
camera_matrix.as_bytes(),
|
||||
wgpu::BufferUsage::UNIFORM,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
use crate::prelude::*;
|
||||
use crate::{
|
||||
asset::Texture,
|
||||
legion::{
|
||||
borrow::{Ref, RefMap},
|
||||
borrow::RefMap,
|
||||
prelude::{Entity, World},
|
||||
},
|
||||
render::render_graph_2::{UniformPropertyType, Binding, BindType},
|
||||
render::Albedo,
|
||||
render::render_graph_2::{UniformPropertyType, BindType},
|
||||
math::Vec4,
|
||||
};
|
||||
use zerocopy::AsBytes;
|
||||
|
@ -38,15 +35,16 @@ pub trait GetBytes {
|
|||
fn get_bytes_ref(&self) -> Option<&[u8]>;
|
||||
}
|
||||
|
||||
impl GetBytes for dyn AsBytes {
|
||||
fn get_bytes(&self) -> Vec<u8> {
|
||||
self.as_bytes().into()
|
||||
}
|
||||
// TODO: might need to add zerocopy to this crate to impl AsBytes for external crates
|
||||
// impl GetBytes for dyn AsBytes {
|
||||
// fn get_bytes(&self) -> Vec<u8> {
|
||||
// self.as_bytes().into()
|
||||
// }
|
||||
|
||||
fn get_bytes_ref(&self) -> Option<&[u8]> {
|
||||
Some(self.as_bytes())
|
||||
}
|
||||
}
|
||||
// fn get_bytes_ref(&self) -> Option<&[u8]> {
|
||||
// Some(self.as_bytes())
|
||||
// }
|
||||
// }
|
||||
|
||||
impl GetBytes for Vec4 {
|
||||
fn get_bytes(&self) -> Vec<u8> {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
legion::prelude::*,
|
||||
render::render_graph_2::{
|
||||
resource_name, BindType, Buffer, PassDescriptor, PipelineDescriptor, RenderGraph,
|
||||
resource_name, BindType, BufferInfo, PassDescriptor, PipelineDescriptor, RenderGraph,
|
||||
RenderPass, RenderPassColorAttachmentDescriptor,
|
||||
RenderPassDepthStencilAttachmentDescriptor, Renderer, TextureDimension,
|
||||
},
|
||||
|
@ -14,7 +14,7 @@ pub struct WgpuRenderer {
|
|||
pub surface: Option<wgpu::Surface>,
|
||||
pub swap_chain_descriptor: wgpu::SwapChainDescriptor,
|
||||
pub render_pipelines: HashMap<String, wgpu::RenderPipeline>,
|
||||
pub buffers: HashMap<String, wgpu::Buffer>,
|
||||
pub buffers: HashMap<String, Buffer<wgpu::Buffer>>,
|
||||
pub textures: HashMap<String, wgpu::TextureView>,
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ impl WgpuRenderer {
|
|||
.map(|(i, binding)| wgpu::BindGroupLayoutBinding {
|
||||
binding: i as u32,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: (&binding.bind_type).into()
|
||||
ty: (&binding.bind_type).into(),
|
||||
})
|
||||
.collect::<Vec<wgpu::BindGroupLayoutBinding>>();
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
|
@ -252,8 +252,10 @@ impl Renderer for WgpuRenderer {
|
|||
|
||||
let mut render_pass = WgpuRenderPass {
|
||||
render_pass: &mut render_pass,
|
||||
renderer: &self,
|
||||
renderer: self,
|
||||
pipeline_descriptor,
|
||||
};
|
||||
|
||||
for draw_target in pipeline_descriptor.draw_targets.iter() {
|
||||
draw_target(world, &mut render_pass);
|
||||
}
|
||||
|
@ -265,46 +267,62 @@ impl Renderer for WgpuRenderer {
|
|||
let command_buffer = encoder.finish();
|
||||
self.queue.submit(&[command_buffer]);
|
||||
}
|
||||
fn create_buffer_with_data(&mut self, data: &[u8], buffer_usage: wgpu::BufferUsage) -> Buffer {
|
||||
|
||||
fn create_buffer_with_data(
|
||||
&mut self,
|
||||
name: &str,
|
||||
data: &[u8],
|
||||
buffer_usage: wgpu::BufferUsage,
|
||||
) {
|
||||
let buffer = self.device.create_buffer_with_data(data, buffer_usage);
|
||||
// TODO: FILL THIS IN
|
||||
Buffer {
|
||||
buffer_usage,
|
||||
size: data.len() as u64,
|
||||
id: 0,
|
||||
}
|
||||
}
|
||||
fn free_buffer(&mut self, id: super::ResourceId) -> super::Buffer {
|
||||
unimplemented!()
|
||||
self.buffers.insert(
|
||||
name.to_string(),
|
||||
Buffer {
|
||||
buffer,
|
||||
buffer_info: BufferInfo {
|
||||
buffer_usage,
|
||||
size: data.len() as u64,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// fn load_mesh(&mut self, asset_id: usize, mesh: &Mesh) {
|
||||
// if let None = mesh.vertex_buffer {
|
||||
// self.buffers.insert(
|
||||
// format!("meshv{}", asset_id),
|
||||
// self.device
|
||||
// .create_buffer_with_data(mesh.vertices.as_bytes(), wgpu::BufferUsage::VERTEX),
|
||||
// );
|
||||
// }
|
||||
fn get_buffer_info(&self, name: &str) -> Option<&BufferInfo> {
|
||||
self.buffers.get(name).map(|b| &b.buffer_info)
|
||||
}
|
||||
|
||||
// if let None = mesh.index_buffer {
|
||||
// self.buffers.insert(
|
||||
// format!("meshi{}", asset_id),
|
||||
// self.device
|
||||
// .create_buffer_with_data(mesh.indices.as_bytes(), wgpu::BufferUsage::INDEX),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
fn remove_buffer(&mut self, name: &str) {
|
||||
self.buffers.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WgpuRenderPass<'a, 'b, 'c> {
|
||||
pub struct WgpuRenderPass<'a, 'b, 'c, 'd> {
|
||||
pub render_pass: &'b mut wgpu::RenderPass<'a>,
|
||||
pub renderer: &'c WgpuRenderer,
|
||||
pub pipeline_descriptor: &'c PipelineDescriptor,
|
||||
pub renderer: &'d mut WgpuRenderer,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c> RenderPass for WgpuRenderPass<'a, 'b, 'c> {
|
||||
fn set_index_buffer(&mut self, buffer: &wgpu::Buffer, offset: wgpu::BufferAddress) {
|
||||
self.render_pass.set_index_buffer(buffer, offset);
|
||||
impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c,'d> {
|
||||
fn get_renderer(&mut self) -> &mut dyn Renderer {
|
||||
self.renderer
|
||||
}
|
||||
|
||||
fn get_pipeline_descriptor(&self) -> &PipelineDescriptor {
|
||||
self.pipeline_descriptor
|
||||
}
|
||||
|
||||
fn set_vertex_buffer(&mut self, start_slot: u32, name: &str, offset: u64) {
|
||||
let buffer = self.renderer.buffers.get(name).unwrap();
|
||||
self.render_pass.set_vertex_buffers(start_slot, &[(&buffer.buffer, offset)]);
|
||||
}
|
||||
|
||||
fn set_index_buffer(&mut self, name: &str, offset: u64) {
|
||||
let buffer = self.renderer.buffers.get(name).unwrap();
|
||||
self.render_pass.set_index_buffer(&buffer.buffer, offset);
|
||||
}
|
||||
|
||||
fn draw_indexed(&mut self, indices: core::ops::Range<u32>, base_vertex: i32, instances: core::ops::Range<u32>) {
|
||||
self.render_pass.draw_indexed(indices, base_vertex, instances);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,12 +342,14 @@ impl From<TextureDimension> for wgpu::TextureViewDimension {
|
|||
impl From<&BindType> for wgpu::BindingType {
|
||||
fn from(bind_type: &BindType) -> Self {
|
||||
match bind_type {
|
||||
BindType::Uniform { dynamic, properties: _ } => {
|
||||
wgpu::BindingType::UniformBuffer { dynamic: *dynamic }
|
||||
}
|
||||
BindType::Buffer { dynamic, readonly } => {
|
||||
wgpu::BindingType::StorageBuffer { dynamic: *dynamic, readonly: *readonly }
|
||||
}
|
||||
BindType::Uniform {
|
||||
dynamic,
|
||||
properties: _,
|
||||
} => wgpu::BindingType::UniformBuffer { dynamic: *dynamic },
|
||||
BindType::Buffer { dynamic, readonly } => wgpu::BindingType::StorageBuffer {
|
||||
dynamic: *dynamic,
|
||||
readonly: *readonly,
|
||||
},
|
||||
BindType::SampledTexture {
|
||||
dimension,
|
||||
multisampled,
|
||||
|
@ -338,10 +358,14 @@ impl From<&BindType> for wgpu::BindingType {
|
|||
multisampled: *multisampled,
|
||||
},
|
||||
BindType::Sampler => wgpu::BindingType::Sampler,
|
||||
BindType::StorageTexture { dimension } => {
|
||||
wgpu::BindingType::StorageTexture { dimension: (*dimension).into() }
|
||||
BindType::StorageTexture { dimension } => wgpu::BindingType::StorageTexture {
|
||||
dimension: (*dimension).into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
pub struct Buffer<T> {
|
||||
pub buffer: T,
|
||||
pub buffer_info: BufferInfo,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue