aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--stockton-render/src/draw/camera.rs30
-rw-r--r--stockton-render/src/draw/context.rs125
-rw-r--r--stockton-render/src/lib.rs27
3 files changed, 131 insertions, 51 deletions
diff --git a/stockton-render/src/draw/camera.rs b/stockton-render/src/draw/camera.rs
index 6733cd7..2abf814 100644
--- a/stockton-render/src/draw/camera.rs
+++ b/stockton-render/src/draw/camera.rs
@@ -29,22 +29,22 @@ use stockton_types::{Vector3, Matrix4};
pub struct CameraSettings {
/// Position of the camera
- position: Vector3,
+ pub position: Vector3,
/// A point the camera is looking directly at
- looking_at: Vector3,
+ pub looking_at: Vector3,
/// The up direction
- up: Vector3,
+ pub up: Vector3,
/// FOV in radians
- fov: f32,
+ pub fov: f32,
/// Near clipping plane (world units)
- near: f32,
+ pub near: f32,
/// Far clipping plane (world units)
- far: f32,
+ pub far: f32,
}
/// Holds settings related to the projection of world space to screen space
@@ -76,12 +76,12 @@ impl<'a> WorkingCamera<'a> {
command_queue: &mut CommandQueue,
command_pool: &mut CommandPool) -> Result<WorkingCamera<'a>, error::CreationError> {
WorkingCamera::with_settings(CameraSettings {
- position: Vector3::new(-0.5, 1.5, -1.0),
- looking_at: Vector3::new(0.5, 0.5, 0.5),
+ position: Vector3::new(-320.0, 0.0, 0.0),
+ looking_at: Vector3::new(0.0, 0.0, 0.0),
up: Vector3::new(0.0, 1.0, 0.0),
fov: f32::to_radians(90.0),
near: 0.1,
- far: 100.0,
+ far: 1024.0,
}, aspect_ratio, device, adapter, command_queue, command_pool)
}
@@ -202,11 +202,19 @@ impl<'a> WorkingCamera<'a> {
projection_matrix * view_matrix
}
+ /// Update the aspect ratio
pub fn update_aspect_ratio(&mut self, new: f32) {
self.aspect_ratio = new;
self.is_dirty = true;
}
+ /// Move the camera by `delta`
+ pub fn move_camera(&mut self, delta: Vector3) {
+ self.settings.position += delta;
+ self.is_dirty = true;
+ }
+
+ /// Ensures the VP matrix on the GPU is up-to-date
pub fn commit<'b>(&'b mut self, device: &Device,
command_queue: &mut CommandQueue,
command_pool: &mut CommandPool) -> &'b DescriptorSet {
@@ -234,4 +242,8 @@ impl<'a> WorkingCamera<'a> {
device.destroy_descriptor_set_layout(ManuallyDrop::into_inner(read(&self.descriptor_set_layout)));
}
}
+
+ pub fn camera_pos(&self) -> Vector3 {
+ self.settings.position
+ }
} \ No newline at end of file
diff --git a/stockton-render/src/draw/context.rs b/stockton-render/src/draw/context.rs
index d9d426d..12f24ad 100644
--- a/stockton-render/src/draw/context.rs
+++ b/stockton-render/src/draw/context.rs
@@ -20,7 +20,8 @@
use std::{
mem::{ManuallyDrop, size_of},
ops::Deref,
- borrow::Borrow
+ borrow::Borrow,
+ convert::TryInto
};
use winit::window::Window;
use arrayvec::ArrayVec;
@@ -32,12 +33,20 @@ use hal::{
window::SwapchainConfig
};
use stockton_types::{Vector2, Vector3};
+use stockton_bsp::{
+ BSPFile,
+ lumps::faces::FaceType
+};
-use crate::types::*;
-use crate::error;
-use super::camera::WorkingCamera;
-use super::texture::TextureStore;
-use super::buffer::{StagedBuffer, ModifiableBuffer};
+use crate::{
+ types::*,
+ error
+};
+use super::{
+ camera::WorkingCamera,
+ texture::TextureStore,
+ buffer::{StagedBuffer, ModifiableBuffer}
+};
/// Entry point name for shaders
const ENTRY_NAME: &str = "main";
@@ -53,10 +62,10 @@ const COLOR_RANGE: hal::image::SubresourceRange = hal::image::SubresourceRange {
const INITIAL_TEX_SIZE: usize = 2;
/// Initial size of vertex buffer. TODO: Way of overriding this
-const INITIAL_VERT_SIZE: u64 = 32;
+const INITIAL_VERT_SIZE: u64 = 3 * 3000;
/// Initial size of index buffer. TODO: Way of overriding this
-const INITIAL_INDEX_SIZE: u64 = 16;
+const INITIAL_INDEX_SIZE: u64 = 3000;
/// Source for vertex shader. TODO
const VERTEX_SOURCE: &str = include_str!("./data/stockton.vert");
@@ -313,9 +322,7 @@ impl<'a> RenderingContext<'a> {
self.device.wait_idle().unwrap();
// Swapchain itself
- let old_swapchain = unsafe {
- ManuallyDrop::into_inner(read(&self.swapchain))
- };
+ let old_swapchain = ManuallyDrop::into_inner(read(&self.swapchain));
let (format, viewport, extent, swapchain, backbuffer) = RenderingContext::create_swapchain(&mut self.surface, &mut self.device, &self.adapter, Some(old_swapchain))?;
@@ -326,12 +333,11 @@ impl<'a> RenderingContext<'a> {
self.camera.update_aspect_ratio(extent.width as f32 / extent.height as f32);
// Graphics pipeline
- unsafe {
- self.device.destroy_graphics_pipeline(ManuallyDrop::into_inner(read(&self.pipeline)));
+ self.device.destroy_graphics_pipeline(ManuallyDrop::into_inner(read(&self.pipeline)));
- self.device
- .destroy_pipeline_layout(ManuallyDrop::into_inner(read(&self.pipeline_layout)));
- }
+ self.device
+ .destroy_pipeline_layout(ManuallyDrop::into_inner(read(&self.pipeline_layout)));
+
let (pipeline_layout, pipeline) = {
let mut descriptor_set_layouts: ArrayVec<[_; 2]> = ArrayVec::new();
@@ -359,24 +365,22 @@ impl<'a> RenderingContext<'a> {
}
// Make new ones
for i in 0..backbuffer.len() {
- unsafe {
- use hal::image::ViewKind;
- use hal::format::Swizzle;
-
- self.imageviews.push(self.device.create_image_view(
- &backbuffer[i],
- ViewKind::D2,
- format,
- Swizzle::NO,
- COLOR_RANGE.clone(),
- ).map_err(|e| error::CreationError::ImageViewError (e))?);
-
- self.framebuffers.push(self.device.create_framebuffer(
- &self.renderpass,
- Some(&self.imageviews[i]),
- extent
- ).map_err(|_| error::CreationError::OutOfMemoryError)?);
- }
+ use hal::image::ViewKind;
+ use hal::format::Swizzle;
+
+ self.imageviews.push(self.device.create_image_view(
+ &backbuffer[i],
+ ViewKind::D2,
+ format,
+ Swizzle::NO,
+ COLOR_RANGE.clone(),
+ ).map_err(|e| error::CreationError::ImageViewError (e))?);
+
+ self.framebuffers.push(self.device.create_framebuffer(
+ &self.renderpass,
+ Some(&self.imageviews[i]),
+ extent
+ ).map_err(|_| error::CreationError::OutOfMemoryError)?);
}
Ok(())
@@ -718,6 +722,7 @@ impl<'a> RenderingContext<'a> {
Ok(())
}
+ /// Draw all vertices in the buffer
pub fn draw_vertices(&mut self) -> Result<(), &'static str> {
let get_image = &self.get_image[self.current_frame];
let render_complete = &self.render_complete[self.current_frame];
@@ -835,6 +840,58 @@ impl<'a> RenderingContext<'a> {
Ok(())
}
+
+ /// Get current position of camera
+ pub fn camera_pos(&self) -> Vector3 {
+ self.camera.camera_pos()
+ }
+
+ /// Move the camera by `delta`
+ pub fn move_camera(&mut self, delta: Vector3) {
+ self.camera.move_camera(delta)
+ }
+
+ /// Load all active faces into the vertex buffers for drawing
+ // TODO: This is just a POC, we need to restructure things a lot for actually texturing, etc
+ pub fn set_active_faces(&mut self, faces: Vec<usize>, file: &BSPFile) {
+ let mut curr_vert_idx: usize = 0;
+ let mut curr_idx_idx: usize = 0;
+
+ for face in faces.into_iter().map(|idx| &file.faces.faces[idx]) {
+ if face.face_type == FaceType::Polygon || face.face_type == FaceType::Mesh {
+ let base = face.vertices_idx.start as i32;
+
+ for idx in face.meshverts_idx.clone().step_by(3) {
+ let start_idx: u16 = curr_vert_idx.try_into().unwrap();
+
+ for mv in &file.meshverts.meshverts[idx..idx+3] {
+ let vert = &file.vertices.vertices[(base + mv.offset) as usize];
+ let uv = Vector2::new(vert.tex.u[0], vert.tex.v[0]);
+
+ let uvp = UVPoint (vert.position, uv, 0);
+ self.vert_buffer[curr_vert_idx] = uvp;
+
+ curr_vert_idx += 1;
+ }
+
+
+ self.index_buffer[curr_idx_idx] = (start_idx, start_idx + 1, start_idx + 2);
+
+ curr_idx_idx += 1;
+
+ if curr_vert_idx >= INITIAL_VERT_SIZE.try_into().unwrap() || curr_idx_idx >= INITIAL_INDEX_SIZE.try_into().unwrap() {
+ break;
+ }
+ }
+ } else {
+ // TODO: Other types of faces
+ }
+
+ if curr_vert_idx >= INITIAL_VERT_SIZE.try_into().unwrap() || curr_idx_idx >= INITIAL_INDEX_SIZE.try_into().unwrap() {
+ break;
+ }
+ }
+ }
}
impl<'a> core::ops::Drop for RenderingContext<'a> {
diff --git a/stockton-render/src/lib.rs b/stockton-render/src/lib.rs
index 2255c49..3f157a1 100644
--- a/stockton-render/src/lib.rs
+++ b/stockton-render/src/lib.rs
@@ -33,18 +33,17 @@ extern crate arrayvec;
pub mod draw;
mod error;
mod types;
-mod walk_bsp;
-
-use std::sync::{Arc, RwLock};
+mod culling;
use stockton_types::World;
use error::{CreationError, FrameError};
use draw::RenderingContext;
+use culling::get_visible_faces;
/// Renders a world to a window when you tell it to.
pub struct Renderer<'a> {
- world: Arc<RwLock<World<'a>>>,
+ world: World,
pub context: RenderingContext<'a>
}
@@ -52,18 +51,30 @@ pub struct Renderer<'a> {
impl<'a> Renderer<'a> {
/// Create a new Renderer.
/// This initialises all the vulkan context, etc needed.
- pub fn new(world: World<'a>, window: &winit::window::Window) -> Result<Self, CreationError> {
- let world = Arc::new(RwLock::new(world));
+ pub fn new(world: World, window: &winit::window::Window) -> Result<Self, CreationError> {
let context = RenderingContext::new(window)?;
Ok(Renderer {
- world: world, context
+ world, context
})
}
/// Render a single frame of the world
pub fn render_frame(&mut self) -> Result<(), FrameError>{
- self.context.draw_vertices().unwrap();
+ // Get visible faces
+ let faces = get_visible_faces(self.context.camera_pos(), &self.world.map);
+
+ // Load them in
+ self.context.set_active_faces(faces, &self.world.map);
+
+ // Then draw them
+ if let Err(_) = self.context.draw_vertices() {
+ unsafe {self.context.handle_surface_change().unwrap()};
+
+ // If it fails twice, then error
+ self.context.draw_vertices().map_err(|_| FrameError::PresentError)?;
+ }
+
Ok(())
}
}