Ignore generated files.
[mandelwow.git] / mandelwow.rs
1 // Wow. Such fractal.
2
3 use cube::Cube;
4 use glium;
5 use glium::index::PrimitiveType;
6 use glium::Surface;
7 use support;
8
9
10 /*
11 fn mand(cx: f32, cy: f32) -> [f32; 3] {
12     let maxiter = 64;
13     let mut iter = maxiter;
14     let mut zx = cx;
15     let mut zy = cy;
16     while iter > 0 {
17         let zx2 = zx * zx;
18         let zy2 = zy * zy;
19         if zx2 + zy2 > 4.0 {
20             return [iter as f32 / maxiter as f32, 1.0, 1.0];
21         }
22         zy = zx * zy * 2.0 + cy;
23         zx = zx2 - zy2 + cx;
24         iter -= 1;
25     }
26
27     [0.0, 0.0, 0.0]
28 }
29 */
30
31 pub fn program(display: &glium::Display) -> glium::Program {
32     return program!(display,
33         140 => {
34             vertex: r#"
35                 #version 140
36                 uniform mat4 perspective;
37                 uniform mat4 view;
38                 uniform mat4 model;
39                 uniform vec2 z0;
40                 in vec3 position;
41                 out vec2 c;
42                 out vec2 z;
43
44                 void main() {
45                     mat4 modelview = view * model;
46                     gl_Position = perspective * modelview * vec4(position, 1.0);
47                     c = vec2(position.x, position.y);
48                     z = vec2(z0.x, z0.y);
49                 }
50             "#,
51
52             fragment: r#"
53                 #version 140
54                 precision highp float;
55                 in vec2 c;
56                 in vec2 z;
57                 out vec4 f_color;
58
59                 void main() {
60                     float zx = z.x;
61                     float zy = z.y;
62                     int maxiter = 64;
63                     int iter = maxiter;
64                     while (iter > 0) {
65                         float zx2 = zx * zx;
66                         float zy2 = zy * zy;
67                         if (zx2 * zy2 > 4.0) {
68                           float index = float(iter) / float(maxiter);
69                           f_color = vec4(index, 0.1, 0.5 - index / 2, 0.8 - index);
70                           return;
71                         }
72                         zy = zx * zy * 2.0 + c.y;
73                         zx = zx2 - zy2 + c.x;
74                         iter -= 1;
75                     }
76                     f_color = vec4((sin(z.y) + 1.0) / 2,
77                                    (sin(c.y) + 1.0) / 2,
78                                    (sin(c.x) + 1.0) / 2,
79                                    1.0);
80                 }
81             "#
82         }).unwrap();
83 }
84
85 fn mandel<U>(display: &glium::Display,
86           frame: &mut glium::Frame,
87           program: &glium::Program,
88           uniforms: &U,
89           bounds: &Cube,
90           z: [f32; 2]) where U: glium::uniforms::Uniforms {
91
92     #[derive(Copy, Clone)]
93     struct Vertex {
94         position: [f32; 3],
95         color: [f32; 3],
96     }
97     implement_vertex!(Vertex, position, color);
98
99     let xmin = bounds.xmin;
100     let xmax = bounds.xmax;
101     let ymin = bounds.ymin;
102     let ymax = bounds.ymax;
103
104     let width = xmax - xmin;
105     let height = ymax - ymin;
106     let xres: usize = 1;
107     let yres: usize = 1;
108     let xstep = width / (xres as f32);
109     let ystep = height / (yres as f32);
110     let vb_size = (xres * 2 + 4) * yres;
111     let mut v : Vec<Vertex> = Vec::with_capacity(vb_size);
112     v.resize(vb_size, Vertex { position: [0.0, 0.0, -1.0], color: [0.0, 0.0, 0.0] });
113     let mut i: usize = 0;
114     let mut vy = ymin;
115     let vz = z[1];
116     for _ in 0..yres {
117         let mut vx = xmin;
118         let c = [0.0, 0.0, 1.0];
119         v[i] = Vertex { position: [vx, vy+ystep, vz], color: c }; i += 1;
120         v[i] = Vertex { position: [vx, vy,       vz], color: c }; i += 1;
121         for _ in 0..xres {
122             //let c = mand(vx, vy);
123             v[i] = Vertex { position: [vx+xstep, vy+ystep, vz], color: c }; i += 1;
124             v[i] = Vertex { position: [vx+xstep, vy,       vz], color: c }; i += 1;
125             vx += xstep;
126         }
127         v[i] = Vertex { position: [vx,   vy, vz], color: c }; i += 1;
128         v[i] = Vertex { position: [xmin, vy, vz], color: c }; i += 1;
129         vy += ystep;
130     }
131
132     //let vb = glium::VertexBuffer::empty_persistent(display, width*height*3).unwrap();
133     let vb = glium::VertexBuffer::new(display, &v).unwrap();
134
135     let indices = glium::index::NoIndices(PrimitiveType::TriangleStrip);
136     //let indices = glium::index::NoIndices(PrimitiveType::LineStrip);
137     //let indices = glium::IndexBuffer::new(display, PrimitiveType::TrianglesList,
138     //                                      &[0u16, 1, 2]).unwrap();
139
140     let params = glium::DrawParameters {
141         depth: glium::Depth {
142             test: glium::draw_parameters::DepthTest::IfLess,
143             write: true,
144             ..Default::default()
145         },
146         blend: glium::Blend::alpha_blending(),
147         ..Default::default()
148     };
149
150     frame.draw(&vb, &indices, program, uniforms, &params).unwrap();
151 }
152
153 pub fn draw(display: &glium::Display,
154              mut frame: &mut glium::Frame,
155              program: &glium::Program,
156              model: [[f32; 4]; 4],
157              camera: &support::camera::CameraState,
158              bounds: &Cube,
159              mandel_w: f32) {
160     let mut z0 = [mandel_w, 0f32];
161     let zres = 30;
162     let zmin = bounds.zmin;
163     let zmax = bounds.zmax;
164     let zstep = (zmax - zmin) / zres as f32;
165     let mut zy = zmin;
166     // zres + 1 to reach the other face of the cube (fencepost error)
167     for _ in 0..(zres + 1) {
168         z0[1] = zy;
169         zy += zstep;
170
171         let uniforms = uniform! {
172             z0: z0,
173             model: model,
174             view:  camera.get_view(),
175             perspective: camera.get_perspective(),
176         };
177
178         mandel(&display, &mut frame, &program, &uniforms, bounds, z0);
179     }
180 }