From c4bd69e109ee580725ee8ba2325732520bc84015 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 15 Jan 2023 16:10:19 +0100 Subject: [PATCH] wip --- src/game.rs | 27 +++++++-- src/game/assets/textures.rs | 2 +- src/game/camera.rs | 108 ++++++++++++++++++++++++---------- src/game/shaders.rs | 58 +++--------------- src/game/shaders/chunk.rs | 41 +++++++++++++ src/game/shaders/colored2d.rs | 27 +++++++++ 6 files changed, 175 insertions(+), 88 deletions(-) create mode 100644 src/game/shaders/chunk.rs create mode 100644 src/game/shaders/colored2d.rs diff --git a/src/game.rs b/src/game.rs index 9ed082b..1e540a0 100644 --- a/src/game.rs +++ b/src/game.rs @@ -11,7 +11,8 @@ mod camera; use assets::Assets; use display::init_display; -use shaders::{Programs, Colored2dVertex}; +use shaders::{Programs, chunk::Vertex as ChunkVertex}; +use camera::Camera; pub fn run() { log::info!("starting up"); @@ -20,14 +21,16 @@ pub fn run() { let display = init_display(&event_loop); log::info!("compiling shaders"); let programs = Programs::compile_all(&display); + log::info!("init camera"); + let camera = Camera::default(); log::info!("loading assets"); let assets = Assets::load_all_sync(&display); log::info!("game loaded"); //======================= - let vertex1 = Colored2dVertex { position: [-0.5, -0.5] }; - let vertex2 = Colored2dVertex { position: [ 0.0, 0.5] }; - let vertex3 = Colored2dVertex { position: [ 0.5, -0.25] }; + let vertex1 = ChunkVertex { position: [-0.5, -0.5, 1.], uv: [0., 0.], normal: [0., 1., 0.] }; + let vertex2 = ChunkVertex { position: [ 0.0, 0.5, 1.], uv: [0., 1.], normal: [0., 1., 0.] }; + let vertex3 = ChunkVertex { position: [ 0.5, -0.25, 1.], uv: [1., 1.], normal: [0., 1., 0.] }; let shape = vec![vertex1, vertex2, vertex3]; let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap(); //======================= @@ -45,8 +48,22 @@ pub fn run() { _ => () } let mut target = display.draw(); + let target_dimensions = target.get_dimensions(); + let perspective = camera.perspective_matrix(target_dimensions); + let view = camera.view_matrix(); target.clear_color_and_depth((0.5, 0.5, 1., 1.), 1.); - target.draw(&vertex_buffer, &glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList), &programs.colored_2d, &uniform! { u_color: [1.0f32, 0.0f32, 0.0f32, 1.0f32] }, &Default::default()).unwrap(); + target.draw( + &vertex_buffer, + &glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList), + &programs.chunk, + &uniform! { + model: [[0.0f32; 4]; 4], + view: view, + perspective: perspective, + tex: &assets.textures.block_atlas + }, + &Default::default() + ).unwrap(); target.finish().unwrap(); }); } diff --git a/src/game/assets/textures.rs b/src/game/assets/textures.rs index c07e5c5..ebf96f4 100644 --- a/src/game/assets/textures.rs +++ b/src/game/assets/textures.rs @@ -26,7 +26,7 @@ fn load_png(file_path: &str, display: &glium::Display) -> SrgbTexture2d { } pub struct Textures { - block_atlas: SrgbTexture2d + pub block_atlas: SrgbTexture2d } impl Textures { /// Load textures synchronously, one by one and upload them to the GPU diff --git a/src/game/camera.rs b/src/game/camera.rs index 31c91e8..1e87db8 100644 --- a/src/game/camera.rs +++ b/src/game/camera.rs @@ -1,35 +1,81 @@ +// Perspective/View matrix code from: +// https://glium.github.io/glium/book/tuto-10-perspective.html // https://glium.github.io/glium/book/tuto-12-camera.html +// I don't understand anything but it works -fn view_matrix(position: &[f32; 3], direction: &[f32; 3], up: &[f32; 3]) -> [[f32; 4]; 4] { - let f = { - let f = direction; - let len = f[0] * f[0] + f[1] * f[1] + f[2] * f[2]; - let len = len.sqrt(); - [f[0] / len, f[1] / len, f[2] / len] - }; +use std::f32::consts::PI; - let s = [up[1] * f[2] - up[2] * f[1], - up[2] * f[0] - up[0] * f[2], - up[0] * f[1] - up[1] * f[0]]; - - let s_norm = { - let len = s[0] * s[0] + s[1] * s[1] + s[2] * s[2]; - let len = len.sqrt(); - [s[0] / len, s[1] / len, s[2] / len] - }; - - let u = [f[1] * s_norm[2] - f[2] * s_norm[1], - f[2] * s_norm[0] - f[0] * s_norm[2], - f[0] * s_norm[1] - f[1] * s_norm[0]]; - - let p = [-position[0] * s_norm[0] - position[1] * s_norm[1] - position[2] * s_norm[2], - -position[0] * u[0] - position[1] * u[1] - position[2] * u[2], - -position[0] * f[0] - position[1] * f[1] - position[2] * f[2]]; - - [ - [s_norm[0], u[0], f[0], 0.0], - [s_norm[1], u[1], f[1], 0.0], - [s_norm[2], u[2], f[2], 0.0], - [p[0], p[1], p[2], 1.0], - ] +pub struct Camera { + pub position: [f32; 3], + pub direction: [f32; 3], + pub up: [f32; 3], + pub fov: f32, + pub znear: f32, + pub zfar: f32, +} +impl Camera { + pub fn new() -> Self { + Default::default() + } + + pub fn view_matrix(&self) -> [[f32; 4]; 4] { + let position = self.position; + let direction = self.direction; + let up = self.up; + + let f = { + let f = direction; + let len = f[0] * f[0] + f[1] * f[1] + f[2] * f[2]; + let len = len.sqrt(); + [f[0] / len, f[1] / len, f[2] / len] + }; + let s = [up[1] * f[2] - up[2] * f[1], + up[2] * f[0] - up[0] * f[2], + up[0] * f[1] - up[1] * f[0]]; + let s_norm = { + let len = s[0] * s[0] + s[1] * s[1] + s[2] * s[2]; + let len = len.sqrt(); + [s[0] / len, s[1] / len, s[2] / len] + }; + let u = [f[1] * s_norm[2] - f[2] * s_norm[1], + f[2] * s_norm[0] - f[0] * s_norm[2], + f[0] * s_norm[1] - f[1] * s_norm[0]]; + let p = [-position[0] * s_norm[0] - position[1] * s_norm[1] - position[2] * s_norm[2], + -position[0] * u[0] - position[1] * u[1] - position[2] * u[2], + -position[0] * f[0] - position[1] * f[1] - position[2] * f[2]]; + [ + [s_norm[0], u[0], f[0], 0.0], + [s_norm[1], u[1], f[1], 0.0], + [s_norm[2], u[2], f[2], 0.0], + [p[0], p[1], p[2], 1.0], + ] + } + + pub fn perspective_matrix(&self, target_dimensions: (u32, u32)) -> [[f32; 4]; 4] { + let znear = self.znear; + let zfar = self.zfar; + let fov = self.fov; + let (width, height) = target_dimensions; + let aspect_ratio = height as f32 / width as f32; + let f = 1.0 / (fov / 2.0).tan(); + [ + [f * aspect_ratio , 0.0, 0.0 , 0.0], + [ 0.0 , f , 0.0 , 0.0], + [ 0.0 , 0.0, (zfar+znear)/(zfar-znear) , 1.0], + [ 0.0 , 0.0, -(2.0*zfar*znear)/(zfar-znear), 0.0], + ] + } +} + +impl Default for Camera { + fn default() -> Self { + Self { + position: [0., 0., 0.], + direction: [0., 0., 0.], + up: [0., 1., 0.], + fov: PI / 3., + zfar: 1024., + znear: 0.1, + } + } } diff --git a/src/game/shaders.rs b/src/game/shaders.rs index 58f6345..38fe256 100644 --- a/src/game/shaders.rs +++ b/src/game/shaders.rs @@ -1,61 +1,17 @@ -use glium::{Display, Program, implement_vertex}; +use glium::{Display, Program}; + +pub mod chunk; +pub mod colored2d; pub struct Programs { pub colored_2d: Program, + pub chunk: Program, } impl Programs { pub fn compile_all(display: &Display) -> Self { Self { - colored_2d: Program::from_source(display, COLORED_2D_VERTEX_SHADER, COLORED_2D_FRAGMENT_SHADER, None).unwrap(), + colored_2d: Program::from_source(display, colored2d::VERTEX_SHADER, colored2d::FRAGMENT_SHADER, None).unwrap(), + chunk: Program::from_source(display, chunk::VERTEX_SHADER, chunk::FRAGMENT_SHADER, None).unwrap(), } } } - -#[derive(Clone, Copy)] -pub struct Colored2dVertex { - pub position: [f32; 2] -} -implement_vertex!(Colored2dVertex, position); - -pub const COLORED_2D_VERTEX_SHADER: &str = r#" - #version 140 - - in vec2 position; - - void main() { - gl_Position = vec4(position, 0., 1.); - } -"#; -pub const COLORED_2D_FRAGMENT_SHADER: &str = r#" - #version 140 - - out vec4 color; - uniform vec4 u_color; - - void main() { - color = u_color; - } -"#; - -//TODO store vertex data in a more compact way -pub const CHUNK_VERTEX_SHADER: &str = r#" - #version 150 - - in vec3 position; - in vec3 normal; - - out vec3 v_normal; - - uniform mat4 perspective; - uniform mat4 view; - uniform mat4 model; - - void main() { - mat4 modelview = view * model; - v_normal = transpose(inverse(mat3(modelview))) * normal; - gl_Position = perspective * modelview * vec4(position, 1.0); - } -"#; -pub const CHUNK_FRAGMENT_SHADER: &str = r#" - #version 150 -"#; diff --git a/src/game/shaders/chunk.rs b/src/game/shaders/chunk.rs new file mode 100644 index 0000000..4eb45ed --- /dev/null +++ b/src/game/shaders/chunk.rs @@ -0,0 +1,41 @@ +use glium::implement_vertex; + +#[derive(Clone, Copy)] +pub struct Vertex { + pub position: [f32; 3], + pub normal: [f32; 3], + pub uv: [f32; 2], +} +implement_vertex!(Vertex, position, normal, uv); + +//TODO store vertex data in a more compact way +pub const VERTEX_SHADER: &str = r#" + #version 150 + + in vec3 position; + in vec3 normal; + in vec2 uv; + out vec3 v_normal; + out vec2 v_uv; + uniform mat4 perspective; + uniform mat4 view; + uniform mat4 model; + + void main() { + mat4 modelview = view * model; + v_normal = transpose(inverse(mat3(modelview))) * normal; + v_uv = uv; + gl_Position = perspective * modelview * vec4(position, 1.0); + } +"#; +pub const FRAGMENT_SHADER: &str = r#" + #version 150 + + in vec2 v_uv; + out vec4 color; + uniform sampler2D tex; + + void main() { + color = texture(tex, v_uv); + } +"#; diff --git a/src/game/shaders/colored2d.rs b/src/game/shaders/colored2d.rs new file mode 100644 index 0000000..099e209 --- /dev/null +++ b/src/game/shaders/colored2d.rs @@ -0,0 +1,27 @@ +use glium::{Display, Program, implement_vertex}; + +#[derive(Clone, Copy)] +pub struct Vertex { + pub position: [f32; 2] +} +implement_vertex!(Vertex, position); + +pub const VERTEX_SHADER: &str = r#" + #version 140 + + in vec2 position; + + void main() { + gl_Position = vec4(position, 0., 1.); + } +"#; +pub const FRAGMENT_SHADER: &str = r#" + #version 140 + + out vec4 color; + uniform vec4 u_color; + + void main() { + color = u_color; + } +"#;