Add a sea shaded cubes, just because. No big deal (yet).
authorBernie Innocenti <bernie@codewiz.org>
Sat, 6 May 2017 23:33:13 +0000 (19:33 -0400)
committerBernie Innocenti <bernie@codewiz.org>
Sat, 6 May 2017 23:33:13 +0000 (19:33 -0400)
cube.rs
lib.rs
main.rs
shaded.frag [new file with mode: 0644]
shaded.vert [new file with mode: 0644]
shaded_cube.rs [new file with mode: 0644]

diff --git a/cube.rs b/cube.rs
index de5315b80fa498404e6108d8e450732312488e32..916b8689d4ee5b8efc0072e9756a443e11d36b49 100644 (file)
--- a/cube.rs
+++ b/cube.rs
@@ -1,6 +1,6 @@
 use std::f32;
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub struct Cube {
     pub xmin: f32,
     pub ymin: f32,
@@ -9,3 +9,10 @@ pub struct Cube {
     pub ymax: f32,
     pub zmax: f32,
 }
+
+// Returns a unit Cube centered in the origin.
+impl Default for Cube {
+    fn default() -> Cube {
+        Cube { xmin: -0.5, ymin: -0.5, zmin: -0.5, xmax: 0.5, ymax: 0.5, zmax: 0.5f32 }
+    }
+}
diff --git a/lib.rs b/lib.rs
index 8fd85f419be5ad221d0347cde5b668f28aba6f6b..aaf2b3c708b4786b9183b8c0d690c305ec345e6b 100644 (file)
--- a/lib.rs
+++ b/lib.rs
@@ -8,7 +8,10 @@ extern crate sdl2;
 pub mod bounding_box;
 pub mod cube;
 pub mod mandelwow;
+pub mod shaded_cube;
 pub mod sound;
 pub mod support;
 
+pub use bounding_box::BoundingBox;
 pub use cube::Cube;
+pub use shaded_cube::ShadedCube;
diff --git a/main.rs b/main.rs
index c58cf5510201cae4949df756f3ed4ac4e6f2f869..e16ba9d9d86155a209d2de08427d76e6ca35d282 100644 (file)
--- a/main.rs
+++ b/main.rs
@@ -6,7 +6,8 @@ extern crate glium;
 extern crate glutin;
 extern crate image;
 
-use cgmath::{Euler, Matrix4, Rad, Vector3};
+use cgmath::{Euler, Matrix4, One, Rad, Vector3};
+use cgmath::conv::array4x4;
 use glium::{DisplayBuild, Surface};
 use glutin::ElementState::Pressed;
 use glutin::Event::KeyboardInput;
@@ -82,6 +83,7 @@ fn main() {
 
     let mandelwow_program = mandelwow::program(&display);
     let bounding_box_program = bounding_box::solid_fill_program(&display);
+    let shaded_program = shaded_cube::shaded_program(&display);
 
     let mut camera = support::camera::CameraState::new();
     let mut t: f32 = 0.0;
@@ -99,6 +101,27 @@ fn main() {
         zmax:  1.1,
     };
     let mandelwow_bbox = bounding_box::BoundingBox::new(&display, &bounds, &bounding_box_program);
+    let shaded_cube = ShadedCube::new(&display, &Cube::default(), &shaded_program);
+
+    const SEA_XSIZE: usize = 24;
+    const SEA_ZSIZE: usize = 20;
+    let sea_xmin = -14.0f32;
+    let sea_xmax =  14.0f32;
+    let sea_zmin =  -2.0f32;
+    let sea_zmax = -26.0f32;
+    let sea_xstep = (sea_xmax - sea_xmin) / (SEA_XSIZE as f32);
+    let sea_zstep = (sea_zmax - sea_zmin) / (SEA_ZSIZE as f32);
+
+    let mut sea = [[Matrix4::one(); SEA_ZSIZE]; SEA_XSIZE];
+    for x in 0..SEA_XSIZE {
+        for z in 0..SEA_ZSIZE {
+            sea[x][z] = Matrix4::from_translation(Vector3{
+                x: sea_xmin + (x as f32) * sea_xstep,
+                y: -3.0,
+                z: sea_zmin + (z as f32) * sea_zstep,
+            });
+        }
+     }
 
     set_main_loop_callback(|| {
         camera.update();
@@ -124,7 +147,7 @@ fn main() {
         let z_trans = -2.0;  // Send the model back a little bit so it fits the screen.
         let model2 =
             Matrix4::from_translation(Vector3::unit_z() * z_trans) * rotation;
-        let model = cgmath::conv::array4x4(model2);
+        let model = array4x4(model2);
 
         // Draw the bounding box before the fractal, when the Z-buffer is still clear,
         // so the lines behind the semi-translucent areas will be drawn.
@@ -137,6 +160,17 @@ fn main() {
             mandelwow_bbox.draw(&mut frame, &uniforms);
         }
 
+        for x in 0..SEA_XSIZE {
+            for z in 0..SEA_ZSIZE {
+                let uniforms = uniform! {
+                    model: array4x4(sea[x][z]),
+                    view:  camera.get_view(),
+                    perspective: camera.get_perspective(),
+                };
+                shaded_cube.draw(&mut frame, &uniforms);
+            }
+        }
+
         mandelwow::draw(&display, &mut frame, &mandelwow_program, model, &camera, &bounds, wow);
         frame.finish().unwrap();
 
diff --git a/shaded.frag b/shaded.frag
new file mode 100644 (file)
index 0000000..e48c837
--- /dev/null
@@ -0,0 +1,9 @@
+#version 300 es
+precision lowp float;
+
+in vec4 color;
+out vec4 color_out;
+
+void main() {
+    color_out = color;
+}
diff --git a/shaded.vert b/shaded.vert
new file mode 100644 (file)
index 0000000..4f3035c
--- /dev/null
@@ -0,0 +1,22 @@
+#version 300 es
+precision lowp float;
+
+in vec3 position;
+in vec3 normal;
+out vec4 color;
+
+uniform mat4 perspective;
+uniform mat4 view;
+uniform mat4 model;
+
+void main() {
+    mat4 modelview = view * model;
+    mat4 m = perspective * modelview;
+    vec3 dark = vec3(0.0, 0.0, 0.1);
+    vec3 bright = vec3(0.0, 0.0, 0.9);
+    vec3 u_light = vec3(-0.5, -0.5, -1.);
+    vec3 v_normal = transpose(inverse(mat3(model))) * normal;
+    float brightness = max(dot(normalize(v_normal), normalize(u_light)), 0.0);
+    color = vec4(mix(dark, bright, brightness), 1.0);
+    gl_Position = m * vec4(position, 1.0);
+}
diff --git a/shaded_cube.rs b/shaded_cube.rs
new file mode 100644 (file)
index 0000000..fb4fb1d
--- /dev/null
@@ -0,0 +1,184 @@
+use cube::Cube;
+use glium;
+use glium::{Display, Program, Surface};
+use glium::index::{IndexBuffer, PrimitiveType};
+
+pub fn shaded_program(display: &Display) -> Program {
+    let vertex_shader_src = include_str!("shaded.vert");
+    let fragment_shader_src = include_str!("shaded.frag");
+    return Program::from_source(display, vertex_shader_src, fragment_shader_src, None).unwrap();
+}
+
+#[derive(Copy, Clone)]
+struct Vertex {
+    position: [f32; 3],
+    normal: [f32; 3],
+}
+implement_vertex!(Vertex, position, normal);
+
+pub struct ShadedCube<'a> {
+    vertexes: glium::VertexBuffer<Vertex>,
+    program: &'a Program,
+    indices: IndexBuffer<u16>,
+}
+
+impl<'a> ShadedCube<'a> {
+    pub fn new(display: &Display, c: &Cube, program: &'a Program) -> ShadedCube<'a> {
+        //      x--->
+        //      4 ──────┐ 5   
+        //      ╱┆     ╱│
+        //   0 ┌─────┐1 │
+        // y   │ 7+┄┄│┄┄+ 6 
+        // |   │╱    │ ╱   /
+        // v   └─────┘    z
+        //    3       2
+        let vertex_data = [
+            // Front face
+            Vertex { position: [c.xmin, c.ymin, c.zmin], normal: [  0.,  0.,  1.] },  // 0
+            Vertex { position: [c.xmax, c.ymin, c.zmin], normal: [  0.,  0.,  1.] },  // 1
+            Vertex { position: [c.xmax, c.ymax, c.zmin], normal: [  0.,  0.,  1.] },  // 2
+            Vertex { position: [c.xmin, c.ymax, c.zmin], normal: [  0.,  0.,  1.] },  // 3
+
+            // Back face
+            Vertex { position: [c.xmin, c.ymax, c.zmax], normal: [  0.,  0., -1.] },  // 7
+            Vertex { position: [c.xmax, c.ymax, c.zmax], normal: [  0.,  0., -1.] },  // 6
+            Vertex { position: [c.xmax, c.ymin, c.zmax], normal: [  0.,  0., -1.] },  // 5
+            Vertex { position: [c.xmin, c.ymin, c.zmax], normal: [  0.,  0., -1.] },  // 4
+
+            // Right face
+            Vertex { position: [c.xmax, c.ymin, c.zmin], normal: [ -1.,  0.,  0.] },  // 1
+            Vertex { position: [c.xmax, c.ymin, c.zmax], normal: [ -1.,  0.,  0.] },  // 5
+            Vertex { position: [c.xmax, c.ymax, c.zmax], normal: [ -1.,  0.,  0.] },  // 6
+            Vertex { position: [c.xmax, c.ymax, c.zmin], normal: [ -1.,  0.,  0.] },  // 2
+
+            // Left face
+            Vertex { position: [c.xmin, c.ymin, c.zmin], normal: [  1.,  0.,  0.] },  // 0
+            Vertex { position: [c.xmin, c.ymax, c.zmin], normal: [  1.,  0.,  0.] },  // 3
+            Vertex { position: [c.xmin, c.ymax, c.zmax], normal: [  1.,  0.,  0.] },  // 7
+            Vertex { position: [c.xmin, c.ymin, c.zmax], normal: [  1.,  0.,  0.] },  // 4
+
+            // Top face
+            Vertex { position: [c.xmin, c.ymin, c.zmin], normal: [  0.,  1.,  0.] },  // 0
+            Vertex { position: [c.xmin, c.ymin, c.zmax], normal: [  0.,  1.,  0.] },  // 4
+            Vertex { position: [c.xmax, c.ymin, c.zmax], normal: [  0.,  1.,  0.] },  // 5
+            Vertex { position: [c.xmax, c.ymin, c.zmin], normal: [  0.,  1.,  0.] },  // 1
+
+            // Bottom face
+            Vertex { position: [c.xmax, c.ymax, c.zmin], normal: [  0., -1.,  0.] },  // 2
+            Vertex { position: [c.xmax, c.ymax, c.zmax], normal: [  0., -1.,  0.] },  // 6
+            Vertex { position: [c.xmin, c.ymax, c.zmax], normal: [  0., -1.,  0.] },  // 7
+            Vertex { position: [c.xmin, c.ymax, c.zmin], normal: [  0., -1.,  0.] },  // 3
+        ];
+        const INDICES: &[u16] = &[
+             0,  1,  2,  0,  2,  3,  // Front
+             4,  5,  6,  4,  6,  7,  // Back
+             8,  9, 10,  8, 10, 11,  // Right
+            12, 13, 14, 12, 14, 15,  // Left
+            16, 17, 18, 16, 18, 19,  // Top
+            20, 21, 22, 20, 22, 23u16  // Bottom
+        ];
+
+        ShadedCube {
+            vertexes: glium::VertexBuffer::new(display, &vertex_data).unwrap(),
+            program: program,
+            indices:  IndexBuffer::new(display, PrimitiveType::TrianglesList, INDICES).unwrap(),
+        }
+    }
+
+    pub fn draw<U>(&self, frame: &mut glium::Frame, uniforms: &U)
+            where U: glium::uniforms::Uniforms {
+        let params = glium::DrawParameters {
+            depth: glium::Depth {
+                test: glium::draw_parameters::DepthTest::IfLess,
+                write: true,
+                ..Default::default()
+            },
+            blend: glium::Blend::alpha_blending(),
+            ..Default::default()
+        };
+        frame.draw(&self.vertexes, &self.indices, &self.program, uniforms, &params).unwrap();
+    }
+}
+
+/*
+pub fn draw<U>(display: &Display,
+               frame: &mut glium::Frame,
+               program: &Program,
+               uniforms: &U,
+               cube: &Cube) where U: glium::uniforms::Uniforms {
+
+    implement_vertex!(Vertex, position, normal);
+
+    #[derive(Copy, Clone)]
+    struct Normal { normal: [f32; 3] }
+    implement_vertex!(Normal, normal);
+
+    //      x--->
+    //      4 ──────┐ 5   
+    //      ╱┆     ╱│
+    //   0 ┌─────┐1 │
+    // y   │ 7+┄┄│┄┄+ 6 
+    // |   │╱    │ ╱   /
+    // v   └─────┘    z
+    //    3       2
+    let cube = [
+        // Front face
+        Vertex { position: [cube.xmin, cube.ymin, cube.zmin], normal: [  0.,  0.,  1.] },  // 0
+        Vertex { position: [cube.xmax, cube.ymin, cube.zmin], normal: [  0.,  0.,  1.] },  // 1
+        Vertex { position: [cube.xmax, cube.ymax, cube.zmin], normal: [  0.,  0.,  1.] },  // 2
+        Vertex { position: [cube.xmin, cube.ymax, cube.zmin], normal: [  0.,  0.,  1.] },  // 3
+
+        // Back face
+        Vertex { position: [cube.xmin, cube.ymax, cube.zmax], normal: [  0.,  0., -1.] },  // 7
+        Vertex { position: [cube.xmax, cube.ymax, cube.zmax], normal: [  0.,  0., -1.] },  // 6
+        Vertex { position: [cube.xmax, cube.ymin, cube.zmax], normal: [  0.,  0., -1.] },  // 5
+        Vertex { position: [cube.xmin, cube.ymin, cube.zmax], normal: [  0.,  0., -1.] },  // 4
+
+        // Right face
+        Vertex { position: [cube.xmax, cube.ymin, cube.zmin], normal: [ -1.,  0.,  0.] },  // 1
+        Vertex { position: [cube.xmax, cube.ymin, cube.zmax], normal: [ -1.,  0.,  0.] },  // 5
+        Vertex { position: [cube.xmax, cube.ymax, cube.zmax], normal: [ -1.,  0.,  0.] },  // 6
+        Vertex { position: [cube.xmax, cube.ymax, cube.zmin], normal: [ -1.,  0.,  0.] },  // 2
+
+        // Left face
+        Vertex { position: [cube.xmin, cube.ymin, cube.zmin], normal: [  1.,  0.,  0.] },  // 0
+        Vertex { position: [cube.xmin, cube.ymax, cube.zmin], normal: [  1.,  0.,  0.] },  // 3
+        Vertex { position: [cube.xmin, cube.ymax, cube.zmax], normal: [  1.,  0.,  0.] },  // 7
+        Vertex { position: [cube.xmin, cube.ymin, cube.zmax], normal: [  1.,  0.,  0.] },  // 4
+
+        // Top face
+        Vertex { position: [cube.xmin, cube.ymin, cube.zmin], normal: [  0.,  1.,  0.] },  // 0
+        Vertex { position: [cube.xmin, cube.ymin, cube.zmax], normal: [  0.,  1.,  0.] },  // 4
+        Vertex { position: [cube.xmax, cube.ymin, cube.zmax], normal: [  0.,  1.,  0.] },  // 5
+        Vertex { position: [cube.xmax, cube.ymin, cube.zmin], normal: [  0.,  1.,  0.] },  // 1
+
+        // Bottom face
+        Vertex { position: [cube.xmax, cube.ymax, cube.zmin], normal: [  0., -1.,  0.] },  // 2
+        Vertex { position: [cube.xmax, cube.ymax, cube.zmax], normal: [  0., -1.,  0.] },  // 6
+        Vertex { position: [cube.xmin, cube.ymax, cube.zmax], normal: [  0., -1.,  0.] },  // 7
+        Vertex { position: [cube.xmin, cube.ymax, cube.zmin], normal: [  0., -1.,  0.] },  // 3
+    ];
+    let vb = glium::VertexBuffer::new(display, &cube).unwrap();
+
+    let params = glium::DrawParameters {
+        depth: glium::Depth {
+            test: glium::draw_parameters::DepthTest::IfLess,
+            write: true,
+            ..Default::default()
+        },
+        blend: glium::Blend::alpha_blending(),
+        ..Default::default()
+    };
+
+    let front_indices = IndexBuffer::new(display, PrimitiveType::TrianglesList,
+                                         &[  0,  1,  2,  0,  2,  3,  // Front
+                                             4,  5,  6,  4,  6,  7,  // Back
+                                             8,  9, 10,  8, 10, 11,  // Right
+                                            12, 13, 14, 12, 14, 15,  // Left
+                                            16, 17, 18, 16, 18, 19,  // Top
+                                            20, 21, 22, 20, 22, 23u16,  // Bottom
+                                        ]).unwrap();
+    frame.draw(&vb, &front_indices, program, uniforms, &params).unwrap();
+}
+
+*/