aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/exuberantplasma.rs
blob: 5d49a561d9759b7ece6bbf8b5b1dae4348c0ef39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

extern crate exuberant;
extern crate getopts;

#[macro_use]
extern crate glium; 

use exuberant::ExuberantHack;
use getopts::Options;
use glium::Surface;

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
}
implement_vertex!(Vertex, position);

struct ExuberantPlasma {
    display: glium::Display,
    program: glium::Program,
}
 
impl ExuberantPlasma {

    pub fn new(display: glium::Display) -> ExuberantPlasma {

        let vertex_shader_src = r#" #version 140 
            
            in vec2 position;
            out vec2 v_coords;

            void main() {
                v_coords = position;
                gl_Position = vec4(position, 0.0, 1.0);
            }
        "#; 

        // This fragment shader verbatim from:
        // http://www.bidouille.org/prog/plasma
        let fragment_shader_src = r#" #version 140

            precision mediump float;
            #define PI 3.1415926535897932384626433832795
            
            uniform float u_time;
            uniform vec2 u_k;
            varying vec2 v_coords;
            
            void main() {
                float v = 0.0;
                vec2 c = v_coords * u_k - u_k/2.0;
                v += sin((c.x+u_time));
                v += sin((c.y+u_time)/2.0);
                v += sin((c.x+c.y+u_time)/2.0);
                c += u_k/2.0 * vec2(sin(u_time/3.0), cos(u_time/2.0));
                v += sin(sqrt(c.x*c.x+c.y*c.y+1.0)+u_time);
                v = v/2.0;
                vec3 col = vec3(1, sin(PI*v), cos(PI*v));
                gl_FragColor = vec4(col*.5 + .5, 1);
            }
        "#;


        let program = glium::Program::from_source(
            &display,
            vertex_shader_src,
            fragment_shader_src,
            None).unwrap();

        ExuberantPlasma {
            display: display,
            program: program,
        }
    }
}

impl ExuberantHack for ExuberantPlasma {

    fn draw_frame(&mut self, t: f64) -> Result<(), String> {

        let vertex1 = Vertex { position: [-1.0, -1.0] };
        let vertex2 = Vertex { position: [ 3.0, -1.0] };
        let vertex3 = Vertex { position: [-1.0,  3.0] };
        let shape = vec![vertex1, vertex2, vertex3];

        let vertex_buffer = glium::VertexBuffer::new(&self.display, &shape).unwrap();

        let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

        // Drawing Pipeline
        let mut target = self.display.draw();

        let uniforms = uniform! {
            u_time: (t % (12.0 * 3.141592)) as f32,
            u_k: [10.0 as f32, 10.0 as f32],
        };

        // Set black background
        target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);

        let params = glium::DrawParameters {
            .. Default::default()
        };

        target.draw(&vertex_buffer,
                    &indices,
                    &self.program,
                    &uniforms,
                    &params).unwrap();

        target.finish().or(Err("Failure rendering".to_string()))
    }

    fn get_display(&self) -> &glium::Display {
        &self.display
    }
}

fn main() {

    let mut opts = Options::new();
    opts.optopt("c", "count", "how many cows? (1 to 9) (IGNORED)", "NUM");
    opts.optopt("s", "speed", "how fast? ratio, with 1.0 as normal (IGNORED)", "NUM");
    opts.optflag("", "wireframe", "wireframe mode (IGNORED)");

    let conf = exuberant::main_helper(opts);
    let dislpay = exuberant::make_display(&conf);
    let mut hack = ExuberantPlasma::new(dislpay);

    // Here is where you would configure the hack based on command line options

    // Ok, actually run it (loops forever)
    exuberant::run(&mut hack, &conf);
}