aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--README.txt2
-rw-r--r--configs/exuberantplasma.xml22
-rw-r--r--doc/exuberantplasma.6.md77
-rw-r--r--src/bin/exuberantplasma.rs134
5 files changed, 236 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 481ccc3..458c3de 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
# This Makefile is self-documenting (via the 'help' target)
# see: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
-HACKS=exuberantbovines
+HACKS=exuberantbovines exuberantplasma
CARGO ?= cargo
CARGO_OPTS ?=
diff --git a/README.txt b/README.txt
index f5003ee..4f33caa 100644
--- a/README.txt
+++ b/README.txt
@@ -56,6 +56,8 @@ You'll need to create at least three files with the same base name ("$HACK"):
- an XML config file (configs/$HACK.xml)
- a manpage in Markdown format (doc/$HACK.6.md)
+Then just add your HACK to the list in Makefile.
+
See also XScreensaver's "Writing new XScreenSaver modules"
https://github.com/Zygo/xscreensaver/blob/master2/README.hacking
diff --git a/configs/exuberantplasma.xml b/configs/exuberantplasma.xml
new file mode 100644
index 0000000..9034255
--- /dev/null
+++ b/configs/exuberantplasma.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="exuberantplasma" _label="ExuberantPlasma" gl="yes">
+
+ <command arg="--root"/>
+
+ <number id="delay" type="slider" arg="--delay %"
+ _label="Frame rate" _low-label="Low" _high-label="High"
+ low="0" high="100000" default="30000"
+ convert="invert"/>
+
+ <boolean id="wire" _label="Wireframe" arg-set="--wireframe"/>
+ <boolean id="showfps" _label="Show frame rate" arg-set="--fps"/>
+
+ <xscreensaver-updater />
+
+ <_description>
+A port of classic GLSL plasma effect to Rust.
+
+A good template for basic GLSL/shader screensavers.
+ </_description>
+</screensaver>
diff --git a/doc/exuberantplasma.6.md b/doc/exuberantplasma.6.md
new file mode 100644
index 0000000..a04be58
--- /dev/null
+++ b/doc/exuberantplasma.6.md
@@ -0,0 +1,77 @@
+% exuberantplasma(6) | XScreenSaver manual
+
+NAME
+====
+
+**exuberantplasma** — classic GLSL screensaver
+
+SYNOPSIS
+========
+
+| **exuberantplasma** \[**-h**|**--help**] \[**--window-id** _id_] \[**--root**]
+| \[**--wireframe**] \[**--fps**]
+
+DESCRIPTION
+===========
+
+This is a "hack" for the XScreensaver screen locker. It shows a wavey color
+background.
+
+OPTIONS
+=========
+
+_exuberantplasma_ accepts the following options. Note that some long options (like
+**root** and **window-id** can be passed with either a single dash (**-root**)
+or a double-dash (**--root**) for backwards compatibility with XScreensaver.
+
+-h, --help
+
+: Prints brief usage information.
+
+--wireframe
+
+: Render in wireframe instead of solid. (UNIMPLEMENTED)
+
+--fps
+
+: Display the current frame rate, CPU load, and polygon count. (UNIMPLEMENTED)
+
+
+FILES
+=====
+
+*~/.xscreensaver*
+
+: Per-user configuration file. If there isn't a line for this hack in the
+ file, xscreensaver-demo won't find or run this hack.
+
+*/usr/share/xscreensaver/config/exuberantplasma.xml*
+
+: Configuration options for this hack
+
+ENVIRONMENT
+===========
+
+**XSCREENSAVER_WINDOW**
+
+: Optional ID number of the X window to draw into.
+
+Note that **XENVIRONMENT** and **DISPLAY** are *not* implemented.
+
+BUGS
+====
+
+A lot of features (like fps, root-window-finding, wireframe, etc) aren't
+implemented yet.
+
+See GitHub Issues: <https://github.com/bnewbold/exuberant-bovines/issues>
+
+AUTHOR
+======
+
+Bryan Newbold <bnewbold@robocracy.org>
+
+SEE ALSO
+========
+
+**xscreensaver(1)**, **xscreensaver-demo(1)**
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,
+ &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);
+}