ECS'ing it up, lost rendering though, bummer

This commit is contained in:
2021-02-02 00:46:47 -08:00
parent a38c8e3f36
commit df13db5270
4 changed files with 387 additions and 225 deletions

View File

@@ -19,6 +19,7 @@ use std::rc::Rc;
use wgpu::Buffer;
use winit::platform::unix::x11::ffi::Time;
use legion::*;
use std::sync::Arc;
mod framework;
mod geometry;
@@ -118,8 +119,8 @@ struct DirectionalLight {
#[derive(Clone, Debug)]
struct Mesh {
index_buffer: Rc<Buffer>,
vertex_buffer: Rc<Buffer>,
index_buffer: Arc<Buffer>,
vertex_buffer: Arc<Buffer>,
}
fn main() {
@@ -138,31 +139,6 @@ fn main() {
use legion::*;
let mut world = World::default();
// This could be used for relationships between entities...???
let entity: Entity = world.push((
cgmath::Point3 {
x: -5.0,
y: 7.0,
z: 10.0,
},
DirectionalLight {
color: wgpu::Color {
r: 1.0,
g: 0.5,
b: 0.5,
a: 1.0,
},
fov: 45.0,
depth: RangeCopy { start: 1.0, end: 20.0 },
}
));
let entities: &[Entity] = world.extend(vec![
(Position { x: 0.0, y: 0.0 }, Velocity { dx: 0.0, dy: 0.0 }),
(Position { x: 1.0, y: 1.0 }, Velocity { dx: 0.0, dy: 0.0 }),
(Position { x: 2.0, y: 2.0 }, Velocity { dx: 0.0, dy: 0.0 }),
]);
/*
Querying entities by their handle
@@ -180,8 +156,14 @@ fn main() {
}
*/
// construct a schedule (you should do this on init)
let mut schedule = Schedule::builder()
#[cfg(not(target_arch = "wasm32"))]
let (mut pool, spawner) = {
let local_pool = futures::executor::LocalPool::new();
let spawner = local_pool.spawner();
(local_pool, spawner)
};
let mut render_schedule = Schedule::builder()
.add_system(render::render_test_system())
.build();
@@ -193,7 +175,7 @@ fn main() {
// you can then iterate through the components found in the world
for position in query.iter(&world) {
println!("{:?}", position);
//println!("{:?}", position);
}
let event_loop = EventLoop::new();
@@ -207,109 +189,10 @@ fn main() {
builder = builder.with_no_redirection_bitmap(true);
}
// I think right here is where I can start pulling everything into the renderer
let window = builder.build(&event_loop).unwrap();
log::info!("Initializing the surface...");
// Grab the GPU instance, and query its features
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
let (size, surface) = unsafe {
let size = window.inner_size();
let surface = instance.create_surface(&window);
(size, surface)
};
let adapter =
instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: Some(&surface),
});
let adapter = futures::executor::block_on(adapter).unwrap();
let optional_features = Renderer::optional_features();
let required_features = Renderer::required_features();
let adapter_features = adapter.features();
// assert!(
// adapter_features.contains(required_features),
// "Adapter does not support required features for this example: {:?}",
// required_features - adapter_features
// );
let needed_limits = wgpu::Limits::default();//Renderer::required_limits();
// Maybe for debug tracing???
let trace_dir = std::env::var("WGPU_TRACE");
// And then get the device we want
let device = adapter
.request_device(
&wgpu::DeviceDescriptor {
features: (optional_features & adapter_features) | required_features,
limits: needed_limits,
shader_validation: true,
},
trace_dir.ok().as_ref().map(std::path::Path::new),
);
let (device, queue) = futures::executor::block_on(device).unwrap();
let device = Rc::new(device);
#[cfg(not(target_arch = "wasm32"))]
let (mut pool, spawner) = {
let local_pool = futures::executor::LocalPool::new();
let spawner = local_pool.spawner();
(local_pool, spawner)
};
// This is some gross-ass web shit
/*#[cfg(target_arch = "wasm32")]
let spawner = {
use futures::{future::LocalFutureObj, task::SpawnError};
use winit::platform::web::WindowExtWebSys;
struct WebSpawner {}
impl LocalSpawn for WebSpawner {
fn spawn_local_obj(
&self,
future: LocalFutureObj<'static, ()>,
) -> Result<(), SpawnError> {
Ok(wasm_bindgen_futures::spawn_local(future))
}
}
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
// On wasm, append the canvas to the document body
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| doc.body())
.and_then(|body| {
body.append_child(&web_sys::Element::from(window.canvas()))
.ok()
})
.expect("couldn't append canvas to document body");
WebSpawner {}
};*/
let mut sc_desc = wgpu::SwapChainDescriptor {
// Allows a texture to be a output attachment of a renderpass.
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: if cfg!(target_arch = "wasm32") {
wgpu::TextureFormat::Bgra8Unorm
} else {
wgpu::TextureFormat::Bgra8UnormSrgb
},
width: size.width,
height: size.height,
// The presentation engine waits for the next vertical blanking period to update
present_mode: wgpu::PresentMode::Mailbox,
};
let mut swap_chain = device.create_swap_chain(&surface, &sc_desc);
log::info!("Done doing the loading part...");
// Not sure why this is guarded, maybe we don't handle the event loop timing?
#[cfg(not(target_arch = "wasm32"))]
@@ -318,12 +201,49 @@ fn main() {
log::info!("Entering render loop...");
// Load up the renderer (and the resources)
let mut renderer = render::Renderer::init(device.clone(), &sc_desc);
let mut renderer = render::Renderer::init(window);
let (plane_vertex_buffer, plane_index_buffer) = Renderer::load_mesh_to_buffer(device.clone(), "./resources/untitled.obj");
let (plane_vertex_buffer, plane_index_buffer) = renderer.load_mesh_to_buffer("./resources/untitled.obj");
// This could be used for relationships between entities...???
let light_entity: Entity = world.push((
cgmath::Point3 {
x: -5.0,
y: 7.0,
z: 10.0,
},
DirectionalLight {
color: wgpu::Color {
r: 1.0,
g: 0.5,
b: 0.5,
a: 1.0,
},
fov: 45.0,
depth: RangeCopy { start: 1.0, end: 20.0 },
}
));
let mesh_entity: Entity = world.push((
cgmath::Point3 {
x: -5.0,
y: 7.0,
z: 10.0,
},
Mesh {
index_buffer: plane_index_buffer,
vertex_buffer: plane_vertex_buffer,
}
));
let entities: &[Entity] = world.extend(vec![
(Position { x: 0.0, y: 0.0 }, Velocity { dx: 0.0, dy: 0.0 }),
(Position { x: 1.0, y: 1.0 }, Velocity { dx: 0.0, dy: 0.0 }),
(Position { x: 2.0, y: 2.0 }, Velocity { dx: 0.0, dy: 0.0 }),
]);
// Init, this wants the references to the buffers...
let mut runtime = runtime::Runtime::init(&sc_desc, &device, &queue);
let mut runtime = runtime::Runtime::init();
let mut resources = Resources::default();
resources.insert(runtime);
@@ -331,7 +251,7 @@ fn main() {
// This is just an winit event loop
event_loop.run(move |event, _, control_flow| {
let _ = (&instance, &adapter); // force ownership by the closure (wtf??)
//let _ = (&instance, &adapter); // force ownership by the closure (wtf??)
// Override the control flow behaviour based on our system
*control_flow = if cfg!(feature = "metal-auto-capture") {
@@ -355,8 +275,8 @@ fn main() {
{
// ask for a redraw every 20 millis
if last_update_inst.elapsed() > Duration::from_millis(20) {
schedule.execute(&mut world, &mut resources);
window.request_redraw();
render_schedule.execute(&mut world, &mut resources);
//window.request_redraw();
last_update_inst = Instant::now();
}
@@ -373,12 +293,12 @@ fn main() {
..
} => {
log::info!("Resizing to {:?}", size);
sc_desc.width = size.width;
sc_desc.height = size.height;
let width = size.width;
let height = size.height;
resources.get_mut::<Renderer>().unwrap().resize(&sc_desc, &device, &queue);
resources.get_mut::<Renderer>().unwrap().resize(width, height);
swap_chain = device.create_swap_chain(&surface, &sc_desc);
//swap_chain = device.create_swap_chain(&surface, &sc_desc);
}
event::Event::WindowEvent { event, .. } => match event {
WindowEvent::KeyboardInput {
@@ -398,17 +318,8 @@ fn main() {
}
},
event::Event::RedrawRequested(_) => {
let frame = match swap_chain.get_current_frame() {
Ok(frame) => frame,
Err(_) => {
swap_chain = device.create_swap_chain(&surface, &sc_desc);
swap_chain
.get_current_frame()
.expect("Failed to acquire next swap chain texture!")
}
};
resources.get_mut::<Renderer>().unwrap().render(&frame.output, &device, &queue, &spawner);
//resources.get_mut::<Renderer>().unwrap().render();
}
_ => {}
}