From b30ee294a6e3d56bf727ae8a7eb08f9e116b62fc Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Sun, 26 Apr 2020 00:28:13 -0700 Subject: [PATCH] Window with textured polygon --- .gitignore | 1 + .vscode/launch.json | 27 + Cargo.lock | 2036 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 16 + shaders/shader.frag | 11 + shaders/shader.vert | 10 + src/application.rs | 240 +++++ src/color_palette.rs | 69 ++ src/gui_rect.rs | 23 + src/main.rs | 30 + src/pipeline.rs | 125 +++ src/program_state.rs | 13 + src/render_state.rs | 26 + src/shader_cache.rs | 49 + src/texture.rs | 78 ++ src/texture_cache.rs | 50 ++ textures/grid.png | Bin 0 -> 17332 bytes 17 files changed, 2804 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 shaders/shader.frag create mode 100644 shaders/shader.vert create mode 100644 src/application.rs create mode 100644 src/color_palette.rs create mode 100644 src/gui_rect.rs create mode 100644 src/main.rs create mode 100644 src/pipeline.rs create mode 100644 src/program_state.rs create mode 100644 src/render_state.rs create mode 100644 src/shader_cache.rs create mode 100644 src/texture.rs create mode 100644 src/texture_cache.rs create mode 100644 textures/grid.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ea8c4bf7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..ad4c87ee --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(Windows) Launch", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/target/debug/graphite.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false + }, + { + "name": "(LLDB) Launch", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/target/debug/graphite.exe", + "args": [], + "cwd": "${workspaceFolder}", + } + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..d884c927 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2036 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adler32" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" + +[[package]] +name = "andrew" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" +dependencies = [ + "bitflags", + "line_drawing", + "rusttype 0.7.9", + "walkdir", + "xdg", + "xml-rs", +] + +[[package]] +name = "android_glue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" + +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "ash" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003d1fb2eb12eb06d4a03dbe02eea67a9fac910fa97932ab9e3a75b96a1ea5e5" +dependencies = [ + "shared_library", +] + +[[package]] +name = "atom" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c86699c3f02778ec07158376991c8f783dd1f2f95c579ffaf0738dc984b2fe2" + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + +[[package]] +name = "backtrace" +version = "0.3.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e" +dependencies = [ + "backtrace-sys", + "cfg-if", + "libc", + "rustc-demangle", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78848718ee1255a2485d1309ad9cdecfc2e7d0362dd11c6829364c6b35ae1bc7" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" +dependencies = [ + "arrayref", + "byte-tools", +] + +[[package]] +name = "bumpalo" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187" + +[[package]] +name = "byte-tools" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "calloop" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aa2097be53a00de9e8fc349fea6d76221f398f5c4fa550d420669906962d160" +dependencies = [ + "mio", + "mio-extras", + "nix", +] + +[[package]] +name = "cc" +version = "1.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cgmath" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "283944cdecc44bf0b8dd010ec9af888d3b4f142844fdbe026c20ef68148d6fe7" +dependencies = [ + "approx", + "num-traits", + "rand 0.6.5", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "cmake" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" +dependencies = [ + "cc", +] + +[[package]] +name = "cocoa" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29f7768b2d1be17b96158e3285951d366b40211320fb30826a76cb7a0da6400" +dependencies = [ + "bitflags", + "block", + "core-foundation 0.6.4", + "core-graphics 0.17.3", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4736c86d51bd878b474400d9ec888156f4037015f5d09794fab9f26eab1ad4" +dependencies = [ + "bitflags", + "block", + "core-foundation 0.7.0", + "core-graphics 0.19.0", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "color_quant" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" + +[[package]] +name = "colorful" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bca1619ff57dd7a56b58a8e25ef4199f123e78e503fe1653410350a1b98ae65" + +[[package]] +name = "copyless" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff9c56c9fb2a49c05ef0e431485a22400af20d33226dc0764d891d09e724127" + +[[package]] +name = "core-foundation" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" +dependencies = [ + "core-foundation-sys 0.6.2", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys 0.7.0", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "core-graphics" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" +dependencies = [ + "bitflags", + "core-foundation 0.6.4", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e78b2e0aaf43f08e7ae0d6bc96895ef72ff0921c7d4ff4762201b2dba376dd" +dependencies = [ + "bitflags", + "core-foundation 0.7.0", + "foreign-types", + "libc", +] + +[[package]] +name = "core-video-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc065219542086f72d1e9f7aadbbab0989e980263695d129d502082d063a9d0" +dependencies = [ + "cfg-if", + "core-foundation-sys 0.6.2", + "core-graphics 0.17.3", + "libc", + "objc", +] + +[[package]] +name = "crc32fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg 1.0.0", + "cfg-if", + "crossbeam-utils", + "lazy_static", + "maybe-uninit", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg 1.0.0", + "cfg-if", + "lazy_static", +] + +[[package]] +name = "d3d12" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7ed48e89905e5e146bcc1951cc3facb9e44aea9adf5dc01078cda1bd24b662" +dependencies = [ + "bitflags", + "libloading", + "winapi 0.3.8", +] + +[[package]] +name = "deflate" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "digest" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dispatch" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e93ca78226c51902d7aa8c12c988338aadd9e85ed9c6be8aaac39192ff3605" + +[[package]] +name = "dlib" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba6eb47c2131e784a38b726eb54c1e1484904f013e576a25354d0124161af6" + +[[package]] +name = "either" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" + +[[package]] +name = "failure" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" +dependencies = [ + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.18", + "synstructure 0.12.3", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" +dependencies = [ + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gfx-auxil" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572eee952a9a23c99cfe3e4fd95d277784058a89ac3c77ff6fa3d80a4e321919" +dependencies = [ + "fxhash", + "gfx-hal", + "spirv_cross", +] + +[[package]] +name = "gfx-backend-dx11" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7527cfcd7d1eec6b99f81891293bdd2a41d044ace009717264e5f3b10ce5b86" +dependencies = [ + "bitflags", + "gfx-auxil", + "gfx-hal", + "libloading", + "log", + "parking_lot 0.10.2", + "range-alloc", + "raw-window-handle", + "smallvec 0.6.13", + "spirv_cross", + "winapi 0.3.8", + "wio", +] + +[[package]] +name = "gfx-backend-dx12" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "305620be6365b7dd8ef8e2bf320174f7aad4a23efb34136ee5b4d4d28bbe1714" +dependencies = [ + "bitflags", + "d3d12", + "gfx-auxil", + "gfx-hal", + "log", + "range-alloc", + "raw-window-handle", + "smallvec 0.6.13", + "spirv_cross", + "winapi 0.3.8", +] + +[[package]] +name = "gfx-backend-empty" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d383e6bc48867cb37d298a20139fd1eec298f8f6d594690cd1c50ef25470cc7" +dependencies = [ + "gfx-hal", + "raw-window-handle", +] + +[[package]] +name = "gfx-backend-metal" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b6130b9a72129ebb5c91d3d75a142a7fa54dcc112603231582e3fdc0b84247" +dependencies = [ + "arrayvec", + "bitflags", + "block", + "cocoa 0.20.0", + "copyless", + "core-graphics 0.19.0", + "foreign-types", + "gfx-auxil", + "gfx-hal", + "lazy_static", + "log", + "metal", + "objc", + "parking_lot 0.10.2", + "range-alloc", + "raw-window-handle", + "smallvec 0.6.13", + "spirv_cross", + "storage-map", +] + +[[package]] +name = "gfx-backend-vulkan" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b8d901941d1734d307dacd8e5f00c89ee8fb8e78b4dab3edd91248150b26b4" +dependencies = [ + "arrayvec", + "ash", + "byteorder", + "core-graphics 0.19.0", + "gfx-hal", + "lazy_static", + "log", + "objc", + "raw-window-handle", + "smallvec 0.6.13", + "winapi 0.3.8", + "x11", +] + +[[package]] +name = "gfx-hal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c88981665c780447bb08eb099e1ded330754a7246719bab927ee4a949c0ba7f" +dependencies = [ + "bitflags", + "raw-window-handle", + "smallvec 0.6.13", +] + +[[package]] +name = "gif" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af" +dependencies = [ + "color_quant", + "lzw", +] + +[[package]] +name = "glsl-to-spirv" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28caebc98746d507603a2d3df66dcbe04e41d4febad0320f3eec1ef72b6bbef1" +dependencies = [ + "cmake", + "sha2", + "tempfile", +] + +[[package]] +name = "graphite" +version = "0.1.0" +dependencies = [ + "cgmath", + "failure", + "glsl-to-spirv", + "image", + "palette", + "wgpu", + "winit", +] + +[[package]] +name = "hermit-abi" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d737e0f947a1864e93d33fdef4af8445a00d1ed8dc0c8ddb73139ea6abf15" +dependencies = [ + "libc", +] + +[[package]] +name = "hibitset" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93a1bb8316a44459a7d14253c4d28dd7395cbd23cc04a68c46e851b8e46d64b1" +dependencies = [ + "atom", +] + +[[package]] +name = "image" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ed2ada878397b045454ac7cfb011d73132c59f31a955d230bd1f1c2e68eb4a" +dependencies = [ + "byteorder", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "inflate" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" +dependencies = [ + "adler32", +] + +[[package]] +name = "instant" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7152d2aed88aa566e7a342250f21ba2222c1ae230ad577499dbfa3c18475b80" + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451" +dependencies = [ + "byteorder", + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" + +[[package]] +name = "libc" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" + +[[package]] +name = "libloading" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" +dependencies = [ + "cc", + "winapi 0.3.8", +] + +[[package]] +name = "line_drawing" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9" +dependencies = [ + "num-traits", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "lzw" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi 0.3.8", +] + +[[package]] +name = "memoffset" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" +dependencies = [ + "autocfg 1.0.0", +] + +[[package]] +name = "metal" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e198a0ee42bdbe9ef2c09d0b9426f3b2b47d90d93a4a9b0395c4cea605e92dc0" +dependencies = [ + "bitflags", + "block", + "cocoa 0.20.0", + "core-graphics 0.19.0", + "foreign-types", + "log", + "objc", +] + +[[package]] +name = "mio" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +dependencies = [ + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio", + "slab", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "net2" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +dependencies = [ + "cfg-if", + "libc", + "winapi 0.3.8", +] + +[[package]] +name = "nix" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "void", +] + +[[package]] +name = "num-derive" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "num-integer" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +dependencies = [ + "autocfg 1.0.0", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00" +dependencies = [ + "autocfg 1.0.0", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg 1.0.0", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +dependencies = [ + "autocfg 1.0.0", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "ordered-float" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" +dependencies = [ + "num-traits", +] + +[[package]] +name = "palette" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a05c0334468e62a4dfbda34b29110aa7d70d58c7fdb2c9857b5874dd9827cc59" +dependencies = [ + "approx", + "num-traits", + "palette_derive", + "phf", + "phf_codegen", +] + +[[package]] +name = "palette_derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b4b5f600e60dd3a147fb57b4547033d382d1979eb087af310e91cb45a63b1f4" +dependencies = [ + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.18", +] + +[[package]] +name = "parking_lot" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" +dependencies = [ + "lock_api", + "parking_lot_core 0.6.2", + "rustc_version", +] + +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +dependencies = [ + "lock_api", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "rustc_version", + "smallvec 0.6.13", + "winapi 0.3.8", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "smallvec 1.4.0", + "winapi 0.3.8", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared", + "rand 0.7.3", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pkg-config" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" + +[[package]] +name = "png" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef859a23054bbfee7811284275ae522f0434a3c8e7f4b74bd4a35ae7e1c4a283" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "inflate", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" +dependencies = [ + "unicode-xid 0.2.0", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +dependencies = [ + "proc-macro2 1.0.10", +] + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg 0.1.2", + "rand_xorshift", + "winapi 0.3.8", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg 0.2.1", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi 0.3.8", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi 0.3.8", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "range-alloc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd5927936723a9e8b715d37d7e4b390455087c4bdf25b9f702309460577b14f9" + +[[package]] +name = "raw-window-handle" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +dependencies = [ + "libc", +] + +[[package]] +name = "rayon" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" +dependencies = [ + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" +dependencies = [ + "crossbeam-deque", + "crossbeam-queue", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + +[[package]] +name = "relevant" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc232e13d37f4547f5b9b42a5efc380cabe5dbc1807f8b893580640b2ab0308" +dependencies = [ + "cfg-if", + "log", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" +dependencies = [ + "winapi 0.3.8", +] + +[[package]] +name = "rendy-descriptor" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f475bcc0505946e998590f1f0545c52ef4b559174a1b353a7ce6638def8b621e" +dependencies = [ + "gfx-hal", + "log", + "relevant", + "smallvec 0.6.13", +] + +[[package]] +name = "rendy-memory" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed492161a819feae7f27f418bb16035276ac20649c60d756699152cb5c1960ec" +dependencies = [ + "colorful", + "gfx-hal", + "hibitset", + "log", + "relevant", + "slab", + "smallvec 0.6.13", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rusttype" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310942406a39981bed7e12b09182a221a29e0990f3e7e0c971f131922ed135d5" +dependencies = [ + "rusttype 0.8.3", +] + +[[package]] +name = "rusttype" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f61411055101f7b60ecf1041d87fb74205fb20b0c7a723f07ef39174cf6b4c0" +dependencies = [ + "approx", + "ordered-float", + "stb_truetype", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "sha2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" +dependencies = [ + "block-buffer", + "byte-tools", + "digest", + "fake-simd", +] + +[[package]] +name = "shared_library" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "siphasher" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7" + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "smallvec" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smallvec" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" + +[[package]] +name = "smithay-client-toolkit" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421c8dc7acf5cb205b88160f8b4cc2c5cfabe210e43b2f80f009f4c1ef910f1d" +dependencies = [ + "andrew", + "bitflags", + "dlib", + "lazy_static", + "memmap", + "nix", + "wayland-client", + "wayland-protocols", +] + +[[package]] +name = "spirv_cross" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbbe441b3ac8ec0ae6a4f05234239bd372a241ce15793eef694e8b24afc267bb" +dependencies = [ + "cc", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "stb_truetype" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" +dependencies = [ + "byteorder", +] + +[[package]] +name = "storage-map" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0a4829a5c591dc24a944a736d6b1e4053e51339a79fd5d4702c4c999a9c45e" +dependencies = [ + "lock_api", +] + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213" +dependencies = [ + "proc-macro2 1.0.10", + "quote 1.0.3", + "unicode-xid 0.2.0", +] + +[[package]] +name = "synstructure" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", + "unicode-xid 0.1.0", +] + +[[package]] +name = "synstructure" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +dependencies = [ + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.18", + "unicode-xid 0.2.0", +] + +[[package]] +name = "tempfile" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +dependencies = [ + "cfg-if", + "libc", + "rand 0.7.3", + "redox_syscall", + "remove_dir_all", + "winapi 0.3.8", +] + +[[package]] +name = "tiff" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b7c2cfc4742bd8a32f2e614339dd8ce30dbcf676bb262bd63a2327bc5df57d" +dependencies = [ + "byteorder", + "lzw", + "num-derive", + "num-traits", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi 0.3.8", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasm-bindgen" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.18", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" +dependencies = [ + "quote 1.0.3", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" +dependencies = [ + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.18", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" + +[[package]] +name = "wayland-client" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda" +dependencies = [ + "bitflags", + "calloop", + "downcast-rs", + "libc", + "mio", + "nix", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb" +dependencies = [ + "nix", + "wayland-sys", +] + +[[package]] +name = "wayland-protocols" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9" +dependencies = [ + "bitflags", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4" +dependencies = [ + "dlib", + "lazy_static", +] + +[[package]] +name = "wgpu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e9c1ff587eddd68cdf2a78889c7a2128683161c72c67b94457cf498accaf7b" +dependencies = [ + "arrayvec", + "raw-window-handle", + "wgpu-native", + "zerocopy", +] + +[[package]] +name = "wgpu-native" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26642308af1cc9a28a24c7fc5e5408d9689c8a0c01d7117aa83d5a1ed6e83438" +dependencies = [ + "arrayvec", + "bitflags", + "copyless", + "fxhash", + "gfx-backend-dx11", + "gfx-backend-dx12", + "gfx-backend-empty", + "gfx-backend-metal", + "gfx-backend-vulkan", + "gfx-hal", + "lazy_static", + "log", + "parking_lot 0.9.0", + "raw-window-handle", + "rendy-descriptor", + "rendy-memory", + "smallvec 0.6.13", + "vec_map", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.8", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winit" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ba128780050481f453bec2a115b916dbc6ae79c303dee9bad8b9080bdccd4f5" +dependencies = [ + "android_glue", + "bitflags", + "cocoa 0.19.1", + "core-foundation 0.6.4", + "core-graphics 0.17.3", + "core-video-sys", + "dispatch", + "instant", + "lazy_static", + "libc", + "log", + "mio", + "mio-extras", + "objc", + "parking_lot 0.10.2", + "percent-encoding", + "raw-window-handle", + "smithay-client-toolkit", + "wayland-client", + "winapi 0.3.8", + "x11-dl", +] + +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi 0.3.8", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "x11" +version = "2.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ecd092546cb16f25783a5451538e73afc8d32e242648d54f4ae5459ba1e773" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +dependencies = [ + "lazy_static", + "libc", + "maybe-uninit", + "pkg-config", +] + +[[package]] +name = "xdg" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" + +[[package]] +name = "xml-rs" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb76e5c421bbbeb8924c60c030331b345555024d56261dae8f3e786ed817c23" + +[[package]] +name = "zerocopy" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "992b9b31f80fd4a167f903f879b8ca43d6716cc368ea01df90538baa2dd34056" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b090467ecd0624026e8a6405d343ac7382592530d54881330b3fc8e400280fa5" +dependencies = [ + "proc-macro2 0.4.30", + "syn 0.15.44", + "synstructure 0.10.2", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..42a9df04 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "graphite" +version = "0.1.0" +authors = ["Keavon Chambers "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +image = "0.22" +winit = "0.20" +wgpu = "0.4" +glsl-to-spirv = "0.1" +failure = "0.1.7" +cgmath = "0.17" +palette = "0.5" \ No newline at end of file diff --git a/shaders/shader.frag b/shaders/shader.frag new file mode 100644 index 00000000..2327b894 --- /dev/null +++ b/shaders/shader.frag @@ -0,0 +1,11 @@ +#version 450 + +layout(location=0) in vec2 v_uv; + +layout(location=0) out vec4 f_color; + +layout(set = 0, binding = 0) uniform sampler2D t_texture; + +void main() { + f_color = texture(t_texture, v_uv / textureSize(t_texture, 0) * 100); +} \ No newline at end of file diff --git a/shaders/shader.vert b/shaders/shader.vert new file mode 100644 index 00000000..06ede5f9 --- /dev/null +++ b/shaders/shader.vert @@ -0,0 +1,10 @@ +#version 450 + +layout(location=0) in vec2 a_position; + +layout(location=0) out vec2 v_uv; + +void main() { + v_uv = a_position; + gl_Position = vec4(a_position, 0.0, 1.0); +} \ No newline at end of file diff --git a/src/application.rs b/src/application.rs new file mode 100644 index 00000000..ad164e3c --- /dev/null +++ b/src/application.rs @@ -0,0 +1,240 @@ +// use super::render_state::RenderState; +// use super::program_state::ProgramState; +use super::color_palette::ColorPalette; +use super::gui_rect::GUIRect; +use super::pipeline::Pipeline; +use super::pipeline::PipelineDetails; +use super::shader_cache::ShaderCache; +use super::texture::Texture; + +use std::collections::VecDeque; +use winit::event::*; +use winit::event_loop::ControlFlow; +use winit::event_loop::EventLoop; +use winit::window::Window; + +pub struct Application { + pub surface: wgpu::Surface, + pub adapter: wgpu::Adapter, + pub device: wgpu::Device, + pub queue: wgpu::Queue, + pub swap_chain_descriptor: wgpu::SwapChainDescriptor, + pub swap_chain: wgpu::SwapChain, + pub shader_cache: ShaderCache, + // pub texture_cache: TextureCache, + pub gui_rect_queue: VecDeque, + pub pipeline_queue: VecDeque, + pub temp_color_toggle: bool, +} + +impl Application { + pub fn new(window: &Window) -> Self { + // Window as understood by WGPU for rendering onto + let surface = wgpu::Surface::create(window); + + // Represents a GPU, exposes the real GPU device and queue + let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions { ..Default::default() }).unwrap(); + + // Requests the device and queue from the adapter + let requested_device = adapter.request_device(&wgpu::DeviceDescriptor { + extensions: wgpu::Extensions { anisotropic_filtering: false }, + limits: Default::default(), + }); + + // Connection to the physical GPU + let device = requested_device.0; + + // Represents the GPU command queue, to submit CommandBuffers + let queue = requested_device.1; + + // Properties for the swap chain frame buffers + let swap_chain_descriptor = wgpu::SwapChainDescriptor { + usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, + format: wgpu::TextureFormat::Bgra8UnormSrgb, + width: window.inner_size().width, + height: window.inner_size().height, + present_mode: wgpu::PresentMode::Vsync, + }; + + // Series of frame buffers with images presented to the surface + let swap_chain = device.create_swap_chain(&surface, &swap_chain_descriptor); + + // Cache of all loaded shaders + let shader_cache = ShaderCache::new(); + + let gui_rect_queue = VecDeque::new(); + + let pipeline_queue = VecDeque::new(); + + Self { + surface, + adapter, + device, + queue, + swap_chain_descriptor, + swap_chain, + shader_cache, + gui_rect_queue, + pipeline_queue, + temp_color_toggle: true, + } + } + + pub fn example(&mut self) { + self.shader_cache.load(&self.device, "shaders/shader.vert", glsl_to_spirv::ShaderType::Vertex).unwrap(); + self.shader_cache.load(&self.device, "shaders/shader.frag", glsl_to_spirv::ShaderType::Fragment).unwrap(); + + let vertex_shader = self.shader_cache.get_by_path("shaders/shader.vert").unwrap(); + let fragment_shader = self.shader_cache.get_by_path("shaders/shader.frag").unwrap(); + + let texture_view = Texture::from_filepath(&self.device, &mut self.queue, "textures/grid.png").unwrap().view; + + let example_pipeline = Pipeline::new(&self.device, PipelineDetails { + vertex_shader, + fragment_shader, + texture_view: Some(&texture_view), + }); + + self.pipeline_queue.push_back(example_pipeline); + } + + pub fn begin_lifecycle(mut self, event_loop: EventLoop<()>, window: Window) { + event_loop.run(move |event, _, control_flow| self.main_event_loop(event, control_flow, &window)); + } + + pub fn main_event_loop(&mut self, event: Event<'_, T>, control_flow: &mut ControlFlow, window: &Window) { + match event { + // Handle all window events in sequence + Event::WindowEvent { ref event, window_id } if window_id == window.id() => { + self.window_event(event, control_flow); + }, + // After handling every event and updating the GUI, request a new sequence of draw commands + Event::MainEventsCleared => { + // Turn the GUI changes into draw commands added to the render pipeline queue + self.redraw(); + + // If any draw commands were actually added, ask the window to issue a redraw event + if !self.pipeline_queue.is_empty() { + window.request_redraw(); + } + + *control_flow = ControlFlow::Wait; + }, + // Resizing or calling `window.request_redraw()` now redraws the GUI with the pipeline queue + Event::RedrawRequested(_) => { + self.render(); + *control_flow = ControlFlow::Wait; + }, + // Catch extraneous events + _ => { + *control_flow = ControlFlow::Wait; + }, + } + } + + pub fn window_event(&mut self, event: &WindowEvent, control_flow: &mut ControlFlow) { + match event { + WindowEvent::CloseRequested => { + self.quit(control_flow); + }, + WindowEvent::KeyboardInput { input, .. } => { + self.keyboard_event(input, control_flow); + }, + WindowEvent::Resized(physical_size) => { + self.resize(*physical_size); + *control_flow = ControlFlow::Wait; + }, + WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { + self.resize(**new_inner_size); + *control_flow = ControlFlow::Wait; + }, + _ => { + *control_flow = ControlFlow::Wait; + }, + } + } + + pub fn keyboard_event(&mut self, input: &KeyboardInput, control_flow: &mut ControlFlow) { + match input { + KeyboardInput { state: ElementState::Pressed, virtual_keycode: Some(VirtualKeyCode::Escape), .. } => { + self.quit(control_flow); + }, + KeyboardInput { state: ElementState::Pressed, virtual_keycode: Some(VirtualKeyCode::Space), .. } => { + self.example(); + }, + _ => { + *control_flow = ControlFlow::Wait; + }, + } + } + + pub fn quit(&self, control_flow: &mut ControlFlow) { + *control_flow = ControlFlow::Exit; + } + + pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize) { + self.swap_chain_descriptor.width = new_size.width; + self.swap_chain_descriptor.height = new_size.height; + + self.swap_chain = self.device.create_swap_chain(&self.surface, &self.swap_chain_descriptor); + + // TODO: Mark root of GUI as dirty to force redraw of everything + } + + // Traverse the dirty GUI elements and queue up pipelines to render each GUI rectangle (box/sprite) + pub fn redraw(&mut self) { + + } + + // Render the queue of pipeline draw commands over the current window + pub fn render(&mut self) { + // Turn the queue of pipelines each into a command buffer and submit it to the render queue + while !self.pipeline_queue.is_empty() { + // Get a frame buffer to render on + let frame = self.swap_chain.get_next_texture(); + + // Get the pipeline to render in this iteration + let pipeline_struct = self.pipeline_queue.pop_back().unwrap(); + + // Generates a render pass that commands are applied to, then generates a command buffer when finished + let mut command_encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); + + // Temporary way to swap clear color every render + let color = match self.temp_color_toggle { + true => ColorPalette::get_color_linear(ColorPalette::MildBlack), + false => ColorPalette::get_color_linear(ColorPalette::NearBlack), + }; + self.temp_color_toggle = !self.temp_color_toggle; + + // Recording of commands while in "rendering mode" that go into a command buffer + let mut render_pass = command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + color_attachments: &[ + wgpu::RenderPassColorAttachmentDescriptor { + attachment: &frame.view, + resolve_target: None, + load_op: wgpu::LoadOp::Clear, + store_op: wgpu::StoreOp::Store, + clear_color: color, + } + ], + depth_stencil_attachment: None, + }); + + // Commands sent to the GPU for drawing during this render pass + render_pass.set_pipeline(&pipeline_struct.render_pipeline); + render_pass.set_vertex_buffers(0, &[(&pipeline_struct.vertex_buffer, 0)]); + render_pass.set_index_buffer(&pipeline_struct.index_buffer, 0); + render_pass.set_bind_group(0, &pipeline_struct.texture_bind_group, &[]); + render_pass.draw_indexed(0..pipeline_struct.index_count, 0, 0..1); + + // Done sending render pass commands so we can give up mutation rights to command_encoder + drop(render_pass); + + // Turn the recording of commands into a complete command buffer + let command_buffer = command_encoder.finish(); + + // Submit the command buffer to the GPU command queue + self.queue.submit(&[command_buffer]); + } + } +} diff --git a/src/color_palette.rs b/src/color_palette.rs new file mode 100644 index 00000000..bf4f8e63 --- /dev/null +++ b/src/color_palette.rs @@ -0,0 +1,69 @@ +#[allow(dead_code)] +pub enum ColorPalette { + Black, + NearBlack, + MildBlack, + DarkGray, + DimGray, + DullGray, + LowerGray, + MiddleGray, + UpperGray, + PaleGray, + SoftGray, + LightGray, + BrightGray, + MildWhite, + NearWhite, + White, + Accent, +} + +impl ColorPalette { + pub fn get_color(self) -> wgpu::Color { + let grayscale = match self { + ColorPalette::Black => 0 * 17, // #000000 + ColorPalette::NearBlack => 1 * 17, // #111111 + ColorPalette::MildBlack => 2 * 17, // #222222 + ColorPalette::DarkGray => 3 * 17, // #333333 + ColorPalette::DimGray => 4 * 17, // #444444 + ColorPalette::DullGray => 5 * 17, // #555555 + ColorPalette::LowerGray => 6 * 17, // #666666 + ColorPalette::MiddleGray => 7 * 17, // #777777 + ColorPalette::UpperGray => 8 * 17, // #888888 + ColorPalette::PaleGray => 9 * 17, // #999999 + ColorPalette::SoftGray => 10 * 17, // #aaaaaa + ColorPalette::LightGray => 11 * 17, // #bbbbbb + ColorPalette::BrightGray => 12 * 17, // #cccccc + ColorPalette::MildWhite => 13 * 17, // #dddddd + ColorPalette::NearWhite => 14 * 17, // #eeeeee + ColorPalette::White => 15 * 17, // #ffffff + _ => -1, + }; + + if grayscale > -1 { + let value = grayscale as f64 / 255.0; + return wgpu::Color { r: value, g: value, b: value, a: 1.0 }; + } + + let rgba = match self { + ColorPalette::Accent => (75, 121, 167, 255), // #4b79a7 + _ => (0, 0, 0, 255), // Unimplemented returns black + }; + + wgpu::Color { + r: rgba.0 as f64 / 255.0, + g: rgba.1 as f64 / 255.0, + b: rgba.2 as f64 / 255.0, + a: rgba.3 as f64 / 255.0 + } + } + + pub fn get_color_linear(self) -> wgpu::Color { + let standard_rgb = ColorPalette::get_color(self); + + let linear = palette::Srgb::new(standard_rgb.r, standard_rgb.g, standard_rgb.b).into_linear(); + + wgpu::Color { r: linear.red, g: linear.green, b: linear.blue, a: standard_rgb.a } + } +} \ No newline at end of file diff --git a/src/gui_rect.rs b/src/gui_rect.rs new file mode 100644 index 00000000..38c62778 --- /dev/null +++ b/src/gui_rect.rs @@ -0,0 +1,23 @@ +pub struct GUIRect { + pub corners: Corners<(f32, f32)>, + pub corners_radius: Corners, + pub sides_inset: Sides, + pub border: f32, + pub border_color: wgpu::Color, + pub fill_color: wgpu::Color, + pub fill_texture: Option, +} + +pub struct Corners { + pub top_left: T, + pub top_right: T, + pub bottom_right: T, + pub bottom_left: T, +} + +pub struct Sides { + pub top: T, + pub right: T, + pub bottom: T, + pub left: T, +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 00000000..505cfd39 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,30 @@ +mod application; +mod gui_rect; +mod pipeline; +mod program_state; +mod texture; +mod color_palette; +mod shader_cache; + +use application::Application; +use winit::event_loop::EventLoop; +use winit::window::WindowBuilder; + +fn main() { + // Handles all window events, user input, and redraws + let event_loop = EventLoop::new(); + + // Application window in the operating system + let window = WindowBuilder::new().with_title("Graphite").build(&event_loop).unwrap(); + + // Initialize the render pipeline + let mut app = Application::new(&window); + app.example(); + + // State managers for render pipeline and program logic + // let app_render_state = RenderState::new(&mut app); + // let app_program_state = ProgramState::new(&mut app); + + // Begin the application lifecycle + app.begin_lifecycle(event_loop, window); +} diff --git a/src/pipeline.rs b/src/pipeline.rs new file mode 100644 index 00000000..958901e3 --- /dev/null +++ b/src/pipeline.rs @@ -0,0 +1,125 @@ +pub struct PipelineDetails<'a> { + pub vertex_shader: &'a wgpu::ShaderModule, + pub fragment_shader: &'a wgpu::ShaderModule, + pub texture_view: Option<&'a wgpu::TextureView>, +} + +pub struct Pipeline { + pub render_pipeline: wgpu::RenderPipeline, + pub vertex_buffer: wgpu::Buffer, + pub index_buffer: wgpu::Buffer, + pub index_count: u32, + pub texture_bind_group: wgpu::BindGroup, +} + +impl Pipeline { + pub fn new(device: &wgpu::Device, pipeline_details: PipelineDetails) -> Self { + let texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + bindings: &[ + wgpu::BindGroupLayoutBinding { + binding: 0, + visibility: wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::SampledTexture { + multisampled: false, + dimension: wgpu::TextureViewDimension::D2, + }, + }, + // wgpu::BindGroupLayoutBinding { + // binding: 1, + // visibility: wgpu::ShaderStage::FRAGMENT, + // ty: wgpu::BindingType::Sampler, + // }, + ], + }); + + let texture_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: &texture_bind_group_layout, + bindings: &[ + wgpu::Binding { + binding: 0, + resource: wgpu::BindingResource::TextureView(pipeline_details.texture_view.unwrap()), + }, + // wgpu::Binding { + // binding: 1, + // resource: wgpu::BindingResource::Sampler(&texture.sampler), + // } + ], + }); + + let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + bind_group_layouts: &[&texture_bind_group_layout], + }); + + let vertex_buffer_descriptors = wgpu::VertexBufferDescriptor { + stride: std::mem::size_of::<[f32; 2]>() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &[ + wgpu::VertexAttributeDescriptor { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float2, + }, + ], + }; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + layout: &render_pipeline_layout, + vertex_stage: wgpu::ProgrammableStageDescriptor { + module: pipeline_details.vertex_shader, + entry_point: "main", + }, + fragment_stage: Some(wgpu::ProgrammableStageDescriptor { + module: pipeline_details.fragment_shader, + entry_point: "main", + }), + rasterization_state: Some(wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::Back, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: 0.0, + }), + color_states: &[ + wgpu::ColorStateDescriptor { + format: wgpu::TextureFormat::Bgra8UnormSrgb, + color_blend: wgpu::BlendDescriptor::REPLACE, + alpha_blend: wgpu::BlendDescriptor::REPLACE, + write_mask: wgpu::ColorWrite::ALL, + }, + ], + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + depth_stencil_state: None, + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[vertex_buffer_descriptors], + sample_count: 1, + sample_mask: !0, + alpha_to_coverage_enabled: false, + }); + + let vertex_buffer = device.create_buffer_mapped(VERTICES.len(), wgpu::BufferUsage::VERTEX).fill_from_slice(VERTICES); + let index_buffer = device.create_buffer_mapped(INDICES.len(), wgpu::BufferUsage::INDEX).fill_from_slice(INDICES); + let index_count = INDICES.len() as u32; + + Self { + render_pipeline, + vertex_buffer, + index_buffer, + index_count, + texture_bind_group, + } + } +} + +const VERTICES: &[[f32; 2]] = &[ + [-0.0868241, -0.49240386], + [-0.49513406, -0.06958647], + [-0.21918549, 0.44939706], + [0.35966998, 0.3473291], + [0.44147372, -0.2347359], +]; + +const INDICES: &[u16] = &[ + 0, 1, 4, + 1, 2, 4, + 2, 3, 4, +]; \ No newline at end of file diff --git a/src/program_state.rs b/src/program_state.rs new file mode 100644 index 00000000..380cf049 --- /dev/null +++ b/src/program_state.rs @@ -0,0 +1,13 @@ +use super::application::Application; + +pub struct ProgramState { + +} + +impl ProgramState { + pub fn new(application: &mut Application) -> ProgramState { + Self { + + } + } +} \ No newline at end of file diff --git a/src/render_state.rs b/src/render_state.rs new file mode 100644 index 00000000..c5899a30 --- /dev/null +++ b/src/render_state.rs @@ -0,0 +1,26 @@ +// use super::texture::Texture; +// use super::application::Application; + +// use std::collections::HashMap; + +// pub struct RenderState { +// pub render_pipeline: wgpu::RenderPipeline, +// pub vertex_buffer: wgpu::Buffer, +// pub index_buffer: wgpu::Buffer, +// pub num_indices: u32, +// pub texture: Texture, +// pub texture_bind_group: wgpu::BindGroup, +// } + +// impl RenderState { +// pub fn new(application: &mut Application) -> Self { + + +// Self { +// vertex_buffer, +// index_buffer, +// num_indices, +// } +// } +// } + diff --git a/src/shader_cache.rs b/src/shader_cache.rs new file mode 100644 index 00000000..77f4703a --- /dev/null +++ b/src/shader_cache.rs @@ -0,0 +1,49 @@ +use std::collections::HashMap; + +#[derive(Copy, Clone)] +pub struct ShaderID { + pub index: usize, +} + +pub struct ShaderCache { + pub shaders: Vec, + pub path_to_id: HashMap, +} + +impl ShaderCache { + pub fn new() -> Self { + let shaders = Vec::new(); + let path_to_id = HashMap::new(); + + Self { + shaders, + path_to_id, + } + } + + pub fn get_by_path(&self, path: &str) -> Option<&wgpu::ShaderModule> { + match self.path_to_id.get(path) { + Some(id) => self.shaders.get(id.index), + None => None, + } + } + + // pub fn get_by_id(&self, id: ShaderID) -> Option<&wgpu::ShaderModule> { + // self.shaders.get(id.index) + // } + + pub fn load(&mut self, device: &wgpu::Device, path: &str, shader_type: glsl_to_spirv::ShaderType) -> Result<(), std::io::Error> { + if self.path_to_id.get(path).is_none() { + let source = std::fs::read_to_string(path)?; + let spirv = glsl_to_spirv::compile(&source[..], shader_type).unwrap(); + let compiled = wgpu::read_spirv(spirv).unwrap(); + let shader = device.create_shader_module(&compiled); + + let length = self.path_to_id.len(); + self.path_to_id.insert(String::from(path), ShaderID { index: length }); + self.shaders.push(shader); + } + + Ok(()) + } +} \ No newline at end of file diff --git a/src/texture.rs b/src/texture.rs new file mode 100644 index 00000000..08248766 --- /dev/null +++ b/src/texture.rs @@ -0,0 +1,78 @@ +use image::GenericImageView; + +pub struct Texture { + pub texture: wgpu::Texture, + pub view: wgpu::TextureView, + pub sampler: wgpu::Sampler, +} + +impl Texture { + pub fn from_filepath(device: &wgpu::Device, queue: &mut wgpu::Queue, path: &str) -> Result { + let bytes = std::fs::read(path)?; + Texture::from_bytes(device, queue, &bytes[..]) + } + + pub fn from_bytes(device: &wgpu::Device, queue: &mut wgpu::Queue, bytes: &[u8]) -> Result { + let img = image::load_from_memory(bytes)?; + Self::from_image(device, queue, &img) + } + + pub fn from_image(device: &wgpu::Device, queue: &mut wgpu::Queue, img: &image::DynamicImage) -> Result { + let rgba = img.as_rgba8().unwrap(); + let dimensions = img.dimensions(); + let size = wgpu::Extent3d { + width: dimensions.0, + height: dimensions.1, + depth: 1, + }; + + let texture = device.create_texture(&wgpu::TextureDescriptor { + size, + array_layer_count: 1, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8UnormSrgb, + usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST, + }); + + let buffer = device.create_buffer_mapped(rgba.len(), wgpu::BufferUsage::COPY_SRC).fill_from_slice(&rgba); + + let mut encoder = device.create_command_encoder(&Default::default()); + + encoder.copy_buffer_to_texture( + wgpu::BufferCopyView { + buffer: &buffer, + offset: 0, + row_pitch: 4 * dimensions.0, + image_height: dimensions.1, + }, + wgpu::TextureCopyView { + texture: &texture, + mip_level: 0, + array_layer: 0, + origin: wgpu::Origin3d::ZERO, + }, + size, + ); + + let command_buffer = encoder.finish(); + + let view = texture.create_default_view(); + let sampler = device.create_sampler(&wgpu::SamplerDescriptor { + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Nearest, + mipmap_filter: wgpu::FilterMode::Nearest, + lod_min_clamp: -100.0, + lod_max_clamp: 100.0, + compare_function: wgpu::CompareFunction::Always, + }); + + queue.submit(&[command_buffer]); + + Ok(Self { texture, view, sampler }) + } +} \ No newline at end of file diff --git a/src/texture_cache.rs b/src/texture_cache.rs new file mode 100644 index 00000000..5ef3ed8d --- /dev/null +++ b/src/texture_cache.rs @@ -0,0 +1,50 @@ +use std::collections::HashMap; +use std::collections::HashMap; + +#[derive(Copy, Clone)] +pub struct TextureID { + pub index: usize, +} + +pub struct TextureCache { + pub textures: Vec, + pub name_to_id: HashMap, +} + +impl ShaderCache { + pub fn new() -> Self { + let shaders = Vec::new(); + let name_to_id = HashMap::new(); + + Self { + shaders, + name_to_id, + } + } + + pub fn get_by_path(&self, path: &str) -> Option<&wgpu::ShaderModule> { + match self.name_to_id.get(path) { + Some(id) => self.shaders.get(id.index), + None => None, + } + } + + pub fn get_by_id(&self, id: ShaderID) -> Option<&wgpu::ShaderModule> { + self.shaders.get(id.index) + } + + pub fn load(&mut self, device: &wgpu::Device, path: &str, shader_type: glsl_to_spirv::ShaderType) -> Result<(), std::io::Error> { + if self.name_to_id.get(path).is_none() { + let source = std::fs::read_to_string(path)?; + let spirv = glsl_to_spirv::compile(&source[..], shader_type).unwrap(); + let compiled = wgpu::read_spirv(spirv).unwrap(); + let shader = device.create_shader_module(&compiled); + + let length = self.name_to_id.len(); + self.name_to_id.insert(String::from(path), ShaderID { index: length }); + self.shaders.push(shader); + } + + Ok(()) + } +} \ No newline at end of file diff --git a/textures/grid.png b/textures/grid.png new file mode 100644 index 0000000000000000000000000000000000000000..4ad1b58c65caa65fd881e2dffe5724474179a987 GIT binary patch literal 17332 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 sjR|Yrnw(Hnd6sl91tx$3P^%>V!Z literal 0 HcmV?d00001