diff --git a/src/game.rs b/src/game.rs index 0325673..9ed082b 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,4 +1,4 @@ -use glium::Surface; +use glium::{Surface, uniform}; use glutin::{ event::{Event, WindowEvent}, event_loop::{EventLoop, ControlFlow}, @@ -6,23 +6,37 @@ use glutin::{ mod assets; mod display; +mod shaders; +mod camera; use assets::Assets; use display::init_display; +use shaders::{Programs, Colored2dVertex}; pub fn run() { log::info!("starting up"); let event_loop = EventLoop::new(); log::info!("initializing display"); let display = init_display(&event_loop); + log::info!("compiling shaders"); + let programs = Programs::compile_all(&display); 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 shape = vec![vertex1, vertex2, vertex3]; + let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap(); + //======================= + event_loop.run(move |ev, _, control_flow| { match ev { Event::WindowEvent { event, .. } => match event { WindowEvent::CloseRequested => { + log::info!("exit requested"); *control_flow = ControlFlow::Exit; return }, @@ -32,6 +46,7 @@ pub fn run() { } let mut target = display.draw(); 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.finish().unwrap(); }); } diff --git a/src/game/camera.rs b/src/game/camera.rs new file mode 100644 index 0000000..31c91e8 --- /dev/null +++ b/src/game/camera.rs @@ -0,0 +1,35 @@ +// https://glium.github.io/glium/book/tuto-12-camera.html + +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] + }; + + 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], + ] +} diff --git a/src/game/shaders.rs b/src/game/shaders.rs new file mode 100644 index 0000000..58f6345 --- /dev/null +++ b/src/game/shaders.rs @@ -0,0 +1,61 @@ +use glium::{Display, Program, implement_vertex}; + +pub struct Programs { + pub colored_2d: 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(), + } + } +} + +#[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 +"#;