فهرست منبع

Refactor camera struct and add camera uniform, stil buggy

Ghastrod 1 سال پیش
والد
کامیت
e6b0a8889b
6فایلهای تغییر یافته به همراه219 افزوده شده و 27 حذف شده
  1. 45 17
      src/camera.rs
  2. 33 0
      src/controller.rs
  3. 91 9
      src/lib.rs
  4. 2 0
      src/main.rs
  5. 47 0
      src/simple_plane.rs
  6. 1 1
      src/wave.rs

+ 45 - 17
src/camera.rs

@@ -1,21 +1,25 @@
-use glam;
-
-struct Camera{
-    eye: glam::Vec3,
-    target: glam::Vec3,
-    up: glam::Vec3,
-    aspect : f32,
-    fovy: f32,
-    znear: f32,
-    zfar: f32,
+use glam::{self, vec4, Mat4};
+
+pub struct Camera{
+    pub eye: glam::Vec3,
+    pub target: glam::Vec3,
+    pub up: glam::Vec3,
+    pub aspect : f32,
+    pub fovy: f32,
+    pub znear: f32,
+    pub zfar: f32,
 }
 
 #[rustfmt::skip]
-pub const OPENGL_TO_WGPU_MATRIX: glam::Mat4 = glam::Mat4::new(
-    1.0, 0.0, 0.0, 0.0,
-    0.0, 1.0, 0.0, 0.0,
-    0.0, 0.0, 0.5, 0.5,
-    0.0, 0.0, 0.0, 1.0,
+pub const OPENGL_TO_WGPU_MATRIX: glam::Mat4 = glam::Mat4::from_cols(
+    // 1.0, 0.0, 0.0, 0.0,
+    // 0.0, 1.0, 0.0, 0.0,
+    // 0.0, 0.0, 0.5, 0.5,
+    // 0.0, 0.0, 0.0, 1.0,
+    vec4(1.0, 0.0, 0.0, 0.0),
+    vec4(0.0, 1.0, 0.0, 0.0),
+    vec4(0.0, 0.0, 0.5, 0.5),
+    vec4(0.0, 0.0, 0.0, 1.0)
 );
 
 
@@ -23,8 +27,32 @@ pub const OPENGL_TO_WGPU_MATRIX: glam::Mat4 = glam::Mat4::new(
 impl Camera{
     fn build_view_projection_matrix(&self) -> glam::Mat4{
 
-        let view = glam::Mat4::look_at_rh(self.eye, self.target, self.up)
+        let view = glam::Mat4::look_at_rh(self.eye, self.target, self.up);
         
-        let proj = glam::Mat4::persp
+        let proj = glam::Mat4::perspective_rh(
+            self.fovy.to_radians(),
+            self.aspect,
+            self.znear,
+            self.zfar
+        );
+
+        return OPENGL_TO_WGPU_MATRIX * proj * view
+    }
+}
+
+#[repr(C)]
+#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
+
+pub struct CameraUniform{
+    view_proj: [[f32; 4]; 4],
+}
+
+impl CameraUniform{
+    pub fn new()->Self{
+        Self { view_proj: Mat4::IDENTITY.to_cols_array_2d() }
+    }
+
+    pub fn update_view_proj(&mut self, camera: &Camera){
+        self.view_proj = camera.build_view_projection_matrix().to_cols_array_2d();
     }
 }

+ 33 - 0
src/controller.rs

@@ -0,0 +1,33 @@
+use winit::event::WindowEvent;
+
+use crate::camera::Camera;
+use crate::camera::CameraUniform;
+
+struct CameraController{
+    speed: f32,
+    is_forward_pressed: bool,
+    is_backward_pressed: bool,
+    is_left_pressed: bool,
+    is_right_pressed: bool,
+}
+
+impl CameraController{
+    pub fn new(speed:f32)->Self{
+        Self{
+            speed,
+            is_forward_pressed: false,
+            is_backward_pressed: false,
+            is_left_pressed: false,
+            is_right_pressed: false,
+        }
+    }
+
+    pub fn process_input(&mut self, event: &winit::event::WindowEvent){
+        match event {
+            WindowEvent::KeyboardInput{
+                device_id: ,
+                event: K
+            }
+        }
+    }
+}

+ 91 - 9
src/lib.rs

@@ -4,6 +4,13 @@ use wgpu::util::DeviceExt;
 
 mod vertex;
 use vertex::Vertex;
+mod simple_plane;
+use simple_plane::generate_simple_plane;
+
+mod camera;
+use camera::Camera;
+use camera::CameraUniform;
+
 mod wave;
 mod texture;
 use winit::{
@@ -96,8 +103,13 @@ struct State<'a> {
     num_vertices: u32,
     //num_indices: u32,
 
-    //diffuse_bind_group: wgpu::BindGroup,
-    //diffuse_texture: texture::Texture,
+    diffuse_bind_group: wgpu::BindGroup,
+    diffuse_texture: texture::Texture,
+
+    camera: Camera,
+    camera_uniform: CameraUniform,
+    camera_buffer: wgpu::Buffer,
+    camera_bind_group: wgpu::BindGroup,
 }
 
 impl<'a> State<'a> {
@@ -163,6 +175,65 @@ impl<'a> State<'a> {
             view_formats: vec![],
         };
         surface.configure(&device, &config);
+        //Camera
+
+        let camera = Camera{
+            eye: glam::Vec3::new(0.0, 1.0, 2.0),
+            target: glam::Vec3::new(0.0, 0.0, 0.0),
+            up: glam::Vec3::new(0.0, 1.0, 0.0),
+            aspect: config.width as f32 / config.height as f32,
+            fovy: 45.0,
+            znear: 0.1,
+            zfar: 100.0,
+        };
+
+        //Camera buffer
+        let mut camera_uniform = CameraUniform::new();
+
+        camera_uniform.update_view_proj(&camera);
+
+        let camera_buffer = device.create_buffer_init(
+            &wgpu::util::BufferInitDescriptor{
+                label: Some("Camera Buffer"),
+                contents: bytemuck::cast_slice(&[camera_uniform]),
+                usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
+            }
+        );
+
+        //Camera Bind Group Layout
+
+        let camera_bind_group_layout = device.create_bind_group_layout(
+            &wgpu::BindGroupLayoutDescriptor{
+                entries: &[
+                    wgpu::BindGroupLayoutEntry{
+                        binding: 0,
+                        visibility: wgpu::ShaderStages::VERTEX,
+                        ty: wgpu::BindingType::Buffer{
+                            min_binding_size: None,
+                            ty: wgpu::BufferBindingType::Uniform,
+                            has_dynamic_offset: false,
+                        },
+                        count: None,
+                    }
+                ],
+                label: Some("camera_bind_group_layout"),
+            }
+        );
+
+        //Camera Bind Group
+
+        let camera_bind_group = device.create_bind_group(
+            &wgpu::BindGroupDescriptor{
+                layout: &camera_bind_group_layout,
+                entries: &[
+                    wgpu::BindGroupEntry{
+                        binding: 0,
+                        resource: camera_buffer.as_entire_binding(),
+                    }
+                ],
+                label: Some("camera_bind_group"),
+            }
+        );
 
         //Texture
         let diffuse_bytes = include_bytes!("happy-tree.png");
@@ -227,6 +298,7 @@ impl<'a> State<'a> {
                 label: Some("Render Pipeline Layout"),
                 bind_group_layouts: &[
                     &texture_bind_group_layout,
+                    &camera_bind_group_layout,
                 ],
                 push_constant_ranges: &[],
             });
@@ -269,7 +341,9 @@ impl<'a> State<'a> {
         });
 
         //let (vertices, indices) = creer_plan_subdivise(1.0, 1.0, 10);
-        let vert = creer_plan_simple(1.0, 1.0);
+        //let vert = creer_plan_simple(1.0, 1.0);
+
+        let vert = generate_simple_plane();
         // Create a buffer with the vertex data
         let vertex_buffer = device.create_buffer_init(
             &wgpu::util::BufferInitDescriptor{
@@ -301,8 +375,13 @@ impl<'a> State<'a> {
             //index_buffer,
             num_vertices,
             //num_indices,
-            //diffuse_bind_group,
-            //diffuse_texture,
+            diffuse_bind_group,
+            diffuse_texture,
+            //Camera
+            camera,
+            camera_uniform,
+            camera_buffer,
+            camera_bind_group,
         }
     }
 
@@ -358,9 +437,12 @@ impl<'a> State<'a> {
                 occlusion_query_set: None,
                 timestamp_writes: None,
             });
-
+            //Add the pipeline
             render_pass.set_pipeline(&self.render_pipeline);
-            //render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]);
+            //Add the bind group for the texture
+            render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]);
+            //Add the camera bind group
+            render_pass.set_bind_group(1, &self.camera_bind_group, &[]);
 
             render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
             //render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
@@ -368,8 +450,8 @@ impl<'a> State<'a> {
             render_pass.draw(0..self.num_vertices, 0..1);
         }
 
-        //self.queue.submit(iter::once(encoder.finish()));
-        //output.present();
+        self.queue.submit(iter::once(encoder.finish()));
+        output.present();
 
         Ok(())
     }

+ 2 - 0
src/main.rs

@@ -3,6 +3,8 @@ use wgpu1::run;
 mod wave;
 mod vertex;
 mod camera;
+mod simple_plane;
+mod controller;
 fn main() {
     pollster::block_on(run());
 }

+ 47 - 0
src/simple_plane.rs

@@ -0,0 +1,47 @@
+use std::vec;
+
+use crate::vertex::Vertex;
+
+pub fn generate_simple_plane()->Vec<Vertex>{
+    let mut vertices: Vec<Vertex> = vec![];
+
+    let vert1 = Vertex{
+        position: [-0.5, -0.5, 0.0],
+        color: [1.0, 0.0, 0.0],
+    };
+
+    let vert2 = Vertex{
+        position: [0.5, -0.5, 0.0],
+        color: [0.0, 1.0, 0.0],
+    };
+
+    let vert3 = Vertex{
+        position: [0.5, 0.5, 0.0],
+        color: [1.0, 1.0, 1.0],
+    };
+
+    let vert4 = Vertex{
+        position: [0.5, 0.5, 0.0],
+        color: [0.0, 0.0, 1.0],
+    };
+
+    let vert5 = Vertex{
+        position: [-0.5, 0.5, 0.0],
+        color: [1.0, 1.0, 1.0],
+    };
+
+    let vert6 = Vertex{
+        position: [-0.5, -0.5, 0.0],
+        color: [1.0, 1.0, 1.0],
+    };
+
+    // Reordered for counter-clockwise rendering
+    vertices.push(vert1);
+    vertices.push(vert2);
+    vertices.push(vert3);
+    vertices.push(vert4);
+    vertices.push(vert5);
+    vertices.push(vert6);
+
+    return vertices
+}

+ 1 - 1
src/wave.rs

@@ -1,4 +1,4 @@
-use std::{arch::x86_64, f64::consts::PI};
+use std::f64::consts::PI;
 
 use crate::vertex::Vertex;