|
|
@ -3,14 +3,17 @@ use std::{iter, num::NonZeroU32, ops::Range, rc::Rc};
|
|
|
|
|
|
|
|
|
|
|
|
use bytemuck::__core::mem;
|
|
|
|
use bytemuck::__core::mem;
|
|
|
|
use bytemuck::{Pod, Zeroable};
|
|
|
|
use bytemuck::{Pod, Zeroable};
|
|
|
|
use cgmath::{vec3, Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rotation3, Transform, Vector3, Rad};
|
|
|
|
use cgmath::{
|
|
|
|
|
|
|
|
vec3, Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rad, Rotation3,
|
|
|
|
|
|
|
|
Transform, Vector3,
|
|
|
|
|
|
|
|
};
|
|
|
|
use futures::executor::LocalPool;
|
|
|
|
use futures::executor::LocalPool;
|
|
|
|
use legion::world::SubWorld;
|
|
|
|
use legion::world::SubWorld;
|
|
|
|
use legion::*;
|
|
|
|
use legion::*;
|
|
|
|
use rapier3d::parry::motion::RigidMotionComposition;
|
|
|
|
use rapier3d::parry::motion::RigidMotionComposition;
|
|
|
|
use wgpu::util::DeviceExt;
|
|
|
|
use wgpu::util::DeviceExt;
|
|
|
|
use wgpu::{
|
|
|
|
use wgpu::{
|
|
|
|
BindGroup, BindGroupLayout, Buffer, Device, Instance, Queue, Surface, SwapChain,
|
|
|
|
BackendBit, BindGroup, BindGroupLayout, Buffer, Device, Instance, Queue, Surface, SwapChain,
|
|
|
|
SwapChainDescriptor, SwapChainFrame, TextureView,
|
|
|
|
SwapChainDescriptor, SwapChainFrame, TextureView,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
use winit::dpi::PhysicalSize;
|
|
|
|
use winit::dpi::PhysicalSize;
|
|
|
@ -69,43 +72,14 @@ pub struct Pass {
|
|
|
|
uniform_buf: wgpu::Buffer,
|
|
|
|
uniform_buf: wgpu::Buffer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub struct Renderer {
|
|
|
|
|
|
|
|
swapchain: SwapChain,
|
|
|
|
|
|
|
|
swapchain_description: SwapChainDescriptor,
|
|
|
|
|
|
|
|
instance: Arc<Instance>,
|
|
|
|
|
|
|
|
device: Arc<Device>,
|
|
|
|
|
|
|
|
queue: Arc<Queue>,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size: PhysicalSize<u32>,
|
|
|
|
|
|
|
|
surface: Arc<Surface>,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lights_are_dirty: bool,
|
|
|
|
|
|
|
|
shadow_pass: Pass,
|
|
|
|
|
|
|
|
shadow_target_views: Vec<Arc<TextureView>>,
|
|
|
|
|
|
|
|
views_given: u32,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
forward_pass: Pass,
|
|
|
|
|
|
|
|
forward_depth: wgpu::TextureView,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
entity_bind_group_layout: BindGroupLayout,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
light_uniform_buf: wgpu::Buffer,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
camera_projection: Matrix4<f32>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[system]
|
|
|
|
#[system]
|
|
|
|
|
|
|
|
#[write_component(Camera)]
|
|
|
|
#[write_component(Position)]
|
|
|
|
#[write_component(Position)]
|
|
|
|
#[write_component(Point3<f32>)]
|
|
|
|
#[write_component(Point3<f32>)]
|
|
|
|
#[write_component(Mesh)]
|
|
|
|
#[write_component(Mesh)]
|
|
|
|
#[write_component(Color)]
|
|
|
|
#[write_component(Color)]
|
|
|
|
#[write_component(DirectionalLight)]
|
|
|
|
#[write_component(DirectionalLight)]
|
|
|
|
pub fn render_test(
|
|
|
|
pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) {
|
|
|
|
world: &mut SubWorld,
|
|
|
|
|
|
|
|
#[resource] renderer: &mut Renderer,
|
|
|
|
|
|
|
|
#[resource] camera_controller: &mut CameraController,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut encoder = renderer
|
|
|
|
let mut encoder = renderer
|
|
|
|
.device
|
|
|
|
.device
|
|
|
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
|
|
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
|
|
@ -113,6 +87,17 @@ pub fn render_test(
|
|
|
|
|
|
|
|
|
|
|
|
let frame = renderer.get_current_frame();
|
|
|
|
let frame = renderer.get_current_frame();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut query = <(&mut Camera)>::query();
|
|
|
|
|
|
|
|
for (camera) in query.iter_mut(world) {
|
|
|
|
|
|
|
|
let matrix = camera.calc_matrix(renderer.camera_projection);
|
|
|
|
|
|
|
|
let mx_ref: &[f32; 16] = matrix.as_ref();
|
|
|
|
|
|
|
|
renderer.queue.write_buffer(
|
|
|
|
|
|
|
|
&renderer.forward_pass.uniform_buf,
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
bytemuck::cast_slice(mx_ref),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query();
|
|
|
|
let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query();
|
|
|
|
|
|
|
|
|
|
|
|
let mut mesh_stack = Vec::new();
|
|
|
|
let mut mesh_stack = Vec::new();
|
|
|
@ -240,6 +225,31 @@ pub fn render_test(
|
|
|
|
renderer.queue.submit(iter::once(encoder.finish()));
|
|
|
|
renderer.queue.submit(iter::once(encoder.finish()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub struct Renderer {
|
|
|
|
|
|
|
|
swapchain: SwapChain,
|
|
|
|
|
|
|
|
swapchain_description: SwapChainDescriptor,
|
|
|
|
|
|
|
|
instance: Arc<Instance>,
|
|
|
|
|
|
|
|
device: Arc<Device>,
|
|
|
|
|
|
|
|
queue: Arc<Queue>,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size: PhysicalSize<u32>,
|
|
|
|
|
|
|
|
surface: Arc<Surface>,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lights_are_dirty: bool,
|
|
|
|
|
|
|
|
shadow_pass: Pass,
|
|
|
|
|
|
|
|
shadow_target_views: Vec<Arc<TextureView>>,
|
|
|
|
|
|
|
|
views_given: u32,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
forward_pass: Pass,
|
|
|
|
|
|
|
|
forward_depth: wgpu::TextureView,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
entity_bind_group_layout: BindGroupLayout,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
light_uniform_buf: wgpu::Buffer,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
camera_projection: Matrix4<f32>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Renderer {
|
|
|
|
impl Renderer {
|
|
|
|
const MAX_LIGHTS: usize = 10;
|
|
|
|
const MAX_LIGHTS: usize = 10;
|
|
|
|
const SHADOW_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
|
|
|
const SHADOW_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
|
|
@ -250,71 +260,21 @@ impl Renderer {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
|
|
|
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
|
|
|
|
|
|
|
|
|
|
|
pub fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4<f32> {
|
|
|
|
/// Generate a projection matrix with no look-at yet
|
|
|
|
|
|
|
|
pub fn generate_matrix(&self) -> cgmath::Matrix4<f32> {
|
|
|
|
// Specifies the aspect ratio that determines the field of view in the x direction.
|
|
|
|
// Specifies the aspect ratio that determines the field of view in the x direction.
|
|
|
|
// The aspect ratio is the ratio of x (width) to y (height).
|
|
|
|
// The aspect ratio is the ratio of x (width) to y (height).
|
|
|
|
let mx_projection = cgmath::perspective(cgmath::Deg(75f32), aspect_ratio, 1.0, 20.0);
|
|
|
|
cgmath::perspective(
|
|
|
|
let mx_view = cgmath::Matrix4::look_at(
|
|
|
|
cgmath::Deg(75f32),
|
|
|
|
cgmath::Point3::new(1.0f32, 1.0, 4.0),
|
|
|
|
self.size.width as f32 / self.size.height as f32,
|
|
|
|
cgmath::Point3::new(0.0f32, 0.0, 0.0),
|
|
|
|
1.0,
|
|
|
|
cgmath::Vector3::unit_z(),
|
|
|
|
20.0,
|
|
|
|
);
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
let mx_correction = OPENGL_TO_WGPU_MATRIX;
|
|
|
|
|
|
|
|
mx_correction * mx_projection * mx_view
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn cam_look_delta(&mut self, delta: (f64, f64)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 20.0);
|
|
|
|
|
|
|
|
// let mx_view = cgmath::Matrix4::look_at(
|
|
|
|
|
|
|
|
// cgmath::Point3::new(3.0f32, -9.0, 6.0),
|
|
|
|
|
|
|
|
// cgmath::Point3::new(0f32, 0.0, 0.0),
|
|
|
|
|
|
|
|
// cgmath::Vector3::unit_z(),
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// let mx_correction = OPENGL_TO_WGPU_MATRIX;
|
|
|
|
|
|
|
|
// let mx_total = mx_correction * mx_projection * mx_view;
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// let rotation = Quaternion::from(Euler {
|
|
|
|
|
|
|
|
// x: Deg(90.0),
|
|
|
|
|
|
|
|
// y: Deg(45.0),
|
|
|
|
|
|
|
|
// z: Deg(15.0),
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// Euler {
|
|
|
|
|
|
|
|
// x: (),
|
|
|
|
|
|
|
|
// y: (),
|
|
|
|
|
|
|
|
// z: ()
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// let offset = cgmath::vec3(1.0, 1.0, 4.0);
|
|
|
|
|
|
|
|
// let transform = Decomposed {
|
|
|
|
|
|
|
|
// disp: offset.clone(),
|
|
|
|
|
|
|
|
// rot: Quaternion::from_axis_angle(offset.normalize(), Deg(50.0)),
|
|
|
|
|
|
|
|
// scale: 1.0,
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// let mut q = Quaternion::from(self.camera_direction);
|
|
|
|
|
|
|
|
// q.v.z += delta.0 as f32;
|
|
|
|
|
|
|
|
// q.v.y += delta.1 as f32;
|
|
|
|
|
|
|
|
// //let q2 = Quaternion::from_angle_x(Deg(delta.0 as f32));
|
|
|
|
|
|
|
|
// //let q3 = Quaternion::from_angle_y(Deg(delta.1 as f32));
|
|
|
|
|
|
|
|
// let w = Matrix4::from(q);
|
|
|
|
|
|
|
|
// //mx_total = mx_total + w;
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// self.camera_projection = transform.into();
|
|
|
|
|
|
|
|
// let mut mx_total = self.camera_projection.clone();
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// let mx_ref: &[f32; 16] = mx_total.as_ref();
|
|
|
|
|
|
|
|
// self.queue.write_buffer(
|
|
|
|
|
|
|
|
// &self.forward_pass.uniform_buf,
|
|
|
|
|
|
|
|
// 0,
|
|
|
|
|
|
|
|
// bytemuck::cast_slice(mx_ref),
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Get the next frame from the swapchain
|
|
|
|
|
|
|
|
/// (recreates if something funky goes on)
|
|
|
|
pub fn get_current_frame(&mut self) -> SwapChainFrame {
|
|
|
|
pub fn get_current_frame(&mut self) -> SwapChainFrame {
|
|
|
|
// Update the renderers swapchain state
|
|
|
|
|
|
|
|
match self.swapchain.get_current_frame() {
|
|
|
|
match self.swapchain.get_current_frame() {
|
|
|
|
Ok(frame) => frame,
|
|
|
|
Ok(frame) => frame,
|
|
|
|
Err(_) => {
|
|
|
|
Err(_) => {
|
|
|
@ -328,6 +288,8 @@ impl Renderer {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Create a bare vertex & indices buffer
|
|
|
|
|
|
|
|
/// TODO I really should remove this / consolidate it
|
|
|
|
pub fn create_buffer(
|
|
|
|
pub fn create_buffer(
|
|
|
|
device: &wgpu::Device,
|
|
|
|
device: &wgpu::Device,
|
|
|
|
indices: Vec<u32>,
|
|
|
|
indices: Vec<u32>,
|
|
|
@ -352,6 +314,9 @@ impl Renderer {
|
|
|
|
(vertex_buf, index_buf)
|
|
|
|
(vertex_buf, index_buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// When creating a light we have to give it a target view to render to
|
|
|
|
|
|
|
|
/// This is major danger scary since we have a 10 light limit, and only
|
|
|
|
|
|
|
|
/// 2 views created at this moment, need to smarten this up
|
|
|
|
pub fn create_light(&mut self) -> DirectionalLight {
|
|
|
|
pub fn create_light(&mut self) -> DirectionalLight {
|
|
|
|
let target = self
|
|
|
|
let target = self
|
|
|
|
.shadow_target_views
|
|
|
|
.shadow_target_views
|
|
|
@ -375,6 +340,7 @@ impl Renderer {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// I don't know why the hell this is still in here
|
|
|
|
pub fn create_plane(&self, size: f32) -> Mesh {
|
|
|
|
pub fn create_plane(&self, size: f32) -> Mesh {
|
|
|
|
let vertices = [
|
|
|
|
let vertices = [
|
|
|
|
vertex([size, -size, 0.0], [0.0, 0.0, 1.0]),
|
|
|
|
vertex([size, -size, 0.0], [0.0, 0.0, 1.0]),
|
|
|
@ -701,7 +667,12 @@ impl Renderer {
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
|
|
|
|
let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
|
|
|
|
let mx_projection = cgmath::perspective(
|
|
|
|
|
|
|
|
cgmath::Deg(75f32), // FOV, might wanna hook this up somewhere
|
|
|
|
|
|
|
|
sc_desc.width as f32 / sc_desc.height as f32,
|
|
|
|
|
|
|
|
1.0,
|
|
|
|
|
|
|
|
20.0,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
let forward_pass = {
|
|
|
|
let forward_pass = {
|
|
|
|
// Create pipeline layout
|
|
|
|
// Create pipeline layout
|
|
|
@ -758,7 +729,7 @@ impl Renderer {
|
|
|
|
|
|
|
|
|
|
|
|
// I need to know the number of lights...
|
|
|
|
// I need to know the number of lights...
|
|
|
|
let forward_uniforms = ForwardUniforms {
|
|
|
|
let forward_uniforms = ForwardUniforms {
|
|
|
|
proj: *mx_total.as_ref(),
|
|
|
|
proj: *mx_projection.as_ref(),
|
|
|
|
//num_lights: [lights.len() as u32, 0, 0, 0],
|
|
|
|
//num_lights: [lights.len() as u32, 0, 0, 0],
|
|
|
|
num_lights: [2 as u32, 0, 0, 0],
|
|
|
|
num_lights: [2 as u32, 0, 0, 0],
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -883,7 +854,7 @@ impl Renderer {
|
|
|
|
surface,
|
|
|
|
surface,
|
|
|
|
instance: Arc::new(instance),
|
|
|
|
instance: Arc::new(instance),
|
|
|
|
views_given: 0,
|
|
|
|
views_given: 0,
|
|
|
|
camera_projection: mx_total,
|
|
|
|
camera_projection: mx_projection,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -903,7 +874,7 @@ impl Renderer {
|
|
|
|
.create_swap_chain(&self.surface, &self.swapchain_description.clone());
|
|
|
|
.create_swap_chain(&self.surface, &self.swapchain_description.clone());
|
|
|
|
|
|
|
|
|
|
|
|
// update view-projection matrix
|
|
|
|
// update view-projection matrix
|
|
|
|
let mx_total = Self::generate_matrix(width as f32 / height as f32);
|
|
|
|
let mx_total = self.generate_matrix();
|
|
|
|
let mx_ref: &[f32; 16] = mx_total.as_ref();
|
|
|
|
let mx_ref: &[f32; 16] = mx_total.as_ref();
|
|
|
|
self.queue.write_buffer(
|
|
|
|
self.queue.write_buffer(
|
|
|
|
&self.forward_pass.uniform_buf,
|
|
|
|
&self.forward_pass.uniform_buf,
|
|
|
|