diff --git a/src/app.rs b/src/app.rs index d32b8b5..69e4dc7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -4,6 +4,7 @@ use futures::executor::block_on; use crate::vertex::Vertex; use crate::texture::Texture; +use crate::camera::Camera; const VERTICES: &[Vertex] = &[ Vertex { position: [-1.0, 1.0, 0.0], uv: [0.0, 0.0] }, @@ -28,7 +29,9 @@ pub struct App { vertex_buffer: wgpu::Buffer, index_buffer: wgpu::Buffer, // Texture - bind_group: wgpu::BindGroup + bind_group: wgpu::BindGroup, + // Camera + camera: Camera } impl App { @@ -179,9 +182,13 @@ impl App { let vertex_buffer = Self::create_buffer(&device, wgpu::BufferUsage::VERTEX, bytemuck::cast_slice(VERTICES)); let index_buffer = Self::create_buffer(&device, wgpu::BufferUsage::INDEX, bytemuck::cast_slice(INDICES)); + // Cam + let aspect = swapchain_desc.width as f32 / swapchain_desc.height as f32; + let camera = Camera::new((0.0, 1.0, 2.0).into(), (0.0, 0.0, 0.0).into(), aspect); + // Save values in app println!("Initialized"); - Self { surface, device, queue, swapchain_desc, swapchain, pipeline, vertex_buffer, index_buffer, bind_group } + Self { surface, device, queue, swapchain_desc, swapchain, pipeline, vertex_buffer, index_buffer, bind_group, camera } } pub fn resize(&mut self, new_size: Option>) { diff --git a/src/camera.rs b/src/camera.rs new file mode 100644 index 0000000..b233480 --- /dev/null +++ b/src/camera.rs @@ -0,0 +1,40 @@ +use cgmath::{Point3, Vector3, Matrix4, Deg}; + +#[rustfmt::skip] +const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4 = cgmath::Matrix4::new( + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.5, 0.0, + 0.0, 0.0, 0.5, 1.0, +); + +pub struct Camera { + pos: Point3, + target: Point3, + up: Vector3, + aspect: f32, + fovy: f32, + znear: f32, + zfar: f32, +} + +impl Camera { + + pub fn new(pos: Point3, target: Point3, aspect: f32) -> Self { + Self { + pos, + target, + up: Vector3::unit_y(), + aspect, + fovy: 45.0, + znear: 0.1, + zfar: 100.0 + } + } + + pub fn projection_matrix(&self) -> Matrix4 { + let view = Matrix4::look_at_rh(self.pos, self.target, self.up); + let proj = cgmath::perspective(Deg(self.fovy), self.aspect, self.znear, self.zfar); + return OPENGL_TO_WGPU_MATRIX * proj * view; + } +} diff --git a/src/main.rs b/src/main.rs index 0a0e52b..7414768 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use winit::{ mod vertex; mod texture; +mod camera; mod app; use app::App; diff --git a/src/uniforms.rs b/src/uniforms.rs new file mode 100644 index 0000000..e07deb0 --- /dev/null +++ b/src/uniforms.rs @@ -0,0 +1,22 @@ +// We need this for Rust to store our data correctly for the shaders +#[repr(C)] +// This is so we can store this in a buffer +#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] +struct Uniforms { + // We can't use cgmath with bytemuck directly so we'll have + // to convert the Matrix4 into a 4x4 f32 array + view_proj: [[f32; 4]; 4], +} + +impl Uniforms { + fn new() -> Self { + use cgmath::SquareMatrix; + Self { + view_proj: cgmath::Matrix4::identity().into(), + } + } + + fn update_view_proj(&mut self, camera: &Camera) { + self.view_proj = camera.build_view_projection_matrix().into(); + } +}