Add RenderState
This commit is contained in:
parent
a622696fe9
commit
73eceb601e
|
@ -4,10 +4,12 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cyborg = { path = "../" }
|
||||
cyborg = { path = "../", features = ["legion"] }
|
||||
egui = "0.17.0"
|
||||
egui-winit = "0.17.0"
|
||||
egui_wgpu_backend = "0.17.0"
|
||||
glam = "0.20"
|
||||
legion = "^0.4"
|
||||
pollster = "0.2"
|
||||
puffin = "^0.13"
|
||||
puffin_egui = "0.14.0"
|
||||
|
|
|
@ -9,6 +9,7 @@ use egui_winit::winit::{
|
|||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
mod render;
|
||||
mod ui;
|
||||
|
||||
struct Application {
|
||||
|
@ -22,6 +23,7 @@ struct Application {
|
|||
egui_ctx: egui::Context,
|
||||
egui_rp: EguiRenderPass,
|
||||
ui: ui::UserInterface,
|
||||
render_state: render::RenderState,
|
||||
}
|
||||
|
||||
impl Application {
|
||||
|
@ -64,6 +66,8 @@ impl Application {
|
|||
let egui_ctx = egui::Context::default();
|
||||
let egui_rp = egui_wgpu_backend::RenderPass::new(&device, config.format, 1);
|
||||
|
||||
let render_state = render::RenderState::new(device.clone(), queue.clone(), config.format);
|
||||
|
||||
Self {
|
||||
window,
|
||||
device,
|
||||
|
@ -75,6 +79,7 @@ impl Application {
|
|||
egui_ctx,
|
||||
egui_rp,
|
||||
ui: ui::UserInterface::new(),
|
||||
render_state,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,6 +109,11 @@ impl Application {
|
|||
self.egui_ctx.run(raw_input, |ctx| self.ui.run(ctx))
|
||||
};
|
||||
|
||||
{
|
||||
puffin::profile_scope!("Main render");
|
||||
self.render_state.render();
|
||||
}
|
||||
|
||||
puffin::profile_scope!("Render egui");
|
||||
|
||||
self.egui_state.handle_platform_output(
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
use crate::wgpu;
|
||||
use cyborg::camera::Camera;
|
||||
use cyborg::viewport::{Viewport, ViewportInfo, ViewportViews};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct OffscreenTextures {
|
||||
width: u32,
|
||||
height: u32,
|
||||
output_texture: wgpu::Texture,
|
||||
output_view: wgpu::TextureView,
|
||||
depth_texture: wgpu::Texture,
|
||||
depth_view: wgpu::TextureView,
|
||||
}
|
||||
|
||||
impl OffscreenTextures {
|
||||
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
||||
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
width: u32,
|
||||
height: u32,
|
||||
output_format: wgpu::TextureFormat,
|
||||
) -> Self {
|
||||
let size = wgpu::Extent3d {
|
||||
width,
|
||||
height,
|
||||
depth_or_array_layers: 1,
|
||||
};
|
||||
|
||||
let mut tex_desc = wgpu::TextureDescriptor {
|
||||
label: None,
|
||||
size,
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: output_format,
|
||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
|
||||
};
|
||||
|
||||
tex_desc.label = Some("Offscreen Output Texture");
|
||||
let output_texture = device.create_texture(&tex_desc);
|
||||
|
||||
tex_desc.label = Some("Offscreen Depth Texture");
|
||||
tex_desc.format = Self::DEPTH_FORMAT;
|
||||
let depth_texture = device.create_texture(&tex_desc);
|
||||
|
||||
let view_desc = wgpu::TextureViewDescriptor::default();
|
||||
let output_view = output_texture.create_view(&view_desc);
|
||||
let depth_view = depth_texture.create_view(&view_desc);
|
||||
|
||||
Self {
|
||||
width,
|
||||
height,
|
||||
output_texture,
|
||||
output_view,
|
||||
depth_texture,
|
||||
depth_view,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OffscreenViewport {
|
||||
device: Arc<wgpu::Device>,
|
||||
queue: Arc<wgpu::Queue>,
|
||||
output_format: wgpu::TextureFormat,
|
||||
textures: OffscreenTextures,
|
||||
}
|
||||
|
||||
impl OffscreenViewport {
|
||||
pub fn new(
|
||||
device: Arc<wgpu::Device>,
|
||||
queue: Arc<wgpu::Queue>,
|
||||
output_format: wgpu::TextureFormat,
|
||||
) -> Self {
|
||||
let textures = OffscreenTextures::new(&device, 640, 480, output_format);
|
||||
|
||||
Self {
|
||||
device,
|
||||
queue,
|
||||
output_format,
|
||||
textures,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_camera(&self) -> Camera {
|
||||
Camera {
|
||||
eye: [1.0, 1.0, 1.0, 0.0],
|
||||
vp: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Viewport for OffscreenViewport {
|
||||
fn get_info(&self) -> ViewportInfo {
|
||||
ViewportInfo {
|
||||
output_format: self.output_format,
|
||||
depth_format: OffscreenTextures::DEPTH_FORMAT,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_queue(&self) -> &wgpu::Queue {
|
||||
&self.queue
|
||||
}
|
||||
|
||||
fn get_views(&self) -> ViewportViews {
|
||||
ViewportViews {
|
||||
output: &self.textures.output_view,
|
||||
depth: &self.textures.depth_view,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ViewportStore {
|
||||
device: Arc<wgpu::Device>,
|
||||
output_format: wgpu::TextureFormat,
|
||||
viewport: OffscreenViewport,
|
||||
}
|
||||
|
||||
impl ViewportStore {
|
||||
pub fn new(
|
||||
device: Arc<wgpu::Device>,
|
||||
queue: Arc<wgpu::Queue>,
|
||||
output_format: wgpu::TextureFormat,
|
||||
) -> Self {
|
||||
Self {
|
||||
device: device.clone(),
|
||||
output_format,
|
||||
viewport: OffscreenViewport::new(device, queue, output_format),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl cyborg::legion::RenderCallbacks for ViewportStore {
|
||||
fn get_viewports(&mut self) -> Vec<(&dyn Viewport, Camera)> {
|
||||
vec![(&self.viewport, self.viewport.get_camera())]
|
||||
}
|
||||
|
||||
fn present(&mut self) {}
|
||||
}
|
||||
|
||||
pub struct RenderState {
|
||||
pub world: legion::World,
|
||||
pub resources: legion::Resources,
|
||||
pub render_schedule: legion::Schedule,
|
||||
}
|
||||
|
||||
impl RenderState {
|
||||
pub fn new(
|
||||
device: Arc<wgpu::Device>,
|
||||
queue: Arc<wgpu::Queue>,
|
||||
output_format: wgpu::TextureFormat,
|
||||
) -> Self {
|
||||
use cyborg::shader::{ShaderStore, ShaderWatcher};
|
||||
|
||||
let mut world = legion::World::default();
|
||||
let mut resources = legion::Resources::default();
|
||||
let viewport_store = ViewportStore::new(device.clone(), queue.clone(), output_format);
|
||||
|
||||
let renderer = cyborg::Renderer::new(device.clone(), queue.clone());
|
||||
resources.insert(renderer);
|
||||
|
||||
let viewport_info = ViewportInfo {
|
||||
output_format,
|
||||
depth_format: OffscreenTextures::DEPTH_FORMAT,
|
||||
};
|
||||
resources.insert(viewport_info);
|
||||
|
||||
let shader_store = Arc::new(ShaderStore::new(device.clone()));
|
||||
let shaders_dir = std::env::current_dir().unwrap();
|
||||
let shaders_dir = shaders_dir.join("shaders/");
|
||||
let shader_watcher = ShaderWatcher::new(shader_store.to_owned(), shaders_dir).unwrap();
|
||||
|
||||
let mesh_forward = shader_watcher.add_file("mesh_forward.wgsl").unwrap();
|
||||
let mesh_skinning = shader_watcher.add_file("mesh_skinning.wgsl").unwrap();
|
||||
|
||||
let mesh_shaders = cyborg::pass::mesh::ShaderInfo {
|
||||
store: shader_store.clone(),
|
||||
forward: mesh_forward,
|
||||
skinning: mesh_skinning,
|
||||
};
|
||||
|
||||
resources.insert(mesh_shaders);
|
||||
|
||||
let mut render_schedule = legion::Schedule::builder();
|
||||
cyborg::legion::build_renderer(viewport_store, &mut resources, &mut render_schedule);
|
||||
let render_schedule = render_schedule.build();
|
||||
|
||||
world.push((
|
||||
cyborg::scene::Transform {
|
||||
transform: Default::default(),
|
||||
},
|
||||
cyborg::scene::DebugDrawList {
|
||||
vertices: vec![
|
||||
cyborg::scene::DebugVertex {
|
||||
color: [1.0, 0.0, 0.0],
|
||||
position: [0.0, 0.0, -1.0],
|
||||
},
|
||||
cyborg::scene::DebugVertex {
|
||||
color: [0.0, 0.0, 1.0],
|
||||
position: [0.0, 0.0, 1.0],
|
||||
},
|
||||
],
|
||||
indices: vec![0, 1],
|
||||
},
|
||||
));
|
||||
|
||||
Self {
|
||||
world,
|
||||
resources,
|
||||
render_schedule,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(&mut self) {
|
||||
self.render_schedule
|
||||
.execute(&mut self.world, &mut self.resources);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue