├── .gitignore ├── .travis.yml ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── android └── build-and-install ├── assets └── screenshots │ ├── shot1.png │ └── shot2.png ├── docs ├── algorithm.md ├── android.md └── hacking.md ├── src ├── fps.rs ├── main.rs ├── params.rs ├── screenshot.rs ├── shader_loader.rs └── shaders │ ├── blit.glsl │ ├── feedback.glsl │ └── vertex.glsl └── tests └── validate-shaders.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - stable 4 | # - beta # Disabled for rustc 1.18.0-beta due to rust-lang/rust#41604 5 | - nightly 6 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "azurescens" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "glium 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "image 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", 8 | "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 9 | "serde 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 10 | "serde_derive 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 11 | "tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 12 | "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 13 | "tunapanel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 14 | ] 15 | 16 | [[package]] 17 | name = "adler32" 18 | version = "1.0.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | 21 | [[package]] 22 | name = "aho-corasick" 23 | version = "0.6.3" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | dependencies = [ 26 | "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 27 | ] 28 | 29 | [[package]] 30 | name = "android_glue" 31 | version = "0.2.2" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | 34 | [[package]] 35 | name = "backtrace" 36 | version = "0.2.3" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | dependencies = [ 39 | "backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 40 | "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 41 | "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 42 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 43 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 44 | "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 45 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 46 | ] 47 | 48 | [[package]] 49 | name = "backtrace" 50 | version = "0.3.0" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | dependencies = [ 53 | "backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 54 | "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 55 | "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 56 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 57 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 58 | "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 59 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 60 | ] 61 | 62 | [[package]] 63 | name = "backtrace-sys" 64 | version = "0.1.10" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | dependencies = [ 67 | "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", 68 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 69 | ] 70 | 71 | [[package]] 72 | name = "base64" 73 | version = "0.5.2" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | dependencies = [ 76 | "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 77 | ] 78 | 79 | [[package]] 80 | name = "bitflags" 81 | version = "0.3.3" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | 84 | [[package]] 85 | name = "bitflags" 86 | version = "0.7.0" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | 89 | [[package]] 90 | name = "block" 91 | version = "0.1.6" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | 94 | [[package]] 95 | name = "byteorder" 96 | version = "1.0.0" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | 99 | [[package]] 100 | name = "cfg-if" 101 | version = "0.1.0" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | 104 | [[package]] 105 | name = "cgl" 106 | version = "0.1.5" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | dependencies = [ 109 | "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 110 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 111 | ] 112 | 113 | [[package]] 114 | name = "cocoa" 115 | version = "0.3.3" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | dependencies = [ 118 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 119 | "core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 120 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 121 | "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 122 | ] 123 | 124 | [[package]] 125 | name = "cocoa" 126 | version = "0.5.2" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | dependencies = [ 129 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 130 | "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 131 | "core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 132 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 133 | "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 134 | ] 135 | 136 | [[package]] 137 | name = "color_quant" 138 | version = "1.0.0" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | 141 | [[package]] 142 | name = "core-foundation" 143 | version = "0.2.3" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | dependencies = [ 146 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 147 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 148 | ] 149 | 150 | [[package]] 151 | name = "core-foundation-sys" 152 | version = "0.2.3" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | dependencies = [ 155 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 156 | ] 157 | 158 | [[package]] 159 | name = "core-graphics" 160 | version = "0.3.2" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | dependencies = [ 163 | "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 164 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 165 | "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", 166 | ] 167 | 168 | [[package]] 169 | name = "core-graphics" 170 | version = "0.4.2" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | dependencies = [ 173 | "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 174 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 175 | "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", 176 | ] 177 | 178 | [[package]] 179 | name = "dbghelp-sys" 180 | version = "0.2.0" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | dependencies = [ 183 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 184 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 185 | ] 186 | 187 | [[package]] 188 | name = "deflate" 189 | version = "0.7.10" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | dependencies = [ 192 | "adler32 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 193 | "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 194 | ] 195 | 196 | [[package]] 197 | name = "deque" 198 | version = "0.3.2" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | 201 | [[package]] 202 | name = "dlib" 203 | version = "0.3.1" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | dependencies = [ 206 | "libloading 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 207 | ] 208 | 209 | [[package]] 210 | name = "dtoa" 211 | version = "0.4.1" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | 214 | [[package]] 215 | name = "dwmapi-sys" 216 | version = "0.1.0" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | dependencies = [ 219 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 220 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 221 | ] 222 | 223 | [[package]] 224 | name = "enum_primitive" 225 | version = "0.1.1" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | dependencies = [ 228 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 229 | ] 230 | 231 | [[package]] 232 | name = "env_logger" 233 | version = "0.4.2" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | dependencies = [ 236 | "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 237 | "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 238 | ] 239 | 240 | [[package]] 241 | name = "error-chain" 242 | version = "0.10.0" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | dependencies = [ 245 | "backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 246 | ] 247 | 248 | [[package]] 249 | name = "fnv" 250 | version = "1.0.5" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | 253 | [[package]] 254 | name = "fs2" 255 | version = "0.2.5" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | dependencies = [ 258 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 259 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 260 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 261 | ] 262 | 263 | [[package]] 264 | name = "gcc" 265 | version = "0.3.45" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | 268 | [[package]] 269 | name = "gdi32-sys" 270 | version = "0.1.1" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | dependencies = [ 273 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 274 | ] 275 | 276 | [[package]] 277 | name = "gif" 278 | version = "0.9.1" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | dependencies = [ 281 | "color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 282 | "lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 283 | ] 284 | 285 | [[package]] 286 | name = "gl_generator" 287 | version = "0.5.2" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | dependencies = [ 290 | "khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 291 | "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 292 | "xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 293 | ] 294 | 295 | [[package]] 296 | name = "gleam" 297 | version = "0.2.32" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | dependencies = [ 300 | "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 301 | "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 302 | ] 303 | 304 | [[package]] 305 | name = "glium" 306 | version = "0.16.0" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | dependencies = [ 309 | "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 310 | "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 311 | "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 312 | "glutin 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", 313 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 314 | "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 315 | ] 316 | 317 | [[package]] 318 | name = "glutin" 319 | version = "0.7.4" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | dependencies = [ 322 | "android_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 323 | "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 324 | "cocoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 325 | "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 326 | "core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 327 | "dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 328 | "gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 329 | "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 330 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 331 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 332 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 333 | "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 334 | "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 335 | "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 336 | "shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 337 | "user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 338 | "wayland-client 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", 339 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 340 | "winit 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", 341 | "x11-dl 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", 342 | ] 343 | 344 | [[package]] 345 | name = "handlebars" 346 | version = "0.26.2" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | dependencies = [ 349 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 350 | "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 351 | "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 352 | "quick-error 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 353 | "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 354 | "serde 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 355 | "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 356 | ] 357 | 358 | [[package]] 359 | name = "httparse" 360 | version = "1.2.2" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | 363 | [[package]] 364 | name = "hyper" 365 | version = "0.10.10" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | dependencies = [ 368 | "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 369 | "httparse 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 370 | "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 371 | "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 372 | "mime 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 373 | "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 374 | "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 375 | "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 376 | "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 377 | "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 378 | "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 379 | "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 380 | ] 381 | 382 | [[package]] 383 | name = "idna" 384 | version = "0.1.1" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | dependencies = [ 387 | "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 388 | "unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 389 | "unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 390 | ] 391 | 392 | [[package]] 393 | name = "image" 394 | version = "0.13.0" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | dependencies = [ 397 | "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 398 | "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 399 | "gif 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 400 | "jpeg-decoder 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 401 | "num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", 402 | "num-rational 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 403 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 404 | "png 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 405 | "scoped_threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 406 | ] 407 | 408 | [[package]] 409 | name = "inflate" 410 | version = "0.2.0" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | 413 | [[package]] 414 | name = "itoa" 415 | version = "0.3.1" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | 418 | [[package]] 419 | name = "jpeg-decoder" 420 | version = "0.1.12" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | dependencies = [ 423 | "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 424 | "rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 425 | ] 426 | 427 | [[package]] 428 | name = "kernel32-sys" 429 | version = "0.2.2" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | dependencies = [ 432 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 433 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 434 | ] 435 | 436 | [[package]] 437 | name = "khronos_api" 438 | version = "1.0.0" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | 441 | [[package]] 442 | name = "language-tags" 443 | version = "0.2.2" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | 446 | [[package]] 447 | name = "lazy_static" 448 | version = "0.2.8" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | 451 | [[package]] 452 | name = "libc" 453 | version = "0.2.22" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | 456 | [[package]] 457 | name = "libloading" 458 | version = "0.3.4" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | dependencies = [ 461 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 462 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 463 | "target_build_utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 464 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 465 | ] 466 | 467 | [[package]] 468 | name = "log" 469 | version = "0.3.7" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | 472 | [[package]] 473 | name = "lzw" 474 | version = "0.10.0" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | 477 | [[package]] 478 | name = "malloc_buf" 479 | version = "0.0.6" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | dependencies = [ 482 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 483 | ] 484 | 485 | [[package]] 486 | name = "matches" 487 | version = "0.1.4" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | 490 | [[package]] 491 | name = "memchr" 492 | version = "1.0.1" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | dependencies = [ 495 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 496 | ] 497 | 498 | [[package]] 499 | name = "memmap" 500 | version = "0.4.0" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | dependencies = [ 503 | "fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 504 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 505 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 506 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 507 | ] 508 | 509 | [[package]] 510 | name = "mime" 511 | version = "0.2.3" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | dependencies = [ 514 | "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 515 | ] 516 | 517 | [[package]] 518 | name = "num-integer" 519 | version = "0.1.34" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | dependencies = [ 522 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 523 | ] 524 | 525 | [[package]] 526 | name = "num-iter" 527 | version = "0.1.33" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | dependencies = [ 530 | "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", 531 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 532 | ] 533 | 534 | [[package]] 535 | name = "num-rational" 536 | version = "0.1.36" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | dependencies = [ 539 | "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", 540 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 541 | ] 542 | 543 | [[package]] 544 | name = "num-traits" 545 | version = "0.1.37" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | 548 | [[package]] 549 | name = "num_cpus" 550 | version = "1.4.0" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | dependencies = [ 553 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 554 | ] 555 | 556 | [[package]] 557 | name = "objc" 558 | version = "0.2.2" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | dependencies = [ 561 | "malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 562 | ] 563 | 564 | [[package]] 565 | name = "osmesa-sys" 566 | version = "0.1.2" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | dependencies = [ 569 | "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 570 | ] 571 | 572 | [[package]] 573 | name = "pest" 574 | version = "0.3.3" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | 577 | [[package]] 578 | name = "phf" 579 | version = "0.7.21" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | dependencies = [ 582 | "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 583 | ] 584 | 585 | [[package]] 586 | name = "phf_codegen" 587 | version = "0.7.21" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | dependencies = [ 590 | "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 591 | "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 592 | ] 593 | 594 | [[package]] 595 | name = "phf_generator" 596 | version = "0.7.21" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | dependencies = [ 599 | "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 600 | "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 601 | ] 602 | 603 | [[package]] 604 | name = "phf_shared" 605 | version = "0.7.21" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | dependencies = [ 608 | "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 609 | ] 610 | 611 | [[package]] 612 | name = "pkg-config" 613 | version = "0.3.9" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | 616 | [[package]] 617 | name = "png" 618 | version = "0.7.0" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | dependencies = [ 621 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 622 | "deflate 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)", 623 | "inflate 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 624 | "num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", 625 | ] 626 | 627 | [[package]] 628 | name = "quick-error" 629 | version = "1.2.0" 630 | source = "registry+https://github.com/rust-lang/crates.io-index" 631 | 632 | [[package]] 633 | name = "quote" 634 | version = "0.3.15" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | 637 | [[package]] 638 | name = "rand" 639 | version = "0.3.15" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | dependencies = [ 642 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 643 | ] 644 | 645 | [[package]] 646 | name = "rayon" 647 | version = "0.7.0" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | dependencies = [ 650 | "rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 651 | ] 652 | 653 | [[package]] 654 | name = "rayon-core" 655 | version = "1.0.0" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | dependencies = [ 658 | "deque 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 659 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 660 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 661 | "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 662 | "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 663 | ] 664 | 665 | [[package]] 666 | name = "redox_syscall" 667 | version = "0.1.17" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | 670 | [[package]] 671 | name = "regex" 672 | version = "0.2.1" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | dependencies = [ 675 | "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 676 | "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 677 | "regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 678 | "thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 679 | "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 680 | ] 681 | 682 | [[package]] 683 | name = "regex-syntax" 684 | version = "0.4.0" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | 687 | [[package]] 688 | name = "rustc-demangle" 689 | version = "0.1.4" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | 692 | [[package]] 693 | name = "rustc_version" 694 | version = "0.1.7" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | dependencies = [ 697 | "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", 698 | ] 699 | 700 | [[package]] 701 | name = "scoped_threadpool" 702 | version = "0.1.7" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | 705 | [[package]] 706 | name = "semver" 707 | version = "0.1.20" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | 710 | [[package]] 711 | name = "serde" 712 | version = "0.7.15" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | 715 | [[package]] 716 | name = "serde" 717 | version = "0.8.23" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | 720 | [[package]] 721 | name = "serde" 722 | version = "0.9.15" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | 725 | [[package]] 726 | name = "serde" 727 | version = "1.0.4" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | 730 | [[package]] 731 | name = "serde_derive" 732 | version = "1.0.4" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | dependencies = [ 735 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 736 | "serde_derive_internals 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", 737 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 738 | ] 739 | 740 | [[package]] 741 | name = "serde_derive_internals" 742 | version = "0.15.0" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | dependencies = [ 745 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 746 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 747 | ] 748 | 749 | [[package]] 750 | name = "serde_json" 751 | version = "0.9.10" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | dependencies = [ 754 | "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 755 | "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 756 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 757 | "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", 758 | ] 759 | 760 | [[package]] 761 | name = "serde_json" 762 | version = "1.0.2" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | dependencies = [ 765 | "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 766 | "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 767 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 768 | "serde 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 769 | ] 770 | 771 | [[package]] 772 | name = "shared_library" 773 | version = "0.1.5" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | dependencies = [ 776 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 777 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 778 | ] 779 | 780 | [[package]] 781 | name = "shell32-sys" 782 | version = "0.1.1" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | dependencies = [ 785 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 786 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 787 | ] 788 | 789 | [[package]] 790 | name = "siphasher" 791 | version = "0.2.2" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | 794 | [[package]] 795 | name = "smallvec" 796 | version = "0.1.8" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | 799 | [[package]] 800 | name = "syn" 801 | version = "0.11.11" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | dependencies = [ 804 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 805 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 806 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 807 | ] 808 | 809 | [[package]] 810 | name = "synom" 811 | version = "0.11.3" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | dependencies = [ 814 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 815 | ] 816 | 817 | [[package]] 818 | name = "target_build_utils" 819 | version = "0.3.1" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | dependencies = [ 822 | "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 823 | "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 824 | "serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", 825 | ] 826 | 827 | [[package]] 828 | name = "tempfile" 829 | version = "2.1.5" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | dependencies = [ 832 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 833 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 834 | "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 835 | "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 836 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 837 | ] 838 | 839 | [[package]] 840 | name = "thread-id" 841 | version = "3.0.0" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | dependencies = [ 844 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 845 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 846 | ] 847 | 848 | [[package]] 849 | name = "thread_local" 850 | version = "0.3.3" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | dependencies = [ 853 | "thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 854 | "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 855 | ] 856 | 857 | [[package]] 858 | name = "time" 859 | version = "0.1.37" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | dependencies = [ 862 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 863 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 864 | "redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 865 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 866 | ] 867 | 868 | [[package]] 869 | name = "traitobject" 870 | version = "0.1.0" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | 873 | [[package]] 874 | name = "tunapanel" 875 | version = "0.1.1" 876 | source = "registry+https://github.com/rust-lang/crates.io-index" 877 | dependencies = [ 878 | "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 879 | "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 880 | "handlebars 0.26.2 (registry+https://github.com/rust-lang/crates.io-index)", 881 | "hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)", 882 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 883 | "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 884 | "serde 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 885 | "serde_derive 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 886 | "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 887 | ] 888 | 889 | [[package]] 890 | name = "typeable" 891 | version = "0.1.2" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | 894 | [[package]] 895 | name = "unicase" 896 | version = "1.4.0" 897 | source = "registry+https://github.com/rust-lang/crates.io-index" 898 | dependencies = [ 899 | "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 900 | ] 901 | 902 | [[package]] 903 | name = "unicode-bidi" 904 | version = "0.2.5" 905 | source = "registry+https://github.com/rust-lang/crates.io-index" 906 | dependencies = [ 907 | "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 908 | ] 909 | 910 | [[package]] 911 | name = "unicode-normalization" 912 | version = "0.1.4" 913 | source = "registry+https://github.com/rust-lang/crates.io-index" 914 | 915 | [[package]] 916 | name = "unicode-xid" 917 | version = "0.0.4" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | 920 | [[package]] 921 | name = "unreachable" 922 | version = "0.1.1" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | dependencies = [ 925 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 926 | ] 927 | 928 | [[package]] 929 | name = "url" 930 | version = "1.4.0" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | dependencies = [ 933 | "idna 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 934 | "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 935 | ] 936 | 937 | [[package]] 938 | name = "user32-sys" 939 | version = "0.1.2" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | dependencies = [ 942 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 943 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 944 | ] 945 | 946 | [[package]] 947 | name = "utf8-ranges" 948 | version = "1.0.0" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | 951 | [[package]] 952 | name = "void" 953 | version = "1.0.2" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | 956 | [[package]] 957 | name = "wayland-client" 958 | version = "0.7.8" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | dependencies = [ 961 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 962 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 963 | "wayland-scanner 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", 964 | "wayland-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", 965 | ] 966 | 967 | [[package]] 968 | name = "wayland-kbd" 969 | version = "0.6.3" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | dependencies = [ 972 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 973 | "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 974 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 975 | "memmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 976 | "wayland-client 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", 977 | ] 978 | 979 | [[package]] 980 | name = "wayland-scanner" 981 | version = "0.7.8" 982 | source = "registry+https://github.com/rust-lang/crates.io-index" 983 | dependencies = [ 984 | "xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 985 | ] 986 | 987 | [[package]] 988 | name = "wayland-sys" 989 | version = "0.7.8" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | dependencies = [ 992 | "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 993 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 994 | ] 995 | 996 | [[package]] 997 | name = "wayland-window" 998 | version = "0.4.4" 999 | source = "registry+https://github.com/rust-lang/crates.io-index" 1000 | dependencies = [ 1001 | "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1002 | "tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1003 | "wayland-client 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "winapi" 1008 | version = "0.2.8" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | 1011 | [[package]] 1012 | name = "winapi-build" 1013 | version = "0.1.1" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | 1016 | [[package]] 1017 | name = "winit" 1018 | version = "0.5.11" 1019 | source = "registry+https://github.com/rust-lang/crates.io-index" 1020 | dependencies = [ 1021 | "android_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1022 | "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1023 | "cocoa 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1024 | "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 1025 | "core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1026 | "dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1027 | "gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1028 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1029 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1030 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 1031 | "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1032 | "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1033 | "shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1034 | "user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1035 | "wayland-client 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", 1036 | "wayland-kbd 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 1037 | "wayland-window 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1038 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1039 | "x11-dl 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "x11-dl" 1044 | version = "2.13.0" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | dependencies = [ 1047 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1048 | "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", 1049 | "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "xml-rs" 1054 | version = "0.3.6" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | dependencies = [ 1057 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1058 | ] 1059 | 1060 | [metadata] 1061 | "checksum adler32 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ff33fe13a08dbce05bcefa2c68eea4844941437e33d6f808240b54d7157b9cd" 1062 | "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" 1063 | "checksum android_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d8289e9637439939cc92b1995b0972117905be88bc28116c86b64d6e589bcd38" 1064 | "checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f" 1065 | "checksum backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f551bc2ddd53aea015d453ef0b635af89444afa5ed2405dd0b2062ad5d600d80" 1066 | "checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842" 1067 | "checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" 1068 | "checksum bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32866f4d103c4e438b1db1158aa1b1a80ee078e5d77a59a2f906fd62a577389c" 1069 | "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" 1070 | "checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 1071 | "checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8" 1072 | "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" 1073 | "checksum cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8bdd78cca65a739cb5475dbf6b6bbb49373e327f4a6f2b499c0f98632df38c10" 1074 | "checksum cocoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3afe4613f57a171039a98db1773f5840b5743cf85aaf03afb65ddfade4f4a9db" 1075 | "checksum cocoa 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1be5fd98bb7e8ef0eea233a4984f4e85ecdcfa002a90b8b12b7a20faf44dc1" 1076 | "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d" 1077 | "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" 1078 | "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" 1079 | "checksum core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0c56c6022ba22aedbaa7d231be545778becbe1c7aceda4c82ba2f2084dd4c723" 1080 | "checksum core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "66e998abb8823fecd2a8a7205429b17a340d447d8c69b3bce86846dcdea3e33b" 1081 | "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" 1082 | "checksum deflate 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8f39474a23b492b7ec97604c7828abd05771b28ed03cac0c6b884e79f9980283" 1083 | "checksum deque 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a694dae478589798d752c7125542f8a5ae8b6e59476172baf2eed67357bdfa27" 1084 | "checksum dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "148bce4ce1c36c4509f29cb54e62c2bd265551a9b00b38070fad551a851866ec" 1085 | "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" 1086 | "checksum dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07c4c7cc7b396419bc0a4d90371d0cee16cb5053b53647d287c0b728000c41fe" 1087 | "checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" 1088 | "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" 1089 | "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" 1090 | "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" 1091 | "checksum fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bcd414e5a1a979b931bb92f41b7a54106d3f6d2e6c253e9ce943b7cd468251ef" 1092 | "checksum gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)" = "40899336fb50db0c78710f53e87afc54d8c7266fb76262fecc78ca1a7f09deae" 1093 | "checksum gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "65256ec4dc2592e6f05bfc1ca3b956a4e0698aa90b1dff1f5687d55a5a3fd59a" 1094 | "checksum gif 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8a80d6fe9e52f637df9afd4779449a7be17c39cc9c35b01589bb833f956ba596" 1095 | "checksum gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1d8edc81c5ae84605a62f5dac661a2313003b26d59839f81d47d46cf0f16a55" 1096 | "checksum gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9590e0e578d528a080c5abac678e7efbe349a73c7316faafd4073edf5f462d01" 1097 | "checksum glium 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c468bf7855f25954a1140f066ebacc1ad5342fd33bf96be28e184c084176f11" 1098 | "checksum glutin 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1f95cc9a8363627259b4a25db878eb5b1a159857bc41f525412302fa9de0f12b" 1099 | "checksum handlebars 0.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fbba80e74e9591a5f6a4ffff6b7f9d645759a896e431cfbdc853e9184370294a" 1100 | "checksum httparse 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77f756bed9ee3a83ce98774f4155b42a31b787029013f3a7d83eca714e500e21" 1101 | "checksum hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)" = "36e108e0b1fa2d17491cbaac4bc460dc0956029d10ccf83c913dd0e5db3e7f07" 1102 | "checksum idna 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac85ec3f80c8e4e99d9325521337e14ec7555c458a14e377d189659a427f375" 1103 | "checksum image 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c3f4f5ea213ed9899eca760a8a14091d4b82d33e27cf8ced336ff730e9f6da8" 1104 | "checksum inflate 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1238524675af3938a7c74980899535854b88ba07907bb1c944abe5b8fc437e5" 1105 | "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" 1106 | "checksum jpeg-decoder 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "919d49b634cde303392353c5dd51153ec005a1a981c6f4b8277692a51e9d260d" 1107 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1108 | "checksum khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09c9d3760673c427d46f91a0350f0a84a52e6bc5a84adf26dc610b6c52436630" 1109 | "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" 1110 | "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" 1111 | "checksum libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "babb8281da88cba992fa1f4ddec7d63ed96280a1a53ec9b919fd37b53d71e502" 1112 | "checksum libloading 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0a020ac941774eb37e9d13d418c37b522e76899bfc4e7b1a600d529a53f83a66" 1113 | "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" 1114 | "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" 1115 | "checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1116 | "checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1" 1117 | "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" 1118 | "checksum memmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "69253224aa10070855ea8fe9dbe94a03fc2b1d7930bb340c9e586a7513716fea" 1119 | "checksum mime 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5514f038123342d01ee5f95129e4ef1e0470c93bc29edf058a46f9ee3ba6737e" 1120 | "checksum num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1a4bf6f9174aa5783a9b4cc892cacd11aebad6c69ad027a0b65c6ca5f8aa37" 1121 | "checksum num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d1891bd7b936f12349b7d1403761c8a0b85a18b148e9da4429d5d102c1a41e" 1122 | "checksum num-rational 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "c2dc5ea04020a8f18318ae485c751f8cfa1c0e69dcf465c29ddaaa64a313cc44" 1123 | "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" 1124 | "checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167" 1125 | "checksum objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "877f30f37acef6749b1841cceab289707f211aecfc756553cd63976190e6cc2e" 1126 | "checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" 1127 | "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8" 1128 | "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" 1129 | "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" 1130 | "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" 1131 | "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" 1132 | "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" 1133 | "checksum png 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48f397b84083c2753ba53c7b56ad023edb94512b2885ffe227c66ff7edb61868" 1134 | "checksum quick-error 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c36987d4978eb1be2e422b1e0423a557923a5c3e7e6f31d5699e9aafaefa469" 1135 | "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 1136 | "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" 1137 | "checksum rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20" 1138 | "checksum rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8" 1139 | "checksum redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "29dbdfd4b9df8ab31dec47c6087b7b13cbf4a776f335e4de8efba8288dda075b" 1140 | "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01" 1141 | "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457" 1142 | "checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95" 1143 | "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" 1144 | "checksum scoped_threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef399c8893e8cb7aa9696e895427fab3a6bf265977bb96e126f24ddd2cda85a" 1145 | "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" 1146 | "checksum serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1b0e0732aa8ec4267f61815a396a942ba3525062e3bd5520aa8419927cfc0a92" 1147 | "checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" 1148 | "checksum serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af" 1149 | "checksum serde 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "991ef6be409a3b7a46cb9ee701d86156ce851825c65dbee7f16dbd5c4e7e2d47" 1150 | "checksum serde_derive 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd81eef9f0b4ec341b11095335b6a4b28ed85581b12dd27585dee1529df35e0" 1151 | "checksum serde_derive_internals 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "021c338d22c7e30f957a6ab7e388cb6098499dda9fd4ba1661ee074ca7a180d1" 1152 | "checksum serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ad8bcf487be7d2e15d3d543f04312de991d631cfe1b43ea0ade69e6a8a5b16a1" 1153 | "checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b" 1154 | "checksum shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04126b6fcfd2710fb5b6d18f4207b6c535f2850a7e1a43bcd526d44f30a79a" 1155 | "checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d" 1156 | "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" 1157 | "checksum smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fcc8d19212aacecf95e4a7a2179b26f7aeb9732a915cf01f05b0d3e044865410" 1158 | "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" 1159 | "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 1160 | "checksum target_build_utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "013d134ae4a25ee744ad6129db589018558f620ddfa44043887cdd45fa08e75c" 1161 | "checksum tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3213fd2b7ed87e39306737ccfac04b1233b57a33ca64cfbf52f2ffaa2b765e2f" 1162 | "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a" 1163 | "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7" 1164 | "checksum time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd7ccbf969a892bf83f1e441126968a07a3941c24ff522a26af9f9f4585d1a3" 1165 | "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" 1166 | "checksum tunapanel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "718aa51e7d7607fed42555189a00d5e53b5670768eb592da9aee496e925fef81" 1167 | "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" 1168 | "checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764" 1169 | "checksum unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a078ebdd62c0e71a709c3d53d2af693fe09fe93fbff8344aebe289b78f9032" 1170 | "checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff" 1171 | "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" 1172 | "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" 1173 | "checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e" 1174 | "checksum user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6717129de5ac253f5642fc78a51d0c7de6f9f53d617fc94e9bae7f6e71cf5504" 1175 | "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" 1176 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 1177 | "checksum wayland-client 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b2b9876c6c97ece4f1ac699b5172550df443f36942fdcdcc27768c8f1437b4" 1178 | "checksum wayland-kbd 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4b69d43d6cce82d95a2c5e81605abd1fa4783bf49d09cd85aa092f16081ef1" 1179 | "checksum wayland-scanner 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "21fd38866b7539ec70300596a905ca838e9f8212aa114fa1cebc13801fbeecff" 1180 | "checksum wayland-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "604257d049da3dc9c49a0bac58f0f09265d838959721da2c41f19db5ca8cc59f" 1181 | "checksum wayland-window 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7595fbe537dee3a380f32104ddfcf2f43db8cb8843031531e1426eb524d1c608" 1182 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1183 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 1184 | "checksum winit 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f68c756743f68e5420a93f72c43c9cd8d3b89163692e09a5b53c12caf82386ba" 1185 | "checksum x11-dl 2.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f8f229cb66ab27440d0b8c8e37f8c62e60e169145e084b49795a1a22b62f1e" 1186 | "checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562" 1187 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "azurescens" 3 | description = "Renders interactive fractal-like animations" 4 | repository = "https://github.com/kmcallister/azurescens" 5 | readme = "README.md" 6 | keywords = ["OpenGL", "fractal", "art", "trippy"] 7 | categories = ["multimedia::video", "visualization"] 8 | license = "MIT/Apache-2.0" 9 | version = "0.1.0" 10 | authors = ["Keegan McAllister "] 11 | 12 | [dependencies] 13 | glium = "0.16" 14 | time = "0.1" 15 | image = "0.13" 16 | serde = "1" 17 | serde_derive = "1" 18 | tunapanel = "0.1.1" 19 | log = "0.3" 20 | env_logger = "0.4" 21 | 22 | [dev-dependencies] 23 | tempfile = "2" 24 | 25 | [features] 26 | default = [] 27 | dynamic-shaders = [] 28 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 The Azurescens Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # azurescens 2 | 3 | [![Travis CI badge](https://api.travis-ci.org/kmcallister/azurescens.svg?branch=master)](https://travis-ci.org/kmcallister/azurescens) 4 | 5 | azurescens renders interactive fractal-like animations. 6 | 7 | **Not recommended for people with photosensitive epilepsy!** 8 | 9 | Currently it is a simple toy, and a platform for experimentation. It will 10 | probably grow more behaviors over time. 11 | 12 | ![Screenshot 1](assets/screenshots/shot1.png) 13 | 14 | ![Screenshot 2](assets/screenshots/shot2.png) 15 | 16 | 17 | ## Quick start 18 | 19 | Install Rust from [rustup.rs](https://rustup.rs/). The latest stable release is 20 | fine. Make sure rustup has put the Rust tools in your `$PATH` — you may need 21 | to restart your terminal. 22 | 23 | Clone this repository and `cd` into it. azurescens is not yet available on 24 | [crates.io](https://crates.io/); sorry! 25 | 26 | Build it in release mode, so that optimizations are enabled: 27 | 28 | cargo build --release 29 | 30 | This will take a little while, as Cargo downloads and builds a bunch of 31 | dependencies. To be honest, the Rust compiler is pretty dang slow. Sorry about 32 | that! 33 | 34 | Then you can run azurescens with 35 | 36 | cargo run --release 37 | 38 | Actually, the `run` command by itself will rebuild as necessary. But on a first 39 | build, you may be surprised when the window opens some minutes later! 40 | 41 | azurescens has been tested on Linux, macOS Sierra (10.12), and Windows 10. You 42 | will need OpenGL 3.2 or later. 43 | 44 | There is also [preliminary support for Android][android]. 45 | 46 | 47 | ## User interface 48 | 49 | There is not much UI yet. 50 | 51 | Try **moving the mouse** within the window to get different behaviors. 52 | 53 | Press `s` to take a screenshot, as a PNG file in the current directory. 54 | 55 | 56 | ## Performance 57 | 58 | azurescens runs smooth as silk on my 2011-era non-gaming laptop, with Intel HD 59 | Graphics 3000 onboard video. If you experience performance issues, **make sure 60 | you are building in release mode**. If that doesn't help, you can lower the 61 | feedback resolution by adjusting `FEEDBACK_TEXTURE_SIZE` in `src/main.rs`. 62 | 63 | Alternately, if you crave ultra-hi-def, you can increase this constant. 4096 64 | should work on any reasonable gaming GPU. 65 | 66 | If you've done these things and still run into performance issues, please let 67 | us know by [opening an issue on GitHub][issue]. 68 | 69 | 70 | ## More documentation 71 | 72 | [**The algorithm**](docs/algorithm.md) 73 | 74 | [**How to hack on it**](docs/hacking.md) 75 | 76 | [**Building for Android**][android] 77 | 78 | 79 | ## Shoutouts 80 | 81 | Uncountable thanks to my good friend Michael Rule, who introduced me to this 82 | whole approach. His implementation in Java may be the most comprehensive and 83 | well-crafted version that exists. 84 | 85 | tomaka's [glium library](https://crates.io/crates/glium) makes OpenGL 86 | programming almost pleasant. It's in maintenance mode, but so is OpenGL these 87 | days. One day I'll port azurescens to Vulkan. 88 | 89 | `#rust-gamedev` on [Mozilla IRC](https://wiki.mozilla.org/IRC) helped me with 90 | several thorny issues. 91 | 92 | And of course, I am grateful to the [thousands of 93 | people](https://thanks.rust-lang.org/rust/all-time) who have made Rust what it 94 | is today. 95 | 96 | [issue]: https://github.com/kmcallister/azurescens/issues 97 | [android]: docs/android.md 98 | -------------------------------------------------------------------------------- /android/build-and-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | 3 | docker run --rm -v $(pwd):/root/src -w /root/src tomaka/android-rs-glue cargo apk 4 | 5 | adb uninstall rust.azurescens 6 | 7 | adb install -r target/android-artifacts/build/bin/azurescens-debug.apk 8 | 9 | adb logcat | grep Rust 10 | -------------------------------------------------------------------------------- /assets/screenshots/shot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmcallister/azurescens/1385d3d0ab4f8735c2cff2d60aa218b4bc05df5b/assets/screenshots/shot1.png -------------------------------------------------------------------------------- /assets/screenshots/shot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmcallister/azurescens/1385d3d0ab4f8735c2cff2d60aa218b4bc05df5b/assets/screenshots/shot2.png -------------------------------------------------------------------------------- /docs/algorithm.md: -------------------------------------------------------------------------------- 1 | ## The algorithm 2 | 3 | Here's how it works, in a nutshell. 4 | 5 | We interpret the screen as a region of the [complex plane] ℂ, for example 6 | 7 | > (-1 to 1) + (-1 to 1)*i* 8 | 9 | We pick a function *f*: ℂ → ℂ. Say we want to render a new frame of the 10 | animation. For each pixel, we interpret its coordinate as a complex number *z*. 11 | We then copy the color from the previous frame at the point *f*(*z*). We also 12 | draw some stuff on top in order to seed the iteration with interesting 13 | structure. 14 | 15 | A simple choice for *f* is 16 | 17 | > *f*(*z*) = *z*2 + *c* 18 | 19 | for some complex parameter *c*. This produces images very similar to [Julia set 20 | fractals]. (The Julia set is the set of points for which repeated iteration of 21 | *f* does not fly off to infinity.) 22 | 23 | However, the animation also displays interesting non-equilibrium behavior, if 24 | we vary the parameter *c* in-between frames. In azurescens this is accomplished 25 | by moving the mouse. Skilled pilots can achieve some very interesting effects. 26 | 27 | [complex plane]: https://en.wikipedia.org/wiki/Complex_plane 28 | [Julia set fractals]: https://en.wikipedia.org/wiki/Julia_set 29 | -------------------------------------------------------------------------------- /docs/android.md: -------------------------------------------------------------------------------- 1 | ## Building for Android 2 | 3 | There is very preliminary support for building azurescens as an Android app. 4 | You will need Android 5.0 or later, which corresponds to OpenGL ES 3.1 or 5 | later. 6 | 7 | You can [download a pre-built `.apk` file][apk]. It may not be up-to-date. You 8 | also have to enable apps from unknown sources in your "Security" settings. 9 | 10 | If you want to build it yourself, run 11 | 12 | ./android/build-and-install 13 | 14 | Make sure `docker` and `adb` are in your `$PATH`. You will likely need to be 15 | root. 16 | 17 | Once the build and install is complete, you will see a live dump of the Android 18 | system log. At this point you can launch the app on your device in the normal 19 | way. 20 | 21 | If all is well you will see some delicious fractals. Touch the screen anywhere 22 | to change the control parameter (equivalent of moving the mouse on the desktop 23 | version). FPS and any errors will be written to the Android system log. 24 | 25 | [apk]: https://kmcallister.github.io/azurescens/downloads/android/azurescens-debug-638bc9c.apk 26 | [cargo-apk]: https://github.com/tomaka/android-rs-glue/tree/master/cargo-apk 27 | -------------------------------------------------------------------------------- /docs/hacking.md: -------------------------------------------------------------------------------- 1 | ## Implementation details 2 | 3 | The feedback happens between two OpenGL textures in a ping-pong fashion. These 4 | have a fixed square size, regardless of the size of the window or screen. It's 5 | determined by the constant `FEEDBACK_TEXTURE_SIZE` in `src/main.rs`. 6 | 7 | Each step of the feedback inverts colors, which produces a lot of the 8 | interesting structure. This is why we only render every other step to the 9 | screen; otherwise it would be far too blinky. 10 | 11 | 12 | ## Experimentation and improvement 13 | 14 | By default, the shader programs are baked into the azurescens executable at 15 | compile time. This means the executable is self-contained and does not rely on 16 | any external files. If you are playing around with the shaders you should switch 17 | this behavior with a command like 18 | 19 | cargo run --release --features dynamic-shaders 20 | 21 | This will read the shaders at runtime, greatly reducing the delay in trying out 22 | new things. 23 | 24 | The actual feedback function is implemented in `src/shaders/feedback.glsl`, 25 | which is probably the most interesting file in the whole project. This is a 26 | great place to start experimenting. There are a million different directions 27 | you can go with this basic idea. Pull requests will be accepted, especially if 28 | they add functionality without removing any. (We will need a mode-switching 29 | interface at some point.) 30 | 31 | Many ideas for improvement are available in the [issue tracker][issue]. See 32 | also some old articles: 33 | [1](http://wealoneonearth.blogspot.com/2007/09/more-fractal-video-feedback.html), 34 | [2](http://wealoneonearth.blogspot.com/2007/09/more-screenshots.html), 35 | [3](http://wealoneonearth.blogspot.com/2008/01/ezeiz-c_24.html), 36 | [4](http://wealoneonearth.blogspot.com/2008/01/ezeiz-c.html), and many others 37 | from that group blog. 38 | 39 | Long ago, I made [a similar program][phosphene] in x86-16 assembly which fits 40 | in a master boot record — 446 bytes. 41 | 42 | [phosphene]: https://github.com/kmcallister/phosphene 43 | [issue]: https://github.com/kmcallister/azurescens/issues 44 | -------------------------------------------------------------------------------- /src/fps.rs: -------------------------------------------------------------------------------- 1 | use time::precise_time_ns; 2 | 3 | // FPS is smoothed with an exponentially-weighted moving average. 4 | // This is the proportion of the old FPS to keep on each step. 5 | const SMOOTHING: f32 6 | = 0.9; 7 | 8 | // How often to output FPS, in milliseconds. 9 | const OUTPUT_INTERVAL: u64 10 | = 5_000; 11 | 12 | pub struct FPSTracker { 13 | last_frame_time: u64, 14 | last_fps_output_time: u64, 15 | smoothed_fps: f32, 16 | } 17 | 18 | impl FPSTracker { 19 | pub fn new() -> FPSTracker { 20 | let t = precise_time_ns(); 21 | FPSTracker { 22 | last_frame_time: t, 23 | last_fps_output_time: t, 24 | smoothed_fps: 0.0, 25 | } 26 | } 27 | 28 | pub fn tick(&mut self) { 29 | let this_frame_time = precise_time_ns(); 30 | let instant_fps = 1e9 / ((this_frame_time - self.last_frame_time) as f32); 31 | self.smoothed_fps = SMOOTHING * self.smoothed_fps 32 | + (1.0-SMOOTHING) * instant_fps; 33 | self.last_frame_time = this_frame_time; 34 | 35 | if (this_frame_time - self.last_fps_output_time) 36 | >= 1_000_000 * OUTPUT_INTERVAL 37 | { 38 | println!("Frames per second: {:7.2}", self.smoothed_fps); 39 | self.last_fps_output_time = this_frame_time; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![deny(warnings)] 2 | 3 | extern crate time; 4 | extern crate image; 5 | extern crate env_logger; 6 | 7 | #[macro_use] 8 | extern crate log; 9 | 10 | #[macro_use] 11 | extern crate glium; 12 | 13 | #[macro_use] 14 | extern crate serde_derive; 15 | 16 | #[macro_use] 17 | extern crate tunapanel; 18 | 19 | use std::mem; 20 | use std::thread; 21 | use std::sync::{Arc, Mutex}; 22 | use std::default::Default; 23 | 24 | use glium::{DisplayBuild, Program, Surface, VertexBuffer, IndexBuffer}; 25 | use glium::texture::Texture2d; 26 | use glium::index::PrimitiveType; 27 | use glium::glutin::{Event, ElementState, VirtualKeyCode, WindowBuilder}; 28 | use glium::glutin::{Touch, TouchPhase}; 29 | use glium::backend::Facade; 30 | use glium::backend::glutin_backend::GlutinFacade; 31 | use glium::uniforms::{Sampler, MagnifySamplerFilter}; 32 | 33 | use params::Params; 34 | use fps::FPSTracker; 35 | use screenshot::screenshot; 36 | 37 | mod params; 38 | mod fps; 39 | mod screenshot; 40 | 41 | // Our vertices are boring. We only ever draw 2 triangles 42 | // covering the whole surface. 43 | #[derive(Copy, Clone)] 44 | struct Vertex { 45 | pos: [f32; 2], 46 | } 47 | 48 | implement_vertex!(Vertex, pos); 49 | 50 | fn whole_surface_triangles(facade: &F) 51 | -> (VertexBuffer, IndexBuffer) 52 | where F: Facade, 53 | { 54 | let vertices = [ 55 | Vertex { pos: [-1.0, -1.0] }, 56 | Vertex { pos: [-1.0, 1.0] }, 57 | Vertex { pos: [ 1.0, 1.0] }, 58 | Vertex { pos: [ 1.0, -1.0] }, 59 | ]; 60 | 61 | let indices = [ 62 | 0, 1, 2, 63 | 2, 3, 0, 64 | ]; 65 | 66 | let vertex_buffer = VertexBuffer::new(facade, &vertices).unwrap(); 67 | let index_buffer = IndexBuffer::new(facade, 68 | PrimitiveType::TrianglesList, 69 | &indices).unwrap(); 70 | 71 | (vertex_buffer, index_buffer) 72 | } 73 | 74 | 75 | // Size in pixels for the feedback textures. 76 | #[cfg(target_os = "android")] 77 | const FEEDBACK_TEXTURE_SIZE: u32 = 1024; 78 | 79 | #[cfg(not(target_os = "android"))] 80 | const FEEDBACK_TEXTURE_SIZE: u32 = 2048; 81 | 82 | // Create a feedback texture. 83 | fn feedback_texture(facade: &F) -> Texture2d 84 | where F: Facade, 85 | { 86 | // Returns a texture with undefined contents. 87 | Texture2d::empty(facade, 88 | FEEDBACK_TEXTURE_SIZE, 89 | FEEDBACK_TEXTURE_SIZE).unwrap() 90 | } 91 | 92 | // Shaders. 93 | #[macro_use] 94 | mod shader_loader; 95 | 96 | // Trivial vertex shader. 97 | shader_loader!(vertex_shader_src, "shaders/vertex.glsl"); 98 | 99 | // Simple fragment shader, used to copy a texture to the screen. 100 | shader_loader!(blit_shader_src, "shaders/blit.glsl"); 101 | 102 | // Fragment shader which runs video feedback between two textures. 103 | shader_loader!(feedback_shader_src, "shaders/feedback.glsl"); 104 | 105 | 106 | // The screen and the feedback textures are interpreted as 107 | // subsets of the complex plane: 108 | // 109 | // (-SCALE to SCALE) + i*(-SCALE to SCALE) 110 | // 111 | const SCALE: f32 = 1.4; 112 | 113 | // Convert a window position in pixels to a complex number. 114 | // 115 | // TODO: Is it slow to look up the size on every mouse move? 116 | fn window_px_to_z(facade: &GlutinFacade, (x, y): (f32, f32)) 117 | -> (f32, f32) 118 | { 119 | let window = facade.get_window().unwrap(); 120 | let (sx, sy) = window.get_inner_size().unwrap(); 121 | 122 | ((x / ((sx-1) as f32) * 2.0 - 1.0) * SCALE, 123 | (y / ((sy-1) as f32) * 2.0 - 1.0) * SCALE) 124 | } 125 | 126 | 127 | #[cfg(target_os = "android")] 128 | fn request_gl_version(bld: WindowBuilder) -> WindowBuilder { 129 | use glium::glutin::{GlRequest, Api}; 130 | bld.with_gl(GlRequest::Specific(Api::OpenGlEs, (3, 1))) 131 | } 132 | 133 | #[cfg(not(target_os = "android"))] 134 | fn request_gl_version(bld: WindowBuilder) -> WindowBuilder { 135 | bld 136 | } 137 | 138 | fn main() { 139 | env_logger::init().unwrap(); 140 | 141 | // Create params struct. 142 | let param_shared = Arc::new(Mutex::new(Params::default())); 143 | let param_for_thread = param_shared.clone(); 144 | 145 | // Start up control panel. 146 | thread::spawn(|| { 147 | tunapanel::serve(move |p: Params| { 148 | *param_for_thread.lock().unwrap() = p; 149 | }).unwrap(); 150 | }); 151 | 152 | // Create a glutin / glium window. 153 | let display_builder = WindowBuilder::new() 154 | .with_title("a z u r e s c e n s".to_owned()) 155 | .with_vsync(); 156 | 157 | let display = request_gl_version(display_builder).build_glium().unwrap(); 158 | 159 | println!("OpenGL {:?}", display.get_opengl_version()); 160 | println!("GLSL {:?}", display.get_supported_glsl_version()); 161 | 162 | // Create two textures for feedback. 163 | let mut read_texture = feedback_texture(&display); 164 | let mut write_texture = feedback_texture(&display); 165 | 166 | // Prepare to draw triangles which cover a whole surface. 167 | let (vertex_buffer, index_buffer) = whole_surface_triangles(&display); 168 | let draw_params = Default::default(); 169 | 170 | // Prepare shader programs. 171 | let vertex_shader_src = vertex_shader_src(); 172 | 173 | let blit_program = Program::from_source(&display, 174 | &vertex_shader_src, &blit_shader_src(), None).unwrap(); 175 | 176 | let feedback_program = Program::from_source(&display, 177 | &vertex_shader_src, &feedback_shader_src(), None).unwrap(); 178 | 179 | // Clear the screen. 180 | let mut target = display.draw(); 181 | target.clear_color(0.0, 0.0, 0.0, 1.0); 182 | target.finish().unwrap(); 183 | 184 | // Initial value for the complex parameter 'c'. 185 | let mut param_c = (0.3, 0.3); 186 | 187 | // FPS tracking. 188 | let mut fps = FPSTracker::new(); 189 | 190 | loop { 191 | // Run video feedback from one texture into the other. 192 | // We do this twice before drawing to the screen. 193 | // The reason is that each frame inverts colors and 194 | // we want to avoid a distracting blinky effect. 195 | for _ in 0..2 { 196 | { 197 | let uniforms = { 198 | let params = param_shared.lock().unwrap(); 199 | 200 | uniform! { 201 | src_near: Sampler::new(&read_texture) 202 | .magnify_filter(MagnifySamplerFilter::Nearest), 203 | src_lin: Sampler::new(&read_texture) 204 | .magnify_filter(MagnifySamplerFilter::Linear), 205 | scale: SCALE, 206 | param_c: param_c, 207 | param_t: time::precise_time_s() as f32, 208 | invert: params.invert, 209 | permute_colors: params.permute_colors, 210 | fade: params.fade, 211 | color_cycle_rate: params.color_cycle_rate, 212 | mix_linear: params.mix_linear, 213 | mix_linear_tv: params.mix_linear_tv, 214 | } 215 | }; 216 | 217 | let mut target = write_texture.as_surface(); 218 | target.draw(&vertex_buffer, &index_buffer, &feedback_program, 219 | &uniforms, &draw_params).unwrap(); 220 | } 221 | 222 | mem::swap(&mut read_texture, &mut write_texture); 223 | } 224 | 225 | // Draw the most recently written texture to the screen. 226 | let uniforms = uniform! { 227 | src: &read_texture, 228 | }; 229 | 230 | let mut target = display.draw(); 231 | target.draw(&vertex_buffer, &index_buffer, &blit_program, 232 | &uniforms, &draw_params).unwrap(); 233 | target.finish().unwrap(); 234 | 235 | // Update FPS. 236 | fps.tick(); 237 | 238 | // Handle events. 239 | for ev in display.poll_events() { 240 | match ev { 241 | Event::Closed => return, 242 | 243 | Event::MouseMoved(x, y) => { 244 | // Update the parameter 'c' according to 245 | // the mouse position. 246 | param_c = window_px_to_z(&display, (x as f32, y as f32)); 247 | } 248 | 249 | Event::Touch(t) => match t { 250 | Touch { phase: TouchPhase::Started, location: (x, y), .. } 251 | | Touch { phase: TouchPhase::Moved, location: (x, y), .. } => { 252 | param_c = window_px_to_z(&display, (x as f32, y as f32)); 253 | } 254 | 255 | _ => (), 256 | }, 257 | 258 | Event::KeyboardInput(ElementState::Pressed, 259 | _, Some(kc)) => match kc { 260 | VirtualKeyCode::S => screenshot(&read_texture), 261 | _ => (), 262 | }, 263 | 264 | _ => (), 265 | } 266 | } 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /src/params.rs: -------------------------------------------------------------------------------- 1 | tunapanel! { 2 | #[title = "Azurescens"] 3 | pub struct Params { 4 | #[label = "Invert each frame"] 5 | invert: bool = true, 6 | 7 | #[label = "Fade (non-inverting mode)"] 8 | fade: f32 = 0.9, 9 | 10 | #[label = "Permute color channels"] 11 | permute_colors: bool = true, 12 | 13 | #[label = "Color cycle rate"] 14 | color_cycle_rate: f32 = 1.0, 15 | 16 | #[label = "Mix for linear interpolation"] 17 | mix_linear: f32 = 0.0, 18 | 19 | #[label = "Time varying mix for linear"] 20 | mix_linear_tv: f32 = 0.2, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/screenshot.rs: -------------------------------------------------------------------------------- 1 | use glium::texture::{Texture2d, RawImage2d, ClientFormat}; 2 | use time; 3 | use image; 4 | 5 | use FEEDBACK_TEXTURE_SIZE; 6 | 7 | // Take a screenshot. 8 | pub fn screenshot(tex: &Texture2d) { 9 | let raw_image: RawImage2d = tex.read(); 10 | assert_eq!(raw_image.format, ClientFormat::U8U8U8U8); 11 | 12 | let image: image::ImageBuffer, &[u8]> 13 | = image::ImageBuffer::from_raw( 14 | FEEDBACK_TEXTURE_SIZE, FEEDBACK_TEXTURE_SIZE, 15 | &*raw_image.data).unwrap(); 16 | 17 | let path_string = format!("az_shot_{}.png", time::precise_time_ns()); 18 | match image.save(&path_string) { 19 | Ok(()) => println!("Saved screenshot {}", path_string), 20 | Err(e) => error!("FAILED to save image {}: {}", path_string, e), 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/shader_loader.rs: -------------------------------------------------------------------------------- 1 | // Load shaders, as GLSL source code. 2 | 3 | #[cfg(target_os = "android")] 4 | pub static GLSL_VERSION: &'static str = "#version 300 es\n\n"; 5 | 6 | #[cfg(not(target_os = "android"))] 7 | pub static GLSL_VERSION: &'static str = "#version 150\n\n"; 8 | 9 | #[cfg(feature = "dynamic-shaders")] 10 | pub fn load_dynamic_shader(which: &str) -> String { 11 | use std::io; 12 | use std::path::PathBuf; 13 | 14 | let mut path = PathBuf::from("src/"); 15 | path.push(which); 16 | 17 | let inner = || -> Result { 18 | use std::io::prelude::*; 19 | use std::fs::File; 20 | 21 | let mut file = File::open(&path)?; 22 | let mut buffer = String::from(GLSL_VERSION); 23 | file.read_to_string(&mut buffer)?; 24 | 25 | Ok(buffer) 26 | }; 27 | 28 | match inner() { 29 | Ok(s) => s, 30 | Err(e) => { 31 | error!("Could not load shader {}", path.to_string_lossy()); 32 | panic!("{}", e) 33 | } 34 | } 35 | } 36 | 37 | macro_rules! shader_loader { 38 | ($name:ident, $path:expr) => { 39 | #[cfg(not(feature = "dynamic-shaders"))] 40 | fn $name() -> String { 41 | format!("{}{}", shader_loader::GLSL_VERSION, include_str!($path)) 42 | } 43 | 44 | #[cfg(feature = "dynamic-shaders")] 45 | fn $name() -> String { 46 | shader_loader::load_dynamic_shader($path) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/shaders/blit.glsl: -------------------------------------------------------------------------------- 1 | // Simple fragment shader, used to copy a texture to the screen. 2 | 3 | precision mediump float; 4 | 5 | uniform sampler2D src; 6 | 7 | in vec2 frag_pos; 8 | 9 | out vec4 color; 10 | 11 | void main() { 12 | vec2 prev_coord = vec2((frag_pos.x + 1.0)/2.0, (frag_pos.y + 1.0)/2.0); 13 | 14 | color = vec4(texture(src, prev_coord).rgb, 1.0); 15 | } 16 | 17 | // vim: ft=glsl 18 | -------------------------------------------------------------------------------- /src/shaders/feedback.glsl: -------------------------------------------------------------------------------- 1 | // Fragment shader which runs video feedback between two textures. 2 | 3 | precision mediump float; 4 | 5 | // Source texture (previous frame) 6 | uniform sampler2D src_near; // Nearest-pixel sampling 7 | uniform sampler2D src_lin; // Linear interpolation 8 | 9 | uniform float scale; 10 | uniform vec2 param_c; 11 | uniform float param_t; 12 | uniform bool invert; 13 | uniform bool permute_colors; 14 | uniform float fade; 15 | uniform float color_cycle_rate; 16 | uniform float mix_linear; 17 | uniform float mix_linear_tv; 18 | 19 | in vec2 frag_pos; 20 | 21 | out vec4 color; 22 | 23 | // Convert HSV colorspace to RGB. 24 | vec3 hsv2rgb(vec3 c) { 25 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 26 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 27 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 28 | } 29 | 30 | // Convert a position (-1, 1) x (-1, 1) to a complex number. 31 | vec2 pos_to_z(vec2 pos) { 32 | return scale * pos; 33 | } 34 | 35 | // Convert a complex number to a texture coordinate. 36 | vec2 z_to_tex(vec2 z) { 37 | return vec2( ((z.x / scale) + 1.0) / 2.0, 38 | ((z.y / scale) + 1.0) / 2.0); 39 | } 40 | 41 | // Multiply two complex numbers. 42 | vec2 cmult(vec2 a, vec2 b) { 43 | return vec2((a.x * b.x) - (a.y * b.y), 44 | (a.x * b.y) + (a.y * b.x)); 45 | } 46 | 47 | // Complex modulus. 48 | float cmod(vec2 z) { 49 | return length(z); 50 | } 51 | 52 | // Complex argument (principal). 53 | float carg(vec2 z) { 54 | return atan(z.y, z.x); 55 | } 56 | 57 | // Complex logarithm. 58 | vec2 clog(vec2 z) { 59 | return vec2(log(cmod(z)), carg(z)); 60 | } 61 | 62 | void main() { 63 | vec2 z = pos_to_z(frag_pos); 64 | 65 | // The central feedback equation. 66 | // z is the current fragment coordinate 67 | // zprev is where we get its color from in the previous frame. 68 | vec2 zprev = cmult(z, z) + 1.2*sin(param_c); 69 | float a = z_to_tex(param_c).y; 70 | zprev.y = mix(sin(zprev.y), zprev.y, a); 71 | 72 | vec2 zt = z_to_tex(zprev); 73 | color = mix(texture(src_near, zt), texture(src_lin, zt), 74 | mix_linear + mix_linear_tv*fract(0.1*param_t)); 75 | 76 | // Color the borders, as an initial condition for the iteration. 77 | float lim = 0.9*scale; 78 | if ((zprev.x <= -lim) 79 | || (zprev.x >= lim) 80 | || (zprev.y <= -lim) 81 | || (zprev.y >= lim)) { 82 | 83 | float h = 2.0*cos(0.128*color_cycle_rate*param_t + 0.1*zprev.x) + 1.0; 84 | float s = 0.6 + 0.2*(sin(0.240*color_cycle_rate*param_t + zprev.y) + 1.0); 85 | 86 | color += vec4(hsv2rgb(vec3(h, s, 1.0)), 1.0); 87 | } 88 | 89 | // Final color mapping / inversion. 90 | if (invert) { 91 | color = vec4(vec3(1.0, 1.0, 1.0) - color.rgb, 1.0); 92 | } else { 93 | color = vec4(fade*color.rgb, 1.0); 94 | } 95 | 96 | if (permute_colors) { 97 | color = vec4(color.gbr, 1.0); 98 | } 99 | } 100 | 101 | // vim: ft=glsl 102 | -------------------------------------------------------------------------------- /src/shaders/vertex.glsl: -------------------------------------------------------------------------------- 1 | // Trivial vertex shader. 2 | 3 | precision mediump float; 4 | 5 | in vec2 pos; 6 | out vec2 frag_pos; 7 | 8 | void main() { 9 | frag_pos = pos; 10 | gl_Position = vec4(pos, 0.0, 1.0); 11 | } 12 | 13 | // vim: ft=glsl 14 | -------------------------------------------------------------------------------- /tests/validate-shaders.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate log; 3 | 4 | extern crate env_logger; 5 | extern crate tempfile; 6 | 7 | use std::process::{Command, Stdio, ExitStatus}; 8 | use std::io; 9 | use std::io::{Read, Write}; 10 | use std::path::PathBuf; 11 | use std::fs::File; 12 | use std::env; 13 | use tempfile::NamedTempFile; 14 | 15 | #[derive(Debug)] 16 | enum Error { 17 | IoError(io::Error), 18 | CommandFailed(ExitStatus, String), 19 | } 20 | 21 | impl From for Error { 22 | fn from(e: io::Error) -> Error { 23 | Error::IoError(e) 24 | } 25 | } 26 | 27 | fn glslang_validator(args: &[&str]) -> Result { 28 | let child = Command::new("glslangValidator") 29 | .stdout(Stdio::piped()) 30 | .stderr(Stdio::piped()) 31 | .args(args) 32 | .spawn()?; 33 | 34 | let res = child.wait_with_output()?; 35 | let mut output = String::new(); 36 | output.push_str(&String::from_utf8_lossy(&res.stdout)); 37 | output.push_str(&String::from_utf8_lossy(&res.stderr)); 38 | 39 | if res.status.success() { 40 | Ok(output) 41 | } else { 42 | Err(Error::CommandFailed(res.status, output)) 43 | } 44 | } 45 | 46 | #[test] 47 | fn validate_shaders() { 48 | env_logger::init().unwrap(); 49 | 50 | // Check for existence of glslangValidator. 51 | match glslang_validator(&["-v"]) { 52 | Err(_) => { 53 | error!("Could not run glslangValidator. Skipping shader validation."); 54 | return; 55 | } 56 | 57 | Ok(out) => { 58 | print!("{}", out); 59 | } 60 | } 61 | 62 | let shaders_dir = { 63 | let mut s = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); 64 | s.push("src"); 65 | s.push("shaders"); 66 | s 67 | }; 68 | 69 | // Validate each shader in each mode. 70 | for &(ty, filename) in &[ 71 | ("vert", "vertex.glsl"), 72 | ("frag", "blit.glsl"), 73 | ("frag", "feedback.glsl"), 74 | ] { 75 | let mut path = shaders_dir.clone(); 76 | path.push(filename); 77 | 78 | let shader_in = { 79 | let mut buf = String::new(); 80 | let mut file = File::open(&path).unwrap(); 81 | file.read_to_string(&mut buf).unwrap(); 82 | buf 83 | }; 84 | 85 | for vers in &["#version 150", "#version 300 es"] { 86 | info!("Validating {} shader {} with {}", 87 | ty, filename, vers); 88 | 89 | let mut temp = NamedTempFile::new().unwrap(); 90 | write!(&mut temp, "{}\n\n{}", vers, shader_in).unwrap(); 91 | 92 | if let Err(e) = glslang_validator(&[ 93 | "-S", 94 | ty, 95 | temp.path().to_str().expect("non-UTF-8 file path") 96 | ]) { 97 | error!("Failed to validate {} shader {} with {}", 98 | ty, filename, vers); 99 | 100 | match e { 101 | Error::IoError(e) => error!("IO error: {:?}", e), 102 | Error::CommandFailed(s, out) => { 103 | error!("glslValidator exited with code {}. Output:\n{}", 104 | s, out); 105 | } 106 | } 107 | 108 | panic!("Shader validation failed."); 109 | } 110 | } 111 | } 112 | } 113 | --------------------------------------------------------------------------------