From 03faaf6551fadf74a581b5090592babcddac3c98 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Fri, 6 May 2016 15:34:37 -0400 Subject: getting towards running --- src/main.rs | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/util.rs | 36 ++++++++++++++++ 2 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/util.rs diff --git a/src/main.rs b/src/main.rs index f027359..a4fd789 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,10 +3,148 @@ extern crate glium; extern crate image; +mod util; mod cow_face; fn run() { - println!("Hello, world!"); + + use glium::{DisplayBuild, Surface}; + + let mut t: f32 = 0.0; + let mut x: f32; + + let display = glium::glutin::WindowBuilder::new() + .with_title(format!("Exuberant Cow!")) + .with_depth_buffer(24) + .build_glium() + .unwrap(); + + let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList); + let vertices = glium::VertexBuffer::new( + &display, &cow_face::cow_face_vertices).unwrap(); + let vertex_shader_src = r#" + #version 140 + + uniform mat4 perspective; + uniform mat4 view; + uniform mat4 model; + + in vec3 position; + in vec3 normal; + + out vec3 v_normal; + out vec3 v_position; + + void main() { + mat4 modelview = view * model; + v_normal = transpose(inverse(mat3(modelview))) * normal; + gl_Position = perspective * modelview * vec4(position, 1.0); + v_position = gl_Position.xyz / gl_Position.w; + } + "#; + + let fragment_shader_src = r#" + #version 140 + + uniform vec3 u_light; + + in vec3 v_normal; + in vec3 v_position; + + out vec4 color; + + const vec3 ambient_color = vec3(0.2, 0.0, 0.0); + const vec3 diffuse_color = vec3(0.6, 0.0, 0.0); + const vec3 specular_color = vec3(1.0, 1.0, 1.0); + + void main() { + float diffuse = max(dot(normalize(v_normal), normalize(u_light)), 0.0); + + vec3 camera_dir = normalize(-v_position); + vec3 half_direction = normalize(normalize(u_light) + camera_dir); + float specular = pow(max(dot(half_direction, normalize(v_normal)), 0.0), 16.); + color = vec4(ambient_color + + diffuse * diffuse_color + + specular * specular_color, 1.0); + } + "#; + + + let program = glium::Program::from_source( + &display, + vertex_shader_src, + fragment_shader_src, + None).unwrap(); + + loop { + + t += 0.02; + x = 0.5 * t.sin(); + + // Drawing Pipeline + let mut target = display.draw(); + + let (width, height) = target.get_dimensions(); + let aspect_ratio = height as f32 / width as f32; + + // Calculate Perspective Matrix + let fov: f32 = 3.141592 / 3.0; // 120 deg + let zfar = 1024.0; + let znear = 0.1; + + let f = 1.0 / (fov / 2.0).tan(); + + let perspective = [ + [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], + ]; + + let light = [-1.0, 0.4, 0.9f32]; + + let view = util::view_matrix(&[2.0, -1.0, 1.0], &[-2.0, 1.0, 1.0], &[0.0, 1.0, 0.0]); + let uniforms = uniform! { + model: [ + [ 0.3, 0.0, 0.0, 0.0 ], + [ 0.0, 0.3, 0.0, 0.0 ], + [ 0.0, 0.0, 0.3, 0.0 ], + [ x, 0.0, 2.0, 1.0 ]], + u_light: light, + perspective: perspective, + view: view, + }; + + target.clear_color_and_depth((0.2, 0.2, 0.2, 1.0), 1.0); + + let params = glium::DrawParameters { + depth: glium::Depth { + test: glium::draw_parameters::DepthTest::IfLess, + write: true, + .. Default::default() + }, + // NB: would enable if all models were "closed" ("sealed", no gaps) + backface_culling: glium::draw_parameters::BackfaceCullingMode::CullClockwise, + .. Default::default() + }; + + target.draw(&vertices, + &indices, + &program, + &uniforms, + ¶ms).unwrap(); + + target.finish().unwrap(); + + for ev in display.poll_events() { + match ev { + glium::glutin::Event::Closed => return, + _ => () + } + } + // XXX: sleep here for 10ms + } + } fn main() { diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..f35c157 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,36 @@ + +pub 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[0], u[0], f[0], 0.0], + [s[1], u[1], f[1], 0.0], + [s[2], u[2], f[2], 0.0], + [p[0], p[1], p[2], 1.0], + ] +} -- cgit v1.2.3