diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/exuberantplasma.rs | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/bin/exuberantplasma.rs b/src/bin/exuberantplasma.rs new file mode 100644 index 0000000..5d49a56 --- /dev/null +++ b/src/bin/exuberantplasma.rs @@ -0,0 +1,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, + ¶ms).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); +} |