From df9c5f387f029a96177035dfa14e229335ce6454 Mon Sep 17 00:00:00 2001 From: Melik Houij Date: Fri, 31 Mar 2023 11:27:31 +0200 Subject: [PATCH] panning in a plane --- resources/shaders/plane/shader.frag | 16 +++++ resources/shaders/plane/shader.vert | 24 ++++++++ resources/texture.jpg | Bin 0 -> 9430 bytes src/camera.rs | 4 ++ src/main.rs | 2 +- src/model.rs | 2 +- src/scene.rs | 20 ++++-- src/scene/objects.rs | 92 +++++++++++++++++++++++++++- 8 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 resources/shaders/plane/shader.frag create mode 100644 resources/shaders/plane/shader.vert create mode 100644 resources/texture.jpg diff --git a/resources/shaders/plane/shader.frag b/resources/shaders/plane/shader.frag new file mode 100644 index 0000000..725c0cb --- /dev/null +++ b/resources/shaders/plane/shader.frag @@ -0,0 +1,16 @@ +#version 330 core + +in vec2 v_texcoord; + +out vec4 frag_color; + +uniform sampler2D tex; + +void main() +{ + // Sample the texture using the texture coordinates + vec4 tex_color = texture(tex, v_texcoord); + + // Output the final color + frag_color = tex_color; +} diff --git a/resources/shaders/plane/shader.vert b/resources/shaders/plane/shader.vert new file mode 100644 index 0000000..66ae781 --- /dev/null +++ b/resources/shaders/plane/shader.vert @@ -0,0 +1,24 @@ +#version 330 core + +layout(location = 0) in vec3 position; +layout(location = 1) in vec2 texcoord; + +out vec2 v_texcoord; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; +uniform float tile_size; +uniform float scroll_speed; + +uniform vec3 camera_position; +void main() +{ + // Apply the model, view, and projection matrices + gl_Position = projection * view * model * vec4(position, 1.0); + + // Calculate the texture coordinate offset based on the camera position + vec2 offset = (camera_position.xz - position.xz) / tile_size; + offset += scroll_speed * vec2(0, 1) * -(gl_Position.w / projection[1][1]); + v_texcoord = texcoord + offset; +} diff --git a/resources/texture.jpg b/resources/texture.jpg new file mode 100644 index 0000000000000000000000000000000000000000..08dd41a0dcc7a9fb5103acaca10b9d2367869fdf GIT binary patch literal 9430 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 literal 0 HcmV?d00001 diff --git a/src/camera.rs b/src/camera.rs index 29f8310..10cb444 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -68,6 +68,10 @@ impl Camera { Matrix4::look_at(self.Position, self.Position + self.Front, self.Up) } + pub fn follow(&mut self, pos: Vector3) + { + self.Position = Point3::new(0.0, 0.55, 1.0) + pos; + } /// Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems) pub fn ProcessKeyboard(&mut self, direction: Camera_Movement, deltaTime: f32) { let velocity = self.MovementSpeed * deltaTime; diff --git a/src/main.rs b/src/main.rs index 5f33f71..6e9656d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -88,7 +88,7 @@ fn main() { let mut State = gameState::Playing; - let mut scene = Scene::new(gl); + let mut scene = Scene::new(gl); println!("entering main loop"); diff --git a/src/model.rs b/src/model.rs index f24fdda..c4c9a7a 100644 --- a/src/model.rs +++ b/src/model.rs @@ -110,7 +110,7 @@ impl Model { } } -unsafe fn TextureFromFile(path: &str, directory: &str, gl: Arc) -> glow::NativeTexture { +pub unsafe fn TextureFromFile(path: &str, directory: &str, gl: Arc) -> glow::NativeTexture { let filename = format!("{}/{}", directory, path); let mut textureID = gl.create_texture().unwrap(); diff --git a/src/scene.rs b/src/scene.rs index cd97b3f..236bb63 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -40,7 +40,8 @@ pub struct Scene { shaders: Vec>, time: std::time::Instant, DebugMode: bool, - input: objects::Input + input: objects::Input, + plane: objects::plane } impl Scene{ @@ -49,6 +50,7 @@ impl Scene{ let Car = objects::Player::new(Arc::clone(&gl)); let shader = Rc::new(shader::new("model", Arc::clone(&gl))); + let planeShader = Rc::new(shader::new("plane", Arc::clone(&gl))); let time = std::time::Instant::now(); @@ -57,6 +59,7 @@ impl Scene{ Pitch: -20.0, ..Camera::default() }; + let plane = objects::plane::new(Arc::clone(&gl)); let debug = Debug::new(gl.clone()); Scene{ @@ -64,15 +67,20 @@ impl Scene{ Car, camera, debug, - shaders: vec![shader], + shaders: vec![shader, planeShader], time, DebugMode: false, - input: objects::Input::default() + input: objects::Input::default(), + plane } } pub fn update(&mut self ,events_loop: &mut sdl2::EventPump, window: &sdl2::video::Window) -> SceneEnum { + + + + let mut ret = SceneEnum::Resume; unsafe { @@ -81,6 +89,10 @@ impl Scene{ } + self.camera.follow(self.Car.Transform.Position); + self.plane.draw(&self.shaders[1], &self.camera); + self.Car.update(&self.input); + self.Car.Draw(&self.shaders[0], &self.camera); if self.DebugMode{ self.handleDebug(events_loop, window, &mut ret) } @@ -133,8 +145,6 @@ impl Scene{ } - self.Car.update(&self.input); - self.Car.Draw(&self.shaders[0], &self.camera); ret } diff --git a/src/scene/objects.rs b/src/scene/objects.rs index 2272d2b..95ebcaa 100644 --- a/src/scene/objects.rs +++ b/src/scene/objects.rs @@ -2,10 +2,11 @@ const SCR_WIDTH: u32 = 1600; const SCR_HEIGHT: u32 = 900; -use cgmath::{Vector3, Quaternion, Rotation3}; +use cgmath::{Vector3, Quaternion, Rotation3, Deg, perspective, Matrix4}; use cgmath::prelude::*; use crate::model::Model; use crate::camera::Camera; +use glow::HasContext; pub struct Input { pub Accel: bool, @@ -117,3 +118,92 @@ impl Player { self.Model.Draw(shader); } } + +pub struct plane { + pub texture: glow::NativeTexture, + pub VAO: glow::VertexArray, + + VBO: glow::Buffer, + EBO: glow::Buffer, +} + +impl plane { + pub fn new(gl: std::sync::Arc) -> plane + { + let vertices: [f32; 20] = [ + 10.5, 10.5, 0.0, 1.0, 1.0, + 10.5, -10.5, 0.0, 1.0, 0.0, + -10.5, -10.5, 0.0, 0.0, 0.0, + -10.5, 10.5, 0.0, 0.0, 1.0 + ]; + let indices: [u32; 6] = [ + 0, 1, 3, + 1, 2, 3 + ]; + unsafe { + let VAO = gl.create_vertex_array().unwrap(); + let VBO = gl.create_buffer().unwrap(); + let EBO = gl.create_buffer().unwrap(); + + gl.bind_vertex_array(Some(VAO)); + + gl.bind_buffer(glow::ARRAY_BUFFER, Some(VBO)); + let data = core::slice::from_raw_parts( + vertices.as_ptr() as *const u8, + vertices.len() * core::mem::size_of::(), + ); + gl.named_buffer_data_u8_slice(VBO, data, glow::STATIC_DRAW); + + gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(EBO)); + let data = core::slice::from_raw_parts( + indices.as_ptr() as *const u8, + indices.len() * core::mem::size_of::(), + ); + gl.named_buffer_data_u8_slice(EBO, data, glow::STATIC_DRAW); + + let stride = 5 * core::mem::size_of::() as i32; + gl.enable_vertex_attrib_array(0); + gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, stride, 0); + + gl.enable_vertex_attrib_array(1); + gl.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, stride, (3 * core::mem::size_of::()) as i32 ); + + gl.bind_vertex_array(None); + + plane { + texture: crate::model::TextureFromFile("texture.jpg", "resources", gl.clone()), + VAO, + VBO, + EBO + } + } + } + + pub fn draw(&self, shader: &crate::shader::shader, camera: &Camera) + { + unsafe { + shader.Use(); + + + let model = cgmath::Matrix4::from_angle_x(cgmath::Deg(-90.0)); + let projection = cgmath::perspective(cgmath::Deg(camera.Zoom), SCR_WIDTH as f32 /SCR_HEIGHT as f32, 0.1, 100.0); + let view = camera.GetViewMatrix(); + + shader.setMat4("model", &model); + shader.setMat4("view", &view); + shader.setMat4("projection", &projection); + shader.setFloat("tile_size", 0.5); + shader.setFloat("scroll_speed", 10.0); + let camera_direction = (camera.Position - cgmath::Point3::new(0.0, 0.0, 0.0)); + shader.setVector3("camera_position", camera_direction); + + shader.gl.bind_texture(glow::TEXTURE_2D, Some(self.texture)); + shader.gl.bind_vertex_array(Some(self.VAO)); + + shader.gl.draw_elements(glow::TRIANGLES, 6, glow::UNSIGNED_INT, 0); + shader.gl.bind_vertex_array(None); + + shader.gl.active_texture(glow::TEXTURE0); + } + } +}