diff options
Diffstat (limited to 'stockton-render/src/lib.rs')
-rw-r--r-- | stockton-render/src/lib.rs | 74 |
1 files changed, 53 insertions, 21 deletions
diff --git a/stockton-render/src/lib.rs b/stockton-render/src/lib.rs index b7bc8ab..ae902df 100644 --- a/stockton-render/src/lib.rs +++ b/stockton-render/src/lib.rs @@ -32,48 +32,80 @@ extern crate stockton_types; extern crate arrayvec; +#[macro_use] +extern crate legion; + mod culling; pub mod draw; mod error; mod types; - -use stockton_levels::prelude::*; -use stockton_types::World; +pub mod window; use culling::get_visible_faces; use draw::RenderingContext; -use error::{CreationError, FrameError}; +use std::sync::mpsc::{Receiver, Sender}; +use std::sync::Arc; +use std::sync::RwLock; +pub use window::WindowEvent; + +use stockton_levels::prelude::*; +use winit::event_loop::ControlFlow; +use winit::window::Window; + +use std::sync::mpsc::channel; /// Renders a world to a window when you tell it to. -pub struct Renderer<'a, T: MinBSPFeatures<VulkanSystem>> { - world: World<T>, - pub context: RenderingContext<'a>, +/// Also takes ownership of the window and channels window events to be processed outside winit's event loop. +pub struct Renderer<'a> { + /// All the vulkan stuff + context: RenderingContext<'a>, + + /// For getting events from the winit event loop + pub window_events: Receiver<WindowEvent>, + + /// For updating the control flow of the winit event loop + pub update_control_flow: Arc<RwLock<ControlFlow>>, } -impl<'a, T: MinBSPFeatures<VulkanSystem>> Renderer<'a, T> { +impl<'a> Renderer<'a> { /// Create a new Renderer. - /// This initialises all the vulkan context, etc needed. - pub fn new(world: World<T>, window: &winit::window::Window) -> Result<Self, CreationError> { - let context = RenderingContext::new(window, &world.map)?; + pub fn new<T: MinBSPFeatures<VulkanSystem>>( + window: &Window, + file: &T, + ) -> (Self, Sender<WindowEvent>) { + let (tx, rx) = channel(); + let update_control_flow = Arc::new(RwLock::new(ControlFlow::Poll)); - Ok(Renderer { world, context }) + ( + Renderer { + context: RenderingContext::new(window, file).unwrap(), + window_events: rx, + update_control_flow, + }, + tx, + ) } - /// Render a single frame of the world - pub fn render_frame(&mut self) -> Result<(), FrameError> { + /// Render a single frame of the given map. + fn render<T: MinBSPFeatures<VulkanSystem>>(&mut self, map: &T) { // Get visible faces - let faces = get_visible_faces(self.context.camera_pos(), &self.world.map); + let faces = get_visible_faces(self.context.camera_pos(), map); // Then draw them - if self.context.draw_vertices(&self.world.map, &faces).is_err() { + if self.context.draw_vertices(map, &faces).is_err() { unsafe { self.context.handle_surface_change().unwrap() }; // If it fails twice, then error - self.context - .draw_vertices(&self.world.map, &faces) - .map_err(|_| FrameError::PresentError)?; + self.context.draw_vertices(map, &faces).unwrap(); } - - Ok(()) } } + +/// A system that just renders the world. +#[system] +pub fn do_render<T: 'static + MinBSPFeatures<VulkanSystem>>( + #[resource] renderer: &mut Renderer<'static>, + #[resource] map: &T, +) { + renderer.render(map); +} |