Put text on the top faces of cubes.
[mandelwow.git] / mandelwow.rs
1 // Wow. Such fractal.
2
3 use cube::Cube;
4 use glium;
5 use glium::index::PrimitiveType;
6 use glium::{Display, Program, Surface};
7 use support;
8
9 /*
10 fn mand(cx: f32, cy: f32) -> [f32; 3] {
11     let maxiter = 64;
12     let mut iter = maxiter;
13     let mut zx = cx;
14     let mut zy = cy;
15     while iter > 0 {
16         let zx2 = zx * zx;
17         let zy2 = zy * zy;
18         if zx2 + zy2 > 4.0 {
19             return [iter as f32 / maxiter as f32, 1.0, 1.0];
20         }
21         zy = zx * zy * 2.0 + cy;
22         zx = zx2 - zy2 + cx;
23         iter -= 1;
24     }
25
26     [0.0, 0.0, 0.0]
27 }
28 */
29
30 pub fn program(display: &Display) -> Program {
31     Program::from_source(
32             display,
33             include_str!("shaders/mandelwow.vert"),
34             include_str!("shaders/mandelwow.frag"), None)
35         .unwrap()
36 }
37
38 fn mandel<U>(display: &Display,
39           frame: &mut glium::Frame,
40           program: &Program,
41           uniforms: &U,
42           bounds: &Cube,
43           z: [f32; 2]) where U: glium::uniforms::Uniforms {
44
45     #[derive(Copy, Clone)]
46     struct Vertex {
47         position: [f32; 3],
48         color: [f32; 3],
49     }
50     implement_vertex!(Vertex, position, color);
51
52     let xmin = bounds.xmin;
53     let xmax = bounds.xmax;
54     let ymin = bounds.ymin;
55     let ymax = bounds.ymax;
56
57     let width = xmax - xmin;
58     let height = ymax - ymin;
59     let xres: usize = 1;
60     let yres: usize = 1;
61     let xstep = width / (xres as f32);
62     let ystep = height / (yres as f32);
63     let vb_size = (xres * 2 + 4) * yres;
64     let mut v : Vec<Vertex> = Vec::with_capacity(vb_size);
65     v.resize(vb_size, Vertex { position: [0.0, 0.0, -1.0], color: [0.0, 0.0, 0.0] });
66     let mut i: usize = 0;
67     let mut vy = ymin;
68     let vz = z[1];
69     for _ in 0..yres {
70         let mut vx = xmin;
71         let c = [0.0, 0.0, 1.0];
72         v[i] = Vertex { position: [vx, vy+ystep, vz], color: c }; i += 1;
73         v[i] = Vertex { position: [vx, vy,       vz], color: c }; i += 1;
74         for _ in 0..xres {
75             //let c = mand(vx, vy);
76             v[i] = Vertex { position: [vx+xstep, vy+ystep, vz], color: c }; i += 1;
77             v[i] = Vertex { position: [vx+xstep, vy,       vz], color: c }; i += 1;
78             vx += xstep;
79         }
80         v[i] = Vertex { position: [vx,   vy, vz], color: c }; i += 1;
81         v[i] = Vertex { position: [xmin, vy, vz], color: c }; i += 1;
82         vy += ystep;
83     }
84
85     //let vb = glium::VertexBuffer::empty_persistent(display, width*height*3).unwrap();
86     let vb = glium::VertexBuffer::new(display, &v).unwrap();
87
88     let indices = glium::index::NoIndices(PrimitiveType::TriangleStrip);
89     //let indices = glium::index::NoIndices(PrimitiveType::LineStrip);
90     //let indices = glium::IndexBuffer::new(display, PrimitiveType::TrianglesList,
91     //                                      &[0u16, 1, 2]).unwrap();
92
93     let params = glium::DrawParameters {
94         depth: glium::Depth {
95             test: glium::draw_parameters::DepthTest::IfLess,
96             write: true,
97             ..Default::default()
98         },
99         blend: glium::Blend::alpha_blending(),
100         ..Default::default()
101     };
102
103     frame.draw(&vb, &indices, program, uniforms, &params).unwrap();
104 }
105
106 pub fn draw(display: &Display,
107              mut frame: &mut glium::Frame,
108              program: &Program,
109              model: [[f32; 4]; 4],
110              camera: &support::camera::CameraState,
111              bounds: &Cube,
112              mandel_w: f32) {
113     let mut z0 = [mandel_w, 0f32];
114     let zres = 30;
115     let zmin = bounds.zmin;
116     let zmax = bounds.zmax;
117     let zstep = (zmax - zmin) / zres as f32;
118     let mut zy = zmin;
119     // zres + 1 to reach the other face of the cube (fencepost error)
120     for _ in 0..(zres + 1) {
121         z0[1] = zy;
122         zy += zstep;
123
124         let uniforms = uniform! {
125             z0: z0,
126             model: model,
127             view:  camera.get_view(),
128             perspective: camera.get_perspective(),
129         };
130
131         mandel(display, &mut frame, program, &uniforms, bounds, z0);
132     }
133 }