panning in a plane
parent
9161af2b83
commit
df9c5f387f
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
|
@ -68,6 +68,10 @@ impl Camera {
|
||||||
Matrix4::look_at(self.Position, self.Position + self.Front, self.Up)
|
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)
|
/// 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) {
|
pub fn ProcessKeyboard(&mut self, direction: Camera_Movement, deltaTime: f32) {
|
||||||
let velocity = self.MovementSpeed * deltaTime;
|
let velocity = self.MovementSpeed * deltaTime;
|
||||||
|
|
|
@ -88,7 +88,7 @@ fn main() {
|
||||||
|
|
||||||
let mut State = gameState::Playing;
|
let mut State = gameState::Playing;
|
||||||
|
|
||||||
let mut scene = Scene::new(gl);
|
let mut scene = Scene::new(gl);
|
||||||
|
|
||||||
println!("entering main loop");
|
println!("entering main loop");
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ impl Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn TextureFromFile(path: &str, directory: &str, gl: Arc<glow::Context>) -> glow::NativeTexture {
|
pub unsafe fn TextureFromFile(path: &str, directory: &str, gl: Arc<glow::Context>) -> glow::NativeTexture {
|
||||||
let filename = format!("{}/{}", directory, path);
|
let filename = format!("{}/{}", directory, path);
|
||||||
|
|
||||||
let mut textureID = gl.create_texture().unwrap();
|
let mut textureID = gl.create_texture().unwrap();
|
||||||
|
|
20
src/scene.rs
20
src/scene.rs
|
@ -40,7 +40,8 @@ pub struct Scene {
|
||||||
shaders: Vec<Rc<shader>>,
|
shaders: Vec<Rc<shader>>,
|
||||||
time: std::time::Instant,
|
time: std::time::Instant,
|
||||||
DebugMode: bool,
|
DebugMode: bool,
|
||||||
input: objects::Input
|
input: objects::Input,
|
||||||
|
plane: objects::plane
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene{
|
impl Scene{
|
||||||
|
@ -49,6 +50,7 @@ impl Scene{
|
||||||
let Car = objects::Player::new(Arc::clone(&gl));
|
let Car = objects::Player::new(Arc::clone(&gl));
|
||||||
|
|
||||||
let shader = Rc::new(shader::new("model", 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();
|
let time = std::time::Instant::now();
|
||||||
|
|
||||||
|
@ -57,6 +59,7 @@ impl Scene{
|
||||||
Pitch: -20.0,
|
Pitch: -20.0,
|
||||||
..Camera::default()
|
..Camera::default()
|
||||||
};
|
};
|
||||||
|
let plane = objects::plane::new(Arc::clone(&gl));
|
||||||
|
|
||||||
let debug = Debug::new(gl.clone());
|
let debug = Debug::new(gl.clone());
|
||||||
Scene{
|
Scene{
|
||||||
|
@ -64,15 +67,20 @@ impl Scene{
|
||||||
Car,
|
Car,
|
||||||
camera,
|
camera,
|
||||||
debug,
|
debug,
|
||||||
shaders: vec![shader],
|
shaders: vec![shader, planeShader],
|
||||||
time,
|
time,
|
||||||
DebugMode: false,
|
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
|
pub fn update(&mut self ,events_loop: &mut sdl2::EventPump, window: &sdl2::video::Window) -> SceneEnum
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let mut ret = SceneEnum::Resume;
|
let mut ret = SceneEnum::Resume;
|
||||||
|
|
||||||
unsafe {
|
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{
|
if self.DebugMode{
|
||||||
self.handleDebug(events_loop, window, &mut ret)
|
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
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
const SCR_WIDTH: u32 = 1600;
|
const SCR_WIDTH: u32 = 1600;
|
||||||
const SCR_HEIGHT: u32 = 900;
|
const SCR_HEIGHT: u32 = 900;
|
||||||
|
|
||||||
use cgmath::{Vector3, Quaternion, Rotation3};
|
use cgmath::{Vector3, Quaternion, Rotation3, Deg, perspective, Matrix4};
|
||||||
use cgmath::prelude::*;
|
use cgmath::prelude::*;
|
||||||
use crate::model::Model;
|
use crate::model::Model;
|
||||||
use crate::camera::Camera;
|
use crate::camera::Camera;
|
||||||
|
use glow::HasContext;
|
||||||
|
|
||||||
pub struct Input {
|
pub struct Input {
|
||||||
pub Accel: bool,
|
pub Accel: bool,
|
||||||
|
@ -117,3 +118,92 @@ impl Player {
|
||||||
self.Model.Draw(shader);
|
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<glow::Context>) -> 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::<f32>(),
|
||||||
|
);
|
||||||
|
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::<u32>(),
|
||||||
|
);
|
||||||
|
gl.named_buffer_data_u8_slice(EBO, data, glow::STATIC_DRAW);
|
||||||
|
|
||||||
|
let stride = 5 * core::mem::size_of::<f32>() 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::<f32>()) 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue