aboutsummaryrefslogtreecommitdiff
path: root/stockton-render/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'stockton-render/src/lib.rs')
-rw-r--r--stockton-render/src/lib.rs74
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);
+}