In VR mode, render one eye and then reproject to both eyes instead of rendering
twice. This reduces both CPU and GPU time a lot in exchange for a small loss in quality.
This commit is contained in:
parent
7cd05cd3ef
commit
6c31e1bc01
|
@ -64,6 +64,15 @@ dependencies = [
|
||||||
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argon2rs"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.4.10"
|
version = "0.4.10"
|
||||||
|
@ -128,6 +137,15 @@ name = "bitflags"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blake2-rfc"
|
||||||
|
version = "0.2.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block"
|
name = "block"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -198,6 +216,15 @@ dependencies = [
|
||||||
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "color-backtrace"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "color_quant"
|
name = "color_quant"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -215,6 +242,11 @@ dependencies = [
|
||||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "constant_time_eq"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.6.4"
|
version = "0.6.4"
|
||||||
|
@ -292,6 +324,7 @@ dependencies = [
|
||||||
name = "demo"
|
name = "demo"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"color-backtrace 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -304,6 +337,16 @@ dependencies = [
|
||||||
"sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dlib"
|
name = "dlib"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -370,6 +413,26 @@ dependencies = [
|
||||||
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "failure"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "failure_derive"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fixedbitset"
|
name = "fixedbitset"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
|
@ -1274,6 +1337,17 @@ dependencies = [
|
||||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "0.1.80"
|
version = "0.1.80"
|
||||||
|
@ -1550,6 +1624,27 @@ dependencies = [
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "synstructure"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "term"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
@ -1715,7 +1810,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1836,6 +1931,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407"
|
"checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407"
|
||||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||||
"checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
|
"checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
|
||||||
|
"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392"
|
||||||
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
|
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
|
||||||
"checksum ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5fc969a8ce2c9c0c4b0429bb8431544f6658283c8326ba5ff8c762b75369335"
|
"checksum ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5fc969a8ce2c9c0c4b0429bb8431544f6658283c8326ba5ff8c762b75369335"
|
||||||
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||||
|
@ -1844,6 +1940,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
|
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
|
||||||
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
|
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
|
||||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||||
|
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
|
||||||
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||||
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
|
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
|
||||||
"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e"
|
"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e"
|
||||||
|
@ -1853,8 +1950,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
||||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
"checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b"
|
"checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b"
|
||||||
|
"checksum color-backtrace 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "90242aff9b6439332beb77ee416126367adcd6376b0dc80b39250e7debdd913d"
|
||||||
"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
|
"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
|
||||||
"checksum combine 3.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d2623b3542b48f4427e15ddd4995186decb594ebbd70271463886584b4a114b9"
|
"checksum combine 3.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d2623b3542b48f4427e15ddd4995186decb594ebbd70271463886584b4a114b9"
|
||||||
|
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
|
||||||
"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
|
"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
|
||||||
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
|
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
|
||||||
"checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9"
|
"checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9"
|
||||||
|
@ -1863,6 +1962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
|
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
|
||||||
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
||||||
"checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86"
|
"checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86"
|
||||||
|
"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
|
||||||
"checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
|
"checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
|
||||||
"checksum downcast-rs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b92dfd5c2f75260cbf750572f95d387e7ca0ba5e3fbe9e1a33f23025be020f"
|
"checksum downcast-rs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b92dfd5c2f75260cbf750572f95d387e7ca0ba5e3fbe9e1a33f23025be020f"
|
||||||
"checksum egl 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a373bc9844200b1ff15bd1b245931d1c20d09d06e4ec09f361171f29a4b0752d"
|
"checksum egl 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a373bc9844200b1ff15bd1b245931d1c20d09d06e4ec09f361171f29a4b0752d"
|
||||||
|
@ -1871,6 +1971,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
|
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
|
||||||
"checksum euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a7698bdda3d7444a79d33bdc96e8b518d44ea3ff101d8492a6ca1207b886ea"
|
"checksum euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a7698bdda3d7444a79d33bdc96e8b518d44ea3ff101d8492a6ca1207b886ea"
|
||||||
"checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
|
"checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
|
||||||
|
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||||
|
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
||||||
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
|
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
|
||||||
"checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
|
"checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
|
||||||
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||||
|
@ -1961,6 +2063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||||
"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
|
"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
|
||||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||||
|
"checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828"
|
||||||
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
|
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
|
||||||
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
|
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
|
||||||
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
|
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
|
||||||
|
@ -1996,6 +2099,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum svgdom 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a9b53b3ed152fc6b871f7232a8772c640567fd25d056941450637ecba32924d"
|
"checksum svgdom 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a9b53b3ed152fc6b871f7232a8772c640567fd25d056941450637ecba32924d"
|
||||||
"checksum svgtypes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c43c25e6de7264024b5e351eb0c342039eb5acf51f2e9d0099bbd324b661453b"
|
"checksum svgtypes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c43c25e6de7264024b5e351eb0c342039eb5acf51f2e9d0099bbd324b661453b"
|
||||||
"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9"
|
"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9"
|
||||||
|
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
|
||||||
|
"checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
|
||||||
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
|
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
|
||||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||||
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
||||||
|
|
|
@ -18,6 +18,7 @@ import android.support.annotation.RequiresApi;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
@ -61,13 +62,8 @@ public class PathfinderDemoActivity extends Activity {
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
void setVRMode(boolean enabled) {
|
void setVRMode(boolean enabled) {
|
||||||
try {
|
|
||||||
setVrModeEnabled(false, mVRListenerComponentName);
|
|
||||||
mContentView.setStereoModeEnabled(enabled);
|
mContentView.setStereoModeEnabled(enabled);
|
||||||
mContentView.setDistortionCorrectionEnabled(false);
|
mContentView.setDistortionCorrectionEnabled(false);
|
||||||
} catch (PackageManager.NameNotFoundException exception) {
|
|
||||||
startActivity(new Intent(Settings.ACTION_VR_LISTENER_SETTINGS));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
|
|
@ -44,5 +44,4 @@ public class PathfinderDemoFileBrowserActivity extends Activity {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package graphics.pathfinder.pathfinderdemo;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.google.vr.sdk.base.Eye;
|
import com.google.vr.sdk.base.Eye;
|
||||||
import com.google.vr.sdk.base.GvrView;
|
import com.google.vr.sdk.base.GvrView;
|
||||||
|
@ -52,6 +53,7 @@ public class PathfinderDemoRenderer extends Object implements GvrView.Renderer {
|
||||||
mInVRMode = inVR;
|
mInVRMode = inVR;
|
||||||
try {
|
try {
|
||||||
mActivity.setVrModeEnabled(mInVRMode, mActivity.mVRListenerComponentName);
|
mActivity.setVrModeEnabled(mInVRMode, mActivity.mVRListenerComponentName);
|
||||||
|
mActivity.setVRMode(inVR);
|
||||||
} catch (PackageManager.NameNotFoundException exception) {
|
} catch (PackageManager.NameNotFoundException exception) {
|
||||||
throw new RuntimeException(exception);
|
throw new RuntimeException(exception);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,19 +12,18 @@
|
||||||
|
|
||||||
use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray};
|
use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray};
|
||||||
use crate::ui::{DemoUI, UIAction};
|
use crate::ui::{DemoUI, UIAction};
|
||||||
use crate::window::{CameraTransform, Event, Keycode, SVGPath, View, Window, WindowSize};
|
use crate::window::{Event, Keycode, OcularTransform, SVGPath, View, Window, WindowSize};
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use image::ColorType;
|
use image::ColorType;
|
||||||
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32, Point3DF32};
|
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32, Point3DF32};
|
||||||
use pathfinder_geometry::basic::rect::RectF32;
|
use pathfinder_geometry::basic::rect::RectF32;
|
||||||
use pathfinder_geometry::basic::transform2d::Transform2DF32;
|
use pathfinder_geometry::basic::transform2d::Transform2DF32;
|
||||||
use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF32};
|
use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF32};
|
||||||
use pathfinder_geometry::color::ColorU;
|
use pathfinder_geometry::color::{ColorF, ColorU};
|
||||||
use pathfinder_geometry::distortion::BarrelDistortionCoefficients;
|
|
||||||
use pathfinder_gl::GLDevice;
|
use pathfinder_gl::GLDevice;
|
||||||
use pathfinder_gpu::resources::ResourceLoader;
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderState, StencilFunc};
|
use pathfinder_gpu::{ClearParams, DepthFunc, DepthState, Device, Primitive, RenderState};
|
||||||
use pathfinder_gpu::{StencilState, UniformData};
|
use pathfinder_gpu::{StencilFunc, StencilState, TextureFormat, UniformData};
|
||||||
use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder};
|
use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder};
|
||||||
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, RenderMode, RenderStats, Renderer};
|
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, RenderMode, RenderStats, Renderer};
|
||||||
use pathfinder_renderer::gpu_data::RenderCommand;
|
use pathfinder_renderer::gpu_data::RenderCommand;
|
||||||
|
@ -37,7 +36,6 @@ use std::f32::consts::FRAC_PI_4;
|
||||||
use std::fmt::{Debug, Formatter, Result as DebugResult};
|
use std::fmt::{Debug, Formatter, Result as DebugResult};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::iter;
|
|
||||||
use std::panic::{self, AssertUnwindSafe};
|
use std::panic::{self, AssertUnwindSafe};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
@ -72,6 +70,9 @@ const MESSAGE_TIMEOUT_SECS: u64 = 5;
|
||||||
|
|
||||||
const MAX_MESSAGES_IN_FLIGHT: usize = 256;
|
const MAX_MESSAGES_IN_FLIGHT: usize = 256;
|
||||||
|
|
||||||
|
// Half of the eye separation distance.
|
||||||
|
const DEFAULT_EYE_OFFSET: f32 = 0.025;
|
||||||
|
|
||||||
pub const GRIDLINE_COUNT: u8 = 10;
|
pub const GRIDLINE_COUNT: u8 = 10;
|
||||||
|
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
@ -104,6 +105,8 @@ pub struct DemoApp<W> where W: Window {
|
||||||
scene_thread_proxy: SceneThreadProxy,
|
scene_thread_proxy: SceneThreadProxy,
|
||||||
renderer: Renderer<GLDevice>,
|
renderer: Renderer<GLDevice>,
|
||||||
|
|
||||||
|
scene_framebuffer: Option<<GLDevice as Device>::Framebuffer>,
|
||||||
|
|
||||||
ground_program: GroundProgram<GLDevice>,
|
ground_program: GroundProgram<GLDevice>,
|
||||||
ground_solid_vertex_array: GroundSolidVertexArray<GLDevice>,
|
ground_solid_vertex_array: GroundSolidVertexArray<GLDevice>,
|
||||||
ground_line_vertex_array: GroundLineVertexArray<GLDevice>,
|
ground_line_vertex_array: GroundLineVertexArray<GLDevice>,
|
||||||
|
@ -178,6 +181,8 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
scene_thread_proxy,
|
scene_thread_proxy,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
||||||
|
scene_framebuffer: None,
|
||||||
|
|
||||||
ground_program,
|
ground_program,
|
||||||
ground_solid_vertex_array,
|
ground_solid_vertex_array,
|
||||||
ground_line_vertex_array,
|
ground_line_vertex_array,
|
||||||
|
@ -195,61 +200,96 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
self.build_scene();
|
self.build_scene();
|
||||||
|
|
||||||
// Get the render message, and determine how many scenes it contains.
|
// Get the render message, and determine how many scenes it contains.
|
||||||
let transforms = match self.scene_thread_proxy.receiver.recv().unwrap() {
|
let transform = match self.scene_thread_proxy.receiver.recv().unwrap() {
|
||||||
SceneToMainMsg::BeginFrame { transforms } => transforms,
|
SceneToMainMsg::BeginFrame { transform } => transform,
|
||||||
msg => panic!("Expected BeginFrame message, found {:?}!", msg),
|
msg => panic!("Expected BeginFrame message, found {:?}!", msg),
|
||||||
};
|
};
|
||||||
let render_scene_count = transforms.len() as u32;
|
|
||||||
|
|
||||||
// Save the frame.
|
// Save the frame.
|
||||||
self.current_frame = Some(Frame::new(transforms, ui_events));
|
self.current_frame = Some(Frame::new(transform, ui_events));
|
||||||
|
|
||||||
|
// Initialize and set the appropriate framebuffer.
|
||||||
|
let view = self.ui.mode.view(0);
|
||||||
|
self.window.make_current(view);
|
||||||
|
let window_size = self.window_size.device_size();
|
||||||
|
let scene_count = match self.camera.mode() {
|
||||||
|
Mode::VR => {
|
||||||
|
let viewport = self.window.viewport(View::Stereo(0));
|
||||||
|
if self.scene_framebuffer.is_none() ||
|
||||||
|
self.renderer
|
||||||
|
.device
|
||||||
|
.texture_size(&self.renderer
|
||||||
|
.device
|
||||||
|
.framebuffer_texture(self.scene_framebuffer
|
||||||
|
.as_ref()
|
||||||
|
.unwrap())) !=
|
||||||
|
viewport.size() {
|
||||||
|
let scene_texture = self.renderer.device.create_texture(TextureFormat::RGBA8,
|
||||||
|
viewport.size());
|
||||||
|
self.scene_framebuffer =
|
||||||
|
Some(self.renderer.device.create_framebuffer(scene_texture));
|
||||||
|
}
|
||||||
|
self.renderer
|
||||||
|
.replace_dest_framebuffer(DestFramebuffer::Other(self.scene_framebuffer
|
||||||
|
.take()
|
||||||
|
.unwrap()));
|
||||||
|
2
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||||
|
viewport: self.window.viewport(View::Mono),
|
||||||
|
window_size,
|
||||||
|
});
|
||||||
|
1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Begin drawing the scene.
|
// Begin drawing the scene.
|
||||||
for render_scene_index in 0..render_scene_count {
|
self.renderer.bind_dest_framebuffer();
|
||||||
let view = self.ui.mode.view(render_scene_index);
|
|
||||||
let viewport = self.window.viewport(view);
|
|
||||||
self.window.make_current(view);
|
|
||||||
self.renderer.set_dest_framebuffer(DestFramebuffer::Default {
|
|
||||||
viewport,
|
|
||||||
window_size: self.window_size.device_size(),
|
|
||||||
});
|
|
||||||
self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
render_scene_count
|
// Clear to the appropriate color.
|
||||||
|
let clear_color = if scene_count == 2 {
|
||||||
|
ColorF::transparent_black()
|
||||||
|
} else {
|
||||||
|
self.background_color().to_f32()
|
||||||
|
};
|
||||||
|
self.renderer.device.clear(&ClearParams {
|
||||||
|
color: Some(clear_color),
|
||||||
|
depth: Some(1.0),
|
||||||
|
stencil: Some(0),
|
||||||
|
..ClearParams::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
scene_count
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_scene(&mut self) {
|
fn build_scene(&mut self) {
|
||||||
let render_transforms = match self.camera {
|
let render_transform = match self.camera {
|
||||||
Camera::ThreeD { ref transforms, ref mut transform, ref mut velocity, .. } => {
|
Camera::ThreeD {
|
||||||
if transform.offset(*velocity) {
|
ref scene_transform,
|
||||||
|
ref mut modelview_transform,
|
||||||
|
ref mut velocity,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
if modelview_transform.offset(*velocity) {
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
transforms.iter()
|
let perspective = scene_transform.perspective
|
||||||
.map(|tr| {
|
.post_mul(&scene_transform.modelview_to_eye)
|
||||||
let perspective = tr.perspective
|
.post_mul(&modelview_transform.to_transform());
|
||||||
.post_mul(&tr.view)
|
|
||||||
.post_mul(&transform.to_transform());
|
|
||||||
RenderTransform::Perspective(perspective)
|
RenderTransform::Perspective(perspective)
|
||||||
}).collect()
|
|
||||||
}
|
}
|
||||||
Camera::TwoD(transform) => vec![RenderTransform::Transform2D(transform)],
|
Camera::TwoD(transform) => RenderTransform::Transform2D(transform),
|
||||||
};
|
|
||||||
|
|
||||||
let barrel_distortion = match self.ui.mode {
|
|
||||||
Mode::VR => Some(self.window.barrel_distortion_coefficients()),
|
|
||||||
_ => None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.scene_thread_proxy.sender.send(MainToSceneMsg::Build(BuildOptions {
|
self.scene_thread_proxy.sender.send(MainToSceneMsg::Build(BuildOptions {
|
||||||
render_transforms,
|
render_transform,
|
||||||
stem_darkening_font_size: if self.ui.stem_darkening_effect_enabled {
|
stem_darkening_font_size: if self.ui.stem_darkening_effect_enabled {
|
||||||
Some(APPROX_FONT_SIZE * self.window_size.backing_scale_factor)
|
Some(APPROX_FONT_SIZE * self.window_size.backing_scale_factor)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
subpixel_aa_enabled: self.ui.subpixel_aa_effect_enabled,
|
subpixel_aa_enabled: self.ui.subpixel_aa_effect_enabled,
|
||||||
barrel_distortion,
|
|
||||||
})).unwrap();
|
})).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,12 +317,12 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
Event::MouseMoved(new_position) if self.mouselook_enabled => {
|
Event::MouseMoved(new_position) if self.mouselook_enabled => {
|
||||||
let mouse_position = self.process_mouse_position(new_position);
|
let mouse_position = self.process_mouse_position(new_position);
|
||||||
if let Camera::ThreeD { ref mut transform, .. } = self.camera {
|
if let Camera::ThreeD { ref mut modelview_transform, .. } = self.camera {
|
||||||
let rotation = mouse_position.relative
|
let rotation = mouse_position.relative
|
||||||
.to_f32()
|
.to_f32()
|
||||||
.scale(MOUSELOOK_ROTATION_SPEED);
|
.scale(MOUSELOOK_ROTATION_SPEED);
|
||||||
transform.yaw += rotation.x();
|
modelview_transform.yaw += rotation.x();
|
||||||
transform.pitch += rotation.y();
|
modelview_transform.pitch += rotation.y();
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,14 +342,14 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Look { pitch, yaw } => {
|
Event::Look { pitch, yaw } => {
|
||||||
if let Camera::ThreeD { ref mut transform, .. } = self.camera {
|
if let Camera::ThreeD { ref mut modelview_transform, .. } = self.camera {
|
||||||
transform.pitch += pitch;
|
modelview_transform.pitch += pitch;
|
||||||
transform.yaw += yaw;
|
modelview_transform.yaw += yaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::CameraTransforms(new_transforms) => {
|
Event::SetEyeTransforms(new_eye_transforms) => {
|
||||||
if let Camera::ThreeD { ref mut transforms, .. } = self.camera {
|
if let Camera::ThreeD { ref mut eye_transforms, .. } = self.camera {
|
||||||
*transforms = new_transforms;
|
*eye_transforms = new_eye_transforms;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::KeyDown(Keycode::Alphanumeric(b'w')) => {
|
Event::KeyDown(Keycode::Alphanumeric(b'w')) => {
|
||||||
|
@ -392,23 +432,101 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
MousePosition { absolute, relative }
|
MousePosition { absolute, relative }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_scene(&mut self, render_scene_index: u32) {
|
pub fn draw_scene(&mut self) {
|
||||||
let view = self.ui.mode.view(render_scene_index);
|
let view = self.ui.mode.view(0);
|
||||||
let viewport = self.window.viewport(view);
|
|
||||||
self.window.make_current(view);
|
self.window.make_current(view);
|
||||||
self.renderer.set_dest_framebuffer(DestFramebuffer::Default {
|
|
||||||
|
if self.camera.mode() != Mode::VR {
|
||||||
|
self.draw_environment(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.render_vector_scene();
|
||||||
|
|
||||||
|
// Reattach default framebuffer.
|
||||||
|
if self.camera.mode() != Mode::VR {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let DestFramebuffer::Other(scene_framebuffer) =
|
||||||
|
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||||
|
viewport: self.window.viewport(View::Mono),
|
||||||
|
window_size: self.window_size.device_size(),
|
||||||
|
}) {
|
||||||
|
self.scene_framebuffer = Some(scene_framebuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn composite_scene(&mut self, render_scene_index: u32) {
|
||||||
|
let (eye_transforms, scene_transform, modelview_transform) = match self.camera {
|
||||||
|
Camera::ThreeD {
|
||||||
|
ref eye_transforms,
|
||||||
|
ref scene_transform,
|
||||||
|
ref modelview_transform,
|
||||||
|
..
|
||||||
|
} if eye_transforms.len() > 1 => {
|
||||||
|
(eye_transforms, scene_transform, modelview_transform)
|
||||||
|
}
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
println!("scene_transform.perspective={:?}", scene_transform.perspective);
|
||||||
|
println!("scene_transform.modelview_to_eye={:?}", scene_transform.modelview_to_eye);
|
||||||
|
println!("modelview transform={:?}", modelview_transform);
|
||||||
|
*/
|
||||||
|
|
||||||
|
let viewport = self.window.viewport(View::Stereo(render_scene_index));
|
||||||
|
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||||
viewport,
|
viewport,
|
||||||
window_size: self.window_size.device_size(),
|
window_size: self.window_size.device_size(),
|
||||||
});
|
});
|
||||||
self.draw_environment(render_scene_index);
|
|
||||||
self.render_vector_scene();
|
|
||||||
|
|
||||||
if let Some(rendering_time) = self.renderer.shift_timer_query() {
|
self.renderer.bind_draw_framebuffer();
|
||||||
self.current_frame.as_mut().unwrap().scene_rendering_times.push(rendering_time)
|
self.renderer.device.clear(&ClearParams {
|
||||||
}
|
color: Some(self.background_color().to_f32()),
|
||||||
|
depth: Some(1.0),
|
||||||
|
stencil: Some(0),
|
||||||
|
rect: Some(viewport),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.draw_environment(render_scene_index);
|
||||||
|
|
||||||
|
let scene_framebuffer = self.scene_framebuffer.as_ref().unwrap();
|
||||||
|
let scene_texture = self.renderer.device.framebuffer_texture(scene_framebuffer);
|
||||||
|
|
||||||
|
let quad_scale_transform = Transform3DF32::from_scale(self.scene_view_box.size().x(),
|
||||||
|
self.scene_view_box.size().y(),
|
||||||
|
1.0);
|
||||||
|
|
||||||
|
let scene_transform_matrix = scene_transform.perspective
|
||||||
|
.post_mul(&scene_transform.modelview_to_eye)
|
||||||
|
.post_mul(&modelview_transform.to_transform())
|
||||||
|
.post_mul(&quad_scale_transform);
|
||||||
|
|
||||||
|
let eye_transform = &eye_transforms[render_scene_index as usize];
|
||||||
|
let eye_transform_matrix = eye_transform.perspective
|
||||||
|
.post_mul(&eye_transform.modelview_to_eye)
|
||||||
|
.post_mul(&modelview_transform.to_transform())
|
||||||
|
.post_mul(&quad_scale_transform);
|
||||||
|
|
||||||
|
/*
|
||||||
|
println!("eye transform({}).modelview_to_eye={:?}",
|
||||||
|
render_scene_index,
|
||||||
|
eye_transform.modelview_to_eye);
|
||||||
|
println!("eye transform_matrix({})={:?}", render_scene_index, eye_transform_matrix);
|
||||||
|
println!("---");
|
||||||
|
*/
|
||||||
|
|
||||||
|
self.renderer.reproject_texture(scene_texture,
|
||||||
|
&scene_transform_matrix.transform,
|
||||||
|
&eye_transform_matrix.transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish_drawing_frame(&mut self) {
|
pub fn finish_drawing_frame(&mut self) {
|
||||||
|
if let Some(rendering_time) = self.renderer.shift_timer_query() {
|
||||||
|
self.current_frame.as_mut().unwrap().scene_rendering_times.push(rendering_time);
|
||||||
|
}
|
||||||
|
|
||||||
let tile_time = match self.scene_thread_proxy.receiver.recv().unwrap() {
|
let tile_time = match self.scene_thread_proxy.receiver.recv().unwrap() {
|
||||||
SceneToMainMsg::EndFrame { tile_time } => tile_time,
|
SceneToMainMsg::EndFrame { tile_time } => tile_time,
|
||||||
_ => panic!("Expected `EndFrame`!"),
|
_ => panic!("Expected `EndFrame`!"),
|
||||||
|
@ -435,7 +553,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
if self.options.ui != UIVisibility::None {
|
if self.options.ui != UIVisibility::None {
|
||||||
let viewport = self.window.viewport(View::Mono);
|
let viewport = self.window.viewport(View::Mono);
|
||||||
self.window.make_current(View::Mono);
|
self.window.make_current(View::Mono);
|
||||||
self.renderer.set_dest_framebuffer(DestFramebuffer::Default {
|
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||||
viewport,
|
viewport,
|
||||||
window_size: self.window_size.device_size(),
|
window_size: self.window_size.device_size(),
|
||||||
});
|
});
|
||||||
|
@ -489,10 +607,11 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_environment(&self, viewport_index: u32) {
|
fn draw_environment(&self, viewport_index: u32) {
|
||||||
let frame = &self.current_frame.as_ref().unwrap();
|
// TODO(pcwalton): Use the viewport index!
|
||||||
let render_transform = &frame.transforms[viewport_index as usize].clone();
|
|
||||||
|
|
||||||
let perspective = match *render_transform {
|
let frame = &self.current_frame.as_ref().unwrap();
|
||||||
|
|
||||||
|
let perspective = match frame.transform {
|
||||||
RenderTransform::Transform2D(..) => return,
|
RenderTransform::Transform2D(..) => return,
|
||||||
RenderTransform::Perspective(perspective) => perspective,
|
RenderTransform::Perspective(perspective) => perspective,
|
||||||
};
|
};
|
||||||
|
@ -542,12 +661,8 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
transform.post_mul(&Transform3DF32::from_scale(ground_scale, 1.0, ground_scale));
|
transform.post_mul(&Transform3DF32::from_scale(ground_scale, 1.0, ground_scale));
|
||||||
device.bind_vertex_array(&self.ground_solid_vertex_array.vertex_array);
|
device.bind_vertex_array(&self.ground_solid_vertex_array.vertex_array);
|
||||||
device.use_program(&self.ground_program.program);
|
device.use_program(&self.ground_program.program);
|
||||||
device.set_uniform(&self.ground_program.transform_uniform, UniformData::Mat4([
|
device.set_uniform(&self.ground_program.transform_uniform,
|
||||||
transform.c0,
|
UniformData::from_transform_3d(&transform));
|
||||||
transform.c1,
|
|
||||||
transform.c2,
|
|
||||||
transform.c3,
|
|
||||||
]));
|
|
||||||
device.set_uniform(&self.ground_program.color_uniform,
|
device.set_uniform(&self.ground_program.color_uniform,
|
||||||
UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0));
|
UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0));
|
||||||
device.draw_arrays(Primitive::TriangleFan, 4, &RenderState {
|
device.draw_arrays(Primitive::TriangleFan, 4, &RenderState {
|
||||||
|
@ -716,16 +831,10 @@ impl SceneThread {
|
||||||
}
|
}
|
||||||
MainToSceneMsg::Build(build_options) => {
|
MainToSceneMsg::Build(build_options) => {
|
||||||
self.sender.send(SceneToMainMsg::BeginFrame {
|
self.sender.send(SceneToMainMsg::BeginFrame {
|
||||||
transforms: build_options.render_transforms.clone(),
|
transform: build_options.render_transform.clone(),
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
for render_transform in &build_options.render_transforms {
|
build_scene(&self.scene, &build_options, self.options.jobs, &mut self.sender);
|
||||||
build_scene(&self.scene,
|
|
||||||
&build_options,
|
|
||||||
(*render_transform).clone(),
|
|
||||||
self.options.jobs,
|
|
||||||
&mut self.sender);
|
|
||||||
}
|
|
||||||
let tile_time = Instant::now() - start_time;
|
let tile_time = Instant::now() - start_time;
|
||||||
self.sender.send(SceneToMainMsg::EndFrame { tile_time }).unwrap();
|
self.sender.send(SceneToMainMsg::EndFrame { tile_time }).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -743,14 +852,13 @@ enum MainToSceneMsg {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct BuildOptions {
|
struct BuildOptions {
|
||||||
render_transforms: Vec<RenderTransform>,
|
render_transform: RenderTransform,
|
||||||
stem_darkening_font_size: Option<f32>,
|
stem_darkening_font_size: Option<f32>,
|
||||||
barrel_distortion: Option<BarrelDistortionCoefficients>,
|
|
||||||
subpixel_aa_enabled: bool,
|
subpixel_aa_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SceneToMainMsg {
|
enum SceneToMainMsg {
|
||||||
BeginFrame { transforms: Vec<RenderTransform> },
|
BeginFrame { transform: RenderTransform },
|
||||||
EndFrame { tile_time: Duration },
|
EndFrame { tile_time: Duration },
|
||||||
BeginRenderScene(SceneDescriptor),
|
BeginRenderScene(SceneDescriptor),
|
||||||
Execute(RenderCommand),
|
Execute(RenderCommand),
|
||||||
|
@ -772,11 +880,10 @@ impl Debug for SceneToMainMsg {
|
||||||
|
|
||||||
fn build_scene(scene: &Scene,
|
fn build_scene(scene: &Scene,
|
||||||
build_options: &BuildOptions,
|
build_options: &BuildOptions,
|
||||||
render_transform: RenderTransform,
|
|
||||||
jobs: Option<usize>,
|
jobs: Option<usize>,
|
||||||
sink: &mut SyncSender<SceneToMainMsg>) {
|
sink: &mut SyncSender<SceneToMainMsg>) {
|
||||||
let render_options = RenderOptions {
|
let render_options = RenderOptions {
|
||||||
transform: render_transform.clone(),
|
transform: build_options.render_transform.clone(),
|
||||||
dilation: match build_options.stem_darkening_font_size {
|
dilation: match build_options.stem_darkening_font_size {
|
||||||
None => Point2DF32::default(),
|
None => Point2DF32::default(),
|
||||||
Some(font_size) => {
|
Some(font_size) => {
|
||||||
|
@ -784,7 +891,6 @@ fn build_scene(scene: &Scene,
|
||||||
Point2DF32::new(x, y).scale(font_size)
|
Point2DF32::new(x, y).scale(font_size)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
barrel_distortion: build_options.barrel_distortion,
|
|
||||||
subpixel_aa_enabled: build_options.subpixel_aa_enabled,
|
subpixel_aa_enabled: build_options.subpixel_aa_enabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -954,11 +1060,15 @@ fn center_of_window(window_size: &WindowSize) -> Point2DF32 {
|
||||||
enum Camera {
|
enum Camera {
|
||||||
TwoD(Transform2DF32),
|
TwoD(Transform2DF32),
|
||||||
ThreeD {
|
ThreeD {
|
||||||
// For each camera, the perspective from camera coordinates to display coordinates,
|
// The ocular transform used for rendering of the scene to the scene framebuffer. If we are
|
||||||
|
// performing stereoscopic rendering, this is then reprojected according to the eye
|
||||||
|
// transforms below.
|
||||||
|
scene_transform: OcularTransform,
|
||||||
|
// For each eye, the perspective from camera coordinates to display coordinates,
|
||||||
// and the view transform from world coordinates to camera coordinates.
|
// and the view transform from world coordinates to camera coordinates.
|
||||||
transforms: Vec<CameraTransform>,
|
eye_transforms: Vec<OcularTransform>,
|
||||||
// The model transform from world coordinates to SVG coordinates
|
// The modelview transform from world coordinates to SVG coordinates
|
||||||
transform: CameraTransform3D,
|
modelview_transform: CameraTransform3D,
|
||||||
// The camera's velocity (in world coordinates)
|
// The camera's velocity (in world coordinates)
|
||||||
velocity: Point3DF32,
|
velocity: Point3DF32,
|
||||||
},
|
},
|
||||||
|
@ -982,17 +1092,37 @@ impl Camera {
|
||||||
|
|
||||||
fn new_3d(mode: Mode, view_box: RectF32, viewport_size: Point2DI32) -> Camera {
|
fn new_3d(mode: Mode, view_box: RectF32, viewport_size: Point2DI32) -> Camera {
|
||||||
let viewport_count = mode.viewport_count();
|
let viewport_count = mode.viewport_count();
|
||||||
|
|
||||||
|
let fov_y = FRAC_PI_4;
|
||||||
let aspect = viewport_size.x() as f32 / viewport_size.y() as f32;
|
let aspect = viewport_size.x() as f32 / viewport_size.y() as f32;
|
||||||
let projection = Transform3DF32::from_perspective(FRAC_PI_4, aspect, NEAR_CLIP_PLANE, FAR_CLIP_PLANE);
|
let projection = Transform3DF32::from_perspective(fov_y,
|
||||||
let transform = CameraTransform {
|
aspect,
|
||||||
perspective: Perspective::new(&projection, viewport_size),
|
NEAR_CLIP_PLANE,
|
||||||
view: Transform3DF32::default(),
|
FAR_CLIP_PLANE);
|
||||||
|
let perspective = Perspective::new(&projection, viewport_size);
|
||||||
|
|
||||||
|
// Create a scene transform by moving the camera back from the center of the eyes so that
|
||||||
|
// its field of view encompasses the field of view of both eyes.
|
||||||
|
let z_offset = -DEFAULT_EYE_OFFSET * projection.c0.x();
|
||||||
|
let scene_transform = OcularTransform {
|
||||||
|
perspective,
|
||||||
|
modelview_to_eye: Transform3DF32::from_translation(0.0, 0.0, z_offset),
|
||||||
};
|
};
|
||||||
let transforms = iter::repeat(transform).take(viewport_count).collect();
|
|
||||||
|
// For now, initialize the eye transforms as copies of the scene transform.
|
||||||
|
let eye_offset = DEFAULT_EYE_OFFSET;
|
||||||
|
let eye_transforms = (0..viewport_count).map(|viewport_index| {
|
||||||
|
let this_eye_offset = if viewport_index == 0 { eye_offset } else { -eye_offset };
|
||||||
|
OcularTransform {
|
||||||
|
perspective,
|
||||||
|
modelview_to_eye: Transform3DF32::from_translation(this_eye_offset, 0.0, 0.0),
|
||||||
|
}
|
||||||
|
}).collect();
|
||||||
|
|
||||||
Camera::ThreeD {
|
Camera::ThreeD {
|
||||||
transforms,
|
scene_transform,
|
||||||
transform: CameraTransform3D::new(view_box),
|
eye_transforms,
|
||||||
|
modelview_transform: CameraTransform3D::new(view_box),
|
||||||
velocity: Point3DF32::default(),
|
velocity: Point3DF32::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1003,14 +1133,14 @@ impl Camera {
|
||||||
|
|
||||||
fn mode(&self) -> Mode {
|
fn mode(&self) -> Mode {
|
||||||
match *self {
|
match *self {
|
||||||
Camera::ThreeD { ref transforms, .. } if 2 <= transforms.len() => Mode::VR,
|
Camera::ThreeD { ref eye_transforms, .. } if eye_transforms.len() >= 2 => Mode::VR,
|
||||||
Camera::ThreeD { .. } => Mode::ThreeD,
|
Camera::ThreeD { .. } => Mode::ThreeD,
|
||||||
Camera::TwoD { .. } => Mode::TwoD,
|
Camera::TwoD { .. } => Mode::TwoD,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct CameraTransform3D {
|
struct CameraTransform3D {
|
||||||
position: Point3DF32,
|
position: Point3DF32,
|
||||||
yaw: f32,
|
yaw: f32,
|
||||||
|
@ -1089,15 +1219,15 @@ fn emit_message<W>(ui: &mut DemoUI<GLDevice>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Frame {
|
struct Frame {
|
||||||
transforms: Vec<RenderTransform>,
|
transform: RenderTransform,
|
||||||
ui_events: Vec<UIEvent>,
|
ui_events: Vec<UIEvent>,
|
||||||
scene_rendering_times: Vec<Duration>,
|
scene_rendering_times: Vec<Duration>,
|
||||||
scene_stats: Vec<RenderStats>,
|
scene_stats: Vec<RenderStats>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Frame {
|
impl Frame {
|
||||||
fn new(transforms: Vec<RenderTransform>, ui_events: Vec<UIEvent>) -> Frame {
|
fn new(transform: RenderTransform, ui_events: Vec<UIEvent>) -> Frame {
|
||||||
Frame { transforms, ui_events, scene_rendering_times: vec![], scene_stats: vec![] }
|
Frame { transform, ui_events, scene_rendering_times: vec![], scene_stats: vec![] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub enum Event {
|
||||||
MouseDragged(Point2DI32),
|
MouseDragged(Point2DI32),
|
||||||
Zoom(f32),
|
Zoom(f32),
|
||||||
Look { pitch: f32, yaw: f32 },
|
Look { pitch: f32, yaw: f32 },
|
||||||
CameraTransforms(Vec<CameraTransform>),
|
SetEyeTransforms(Vec<OcularTransform>),
|
||||||
OpenSVG(SVGPath),
|
OpenSVG(SVGPath),
|
||||||
User { message_type: u32, message_data: u32 },
|
User { message_type: u32, message_data: u32 },
|
||||||
}
|
}
|
||||||
|
@ -85,12 +85,12 @@ pub enum View {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct CameraTransform {
|
pub struct OcularTransform {
|
||||||
// The perspective which converts from camera coordinates to display coordinates
|
// The perspective which converts from camera coordinates to display coordinates
|
||||||
pub perspective: Perspective,
|
pub perspective: Perspective,
|
||||||
|
|
||||||
// The view transform which converts from world coordinates to camera coordinates
|
// The view transform which converts from world coordinates to camera coordinates
|
||||||
pub view: Transform3DF32,
|
pub modelview_to_eye: Transform3DF32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
|
@ -8,6 +8,7 @@ authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
||||||
pf-no-simd = ["pathfinder_simd/pf-no-simd"]
|
pf-no-simd = ["pathfinder_simd/pf-no-simd"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
color-backtrace = "0.1"
|
||||||
gl = "0.6"
|
gl = "0.6"
|
||||||
jemallocator = "0.1"
|
jemallocator = "0.1"
|
||||||
nfd = "0.0.4"
|
nfd = "0.0.4"
|
||||||
|
|
|
@ -34,6 +34,8 @@ const DEFAULT_WINDOW_WIDTH: u32 = 1067;
|
||||||
const DEFAULT_WINDOW_HEIGHT: u32 = 800;
|
const DEFAULT_WINDOW_HEIGHT: u32 = 800;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
color_backtrace::install();
|
||||||
|
|
||||||
let window = WindowImpl::new();
|
let window = WindowImpl::new();
|
||||||
let window_size = window.size();
|
let window_size = window.size();
|
||||||
let options = Options::default();
|
let options = Options::default();
|
||||||
|
@ -49,8 +51,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let scene_count = app.prepare_frame(events);
|
let scene_count = app.prepare_frame(events);
|
||||||
|
app.draw_scene();
|
||||||
for scene_index in 0..scene_count {
|
for scene_index in 0..scene_count {
|
||||||
app.draw_scene(scene_index);
|
app.composite_scene(scene_index);
|
||||||
}
|
}
|
||||||
app.finish_drawing_frame();
|
app.finish_drawing_frame();
|
||||||
}
|
}
|
||||||
|
@ -91,10 +94,7 @@ impl Window for WindowImpl {
|
||||||
width = width / 2;
|
width = width / 2;
|
||||||
x_offset = width * (index as i32);
|
x_offset = width * (index as i32);
|
||||||
}
|
}
|
||||||
RectI32::new (
|
RectI32::new(Point2DI32::new(x_offset, 0), Point2DI32::new(width, height))
|
||||||
Point2DI32::new(x_offset, 0),
|
|
||||||
Point2DI32::new(width, height),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_current(&mut self, _view: View) {
|
fn make_current(&mut self, _view: View) {
|
||||||
|
|
|
@ -56,6 +56,11 @@ impl Debug for ColorU {
|
||||||
pub struct ColorF(pub F32x4);
|
pub struct ColorF(pub F32x4);
|
||||||
|
|
||||||
impl ColorF {
|
impl ColorF {
|
||||||
|
#[inline]
|
||||||
|
pub fn transparent_black() -> ColorF {
|
||||||
|
ColorF(F32x4::default())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn r(&self) -> f32 {
|
pub fn r(&self) -> f32 {
|
||||||
self.0[0]
|
self.0[0]
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
||||||
use pathfinder_geometry::basic::point::Point2DI32;
|
use pathfinder_geometry::basic::point::Point2DI32;
|
||||||
use pathfinder_geometry::basic::rect::RectI32;
|
use pathfinder_geometry::basic::rect::RectI32;
|
||||||
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, DepthFunc, Device};
|
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, ClearParams};
|
||||||
use pathfinder_gpu::{Primitive, RenderState, ShaderKind, StencilFunc, TextureFormat};
|
use pathfinder_gpu::{DepthFunc, Device, Primitive, RenderState, ShaderKind, StencilFunc};
|
||||||
use pathfinder_gpu::{UniformData, VertexAttrType};
|
use pathfinder_gpu::{TextureFormat, UniformData, VertexAttrType};
|
||||||
use pathfinder_simd::default::F32x4;
|
use pathfinder_simd::default::F32x4;
|
||||||
use rustache::{HashBuilder, Render};
|
use rustache::{HashBuilder, Render};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
@ -367,6 +367,14 @@ impl Device for GLDevice {
|
||||||
UniformData::Int(value) => {
|
UniformData::Int(value) => {
|
||||||
gl::Uniform1i(uniform.location, value); ck();
|
gl::Uniform1i(uniform.location, value); ck();
|
||||||
}
|
}
|
||||||
|
UniformData::Mat2(data) => {
|
||||||
|
assert_eq!(mem::size_of::<F32x4>(), 4 * 4);
|
||||||
|
let data_ptr: *const F32x4 = &data;
|
||||||
|
gl::UniformMatrix2fv(uniform.location,
|
||||||
|
1,
|
||||||
|
gl::FALSE,
|
||||||
|
data_ptr as *const GLfloat);
|
||||||
|
}
|
||||||
UniformData::Mat4(data) => {
|
UniformData::Mat4(data) => {
|
||||||
assert_eq!(mem::size_of::<[F32x4; 4]>(), 4 * 4 * 4);
|
assert_eq!(mem::size_of::<[F32x4; 4]>(), 4 * 4 * 4);
|
||||||
let data_ptr: *const F32x4 = data.as_ptr();
|
let data_ptr: *const F32x4 = data.as_ptr();
|
||||||
|
@ -487,21 +495,26 @@ impl Device for GLDevice {
|
||||||
pixels
|
pixels
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(pcwalton): Switch to `ColorF`!
|
fn clear(&self, params: &ClearParams) {
|
||||||
fn clear(&self, color: Option<F32x4>, depth: Option<f32>, stencil: Option<u8>) {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
if let Some(rect) = params.rect {
|
||||||
|
let (origin, size) = (rect.origin(), rect.size());
|
||||||
|
gl::Scissor(origin.x(), origin.y(), size.x(), size.y()); ck();
|
||||||
|
gl::Enable(gl::SCISSOR_TEST); ck();
|
||||||
|
}
|
||||||
|
|
||||||
let mut flags = 0;
|
let mut flags = 0;
|
||||||
if let Some(color) = color {
|
if let Some(color) = params.color {
|
||||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); ck();
|
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE); ck();
|
||||||
gl::ClearColor(color.x(), color.y(), color.z(), color.w()); ck();
|
gl::ClearColor(color.r(), color.g(), color.b(), color.a()); ck();
|
||||||
flags |= gl::COLOR_BUFFER_BIT;
|
flags |= gl::COLOR_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
if let Some(depth) = depth {
|
if let Some(depth) = params.depth {
|
||||||
gl::DepthMask(gl::TRUE); ck();
|
gl::DepthMask(gl::TRUE); ck();
|
||||||
gl::ClearDepthf(depth as _); ck(); // FIXME(pcwalton): GLES
|
gl::ClearDepthf(depth as _); ck(); // FIXME(pcwalton): GLES
|
||||||
flags |= gl::DEPTH_BUFFER_BIT;
|
flags |= gl::DEPTH_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
if let Some(stencil) = stencil {
|
if let Some(stencil) = params.stencil {
|
||||||
gl::StencilMask(!0); ck();
|
gl::StencilMask(!0); ck();
|
||||||
gl::ClearStencil(stencil as GLint); ck();
|
gl::ClearStencil(stencil as GLint); ck();
|
||||||
flags |= gl::STENCIL_BUFFER_BIT;
|
flags |= gl::STENCIL_BUFFER_BIT;
|
||||||
|
@ -509,6 +522,10 @@ impl Device for GLDevice {
|
||||||
if flags != 0 {
|
if flags != 0 {
|
||||||
gl::Clear(flags); ck();
|
gl::Clear(flags); ck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if params.rect.is_some() {
|
||||||
|
gl::Disable(gl::SCISSOR_TEST); ck();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ use crate::resources::ResourceLoader;
|
||||||
use image::ImageFormat;
|
use image::ImageFormat;
|
||||||
use pathfinder_geometry::basic::point::Point2DI32;
|
use pathfinder_geometry::basic::point::Point2DI32;
|
||||||
use pathfinder_geometry::basic::rect::RectI32;
|
use pathfinder_geometry::basic::rect::RectI32;
|
||||||
|
use pathfinder_geometry::basic::transform3d::Transform3DF32;
|
||||||
|
use pathfinder_geometry::color::ColorF;
|
||||||
use pathfinder_simd::default::F32x4;
|
use pathfinder_simd::default::F32x4;
|
||||||
use rustache::HashBuilder;
|
use rustache::HashBuilder;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -75,8 +77,7 @@ pub trait Device {
|
||||||
fn texture_size(&self, texture: &Self::Texture) -> Point2DI32;
|
fn texture_size(&self, texture: &Self::Texture) -> Point2DI32;
|
||||||
fn upload_to_texture(&self, texture: &Self::Texture, size: Point2DI32, data: &[u8]);
|
fn upload_to_texture(&self, texture: &Self::Texture, size: Point2DI32, data: &[u8]);
|
||||||
fn read_pixels_from_default_framebuffer(&self, size: Point2DI32) -> Vec<u8>;
|
fn read_pixels_from_default_framebuffer(&self, size: Point2DI32) -> Vec<u8>;
|
||||||
// TODO(pcwalton): Switch to `ColorF`!
|
fn clear(&self, params: &ClearParams);
|
||||||
fn clear(&self, color: Option<F32x4>, depth: Option<f32>, stencil: Option<u8>);
|
|
||||||
fn draw_arrays(&self, primitive: Primitive, index_count: u32, render_state: &RenderState);
|
fn draw_arrays(&self, primitive: Primitive, index_count: u32, render_state: &RenderState);
|
||||||
fn draw_elements(&self, primitive: Primitive, index_count: u32, render_state: &RenderState);
|
fn draw_elements(&self, primitive: Primitive, index_count: u32, render_state: &RenderState);
|
||||||
fn draw_arrays_instanced(&self,
|
fn draw_arrays_instanced(&self,
|
||||||
|
@ -199,6 +200,7 @@ pub enum ShaderKind {
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum UniformData {
|
pub enum UniformData {
|
||||||
Int(i32),
|
Int(i32),
|
||||||
|
Mat2(F32x4),
|
||||||
Mat4([F32x4; 4]),
|
Mat4([F32x4; 4]),
|
||||||
Vec2(F32x4),
|
Vec2(F32x4),
|
||||||
Vec4(F32x4),
|
Vec4(F32x4),
|
||||||
|
@ -212,6 +214,14 @@ pub enum Primitive {
|
||||||
Lines,
|
Lines,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Default)]
|
||||||
|
pub struct ClearParams {
|
||||||
|
pub color: Option<ColorF>,
|
||||||
|
pub rect: Option<RectI32>,
|
||||||
|
pub depth: Option<f32>,
|
||||||
|
pub stencil: Option<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RenderState {
|
pub struct RenderState {
|
||||||
pub blend: BlendState,
|
pub blend: BlendState,
|
||||||
|
@ -290,6 +300,13 @@ impl Default for StencilFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UniformData {
|
||||||
|
#[inline]
|
||||||
|
pub fn from_transform_3d(transform: &Transform3DF32) -> UniformData {
|
||||||
|
UniformData::Mat4([transform.c0, transform.c1, transform.c2, transform.c3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn load_shader_include(resources: &dyn ResourceLoader, include_name: &str) -> String {
|
fn load_shader_include(resources: &dyn ResourceLoader, include_name: &str) -> String {
|
||||||
let resource = resources.slurp(&format!("shaders/{}.inc.glsl", include_name)).unwrap();
|
let resource = resources.slurp(&format!("shaders/{}.inc.glsl", include_name)).unwrap();
|
||||||
String::from_utf8_lossy(&resource).to_string()
|
String::from_utf8_lossy(&resource).to_string()
|
||||||
|
|
|
@ -19,14 +19,10 @@ use pathfinder_geometry::basic::rect::RectF32;
|
||||||
use pathfinder_geometry::basic::transform2d::Transform2DF32;
|
use pathfinder_geometry::basic::transform2d::Transform2DF32;
|
||||||
use pathfinder_geometry::basic::transform3d::Perspective;
|
use pathfinder_geometry::basic::transform3d::Perspective;
|
||||||
use pathfinder_geometry::clip::PolygonClipper3D;
|
use pathfinder_geometry::clip::PolygonClipper3D;
|
||||||
use pathfinder_geometry::distortion::BarrelDistortionCoefficients;
|
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::u16;
|
use std::u16;
|
||||||
|
|
||||||
// Must be a power of two.
|
|
||||||
pub const MAX_FILLS_PER_BATCH: u32 = 0x1000;
|
|
||||||
|
|
||||||
pub trait RenderCommandListener: Send + Sync {
|
pub trait RenderCommandListener: Send + Sync {
|
||||||
fn send(&self, command: RenderCommand);
|
fn send(&self, command: RenderCommand);
|
||||||
}
|
}
|
||||||
|
@ -134,7 +130,6 @@ impl<'a> SceneBuilder<'a> {
|
||||||
pub struct RenderOptions {
|
pub struct RenderOptions {
|
||||||
pub transform: RenderTransform,
|
pub transform: RenderTransform,
|
||||||
pub dilation: Point2DF32,
|
pub dilation: Point2DF32,
|
||||||
pub barrel_distortion: Option<BarrelDistortionCoefficients>,
|
|
||||||
pub subpixel_aa_enabled: bool,
|
pub subpixel_aa_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +138,6 @@ impl RenderOptions {
|
||||||
PreparedRenderOptions {
|
PreparedRenderOptions {
|
||||||
transform: self.transform.prepare(bounds),
|
transform: self.transform.prepare(bounds),
|
||||||
dilation: self.dilation,
|
dilation: self.dilation,
|
||||||
barrel_distortion: self.barrel_distortion,
|
|
||||||
subpixel_aa_enabled: self.subpixel_aa_enabled,
|
subpixel_aa_enabled: self.subpixel_aa_enabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +207,6 @@ impl RenderTransform {
|
||||||
pub struct PreparedRenderOptions {
|
pub struct PreparedRenderOptions {
|
||||||
pub transform: PreparedRenderTransform,
|
pub transform: PreparedRenderTransform,
|
||||||
pub dilation: Point2DF32,
|
pub dilation: Point2DF32,
|
||||||
pub barrel_distortion: Option<BarrelDistortionCoefficients>,
|
|
||||||
pub subpixel_aa_enabled: bool,
|
pub subpixel_aa_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,16 @@ use crate::scene::{ObjectShader, SceneDescriptor};
|
||||||
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
||||||
use pathfinder_geometry::basic::point::{Point2DI32, Point3DF32};
|
use pathfinder_geometry::basic::point::{Point2DI32, Point3DF32};
|
||||||
use pathfinder_geometry::basic::rect::RectI32;
|
use pathfinder_geometry::basic::rect::RectI32;
|
||||||
|
use pathfinder_geometry::basic::transform3d::Transform3DF32;
|
||||||
use pathfinder_geometry::color::ColorF;
|
use pathfinder_geometry::color::ColorF;
|
||||||
use pathfinder_gpu::resources::ResourceLoader;
|
use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, DepthFunc};
|
use pathfinder_gpu::{BlendState, BufferData, BufferTarget, BufferUploadMode, ClearParams};
|
||||||
use pathfinder_gpu::{DepthState, Device, Primitive, RenderState, StencilFunc, StencilState};
|
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderState, StencilFunc};
|
||||||
use pathfinder_gpu::{TextureFormat, UniformData, VertexAttrType};
|
use pathfinder_gpu::{StencilState, TextureFormat, UniformData, VertexAttrType};
|
||||||
use pathfinder_simd::default::{F32x4, I32x4};
|
use pathfinder_simd::default::{F32x4, I32x4};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
use std::mem;
|
||||||
use std::ops::{Add, Div};
|
use std::ops::{Add, Div};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
@ -75,6 +77,10 @@ pub struct Renderer<D> where D: Device {
|
||||||
stencil_program: StencilProgram<D>,
|
stencil_program: StencilProgram<D>,
|
||||||
stencil_vertex_array: StencilVertexArray<D>,
|
stencil_vertex_array: StencilVertexArray<D>,
|
||||||
|
|
||||||
|
// Reprojection shader
|
||||||
|
reprojection_program: ReprojectionProgram<D>,
|
||||||
|
reprojection_vertex_array: ReprojectionVertexArray<D>,
|
||||||
|
|
||||||
// Rendering state
|
// Rendering state
|
||||||
mask_framebuffer_cleared: bool,
|
mask_framebuffer_cleared: bool,
|
||||||
buffered_fills: Vec<FillBatchPrimitive>,
|
buffered_fills: Vec<FillBatchPrimitive>,
|
||||||
|
@ -103,6 +109,7 @@ impl<D> Renderer<D> where D: Device {
|
||||||
|
|
||||||
let postprocess_program = PostprocessProgram::new(&device, resources);
|
let postprocess_program = PostprocessProgram::new(&device, resources);
|
||||||
let stencil_program = StencilProgram::new(&device, resources);
|
let stencil_program = StencilProgram::new(&device, resources);
|
||||||
|
let reprojection_program = ReprojectionProgram::new(&device, resources);
|
||||||
|
|
||||||
let area_lut_texture = device.create_texture_from_png(resources, "area-lut");
|
let area_lut_texture = device.create_texture_from_png(resources, "area-lut");
|
||||||
let gamma_lut_texture = device.create_texture_from_png(resources, "gamma-lut");
|
let gamma_lut_texture = device.create_texture_from_png(resources, "gamma-lut");
|
||||||
|
@ -136,6 +143,10 @@ impl<D> Renderer<D> where D: Device {
|
||||||
&postprocess_program,
|
&postprocess_program,
|
||||||
&quad_vertex_positions_buffer);
|
&quad_vertex_positions_buffer);
|
||||||
let stencil_vertex_array = StencilVertexArray::new(&device, &stencil_program);
|
let stencil_vertex_array = StencilVertexArray::new(&device, &stencil_program);
|
||||||
|
let reprojection_vertex_array =
|
||||||
|
ReprojectionVertexArray::new(&device,
|
||||||
|
&reprojection_program,
|
||||||
|
&quad_vertex_positions_buffer);
|
||||||
|
|
||||||
let mask_framebuffer_size = Point2DI32::new(MASK_FRAMEBUFFER_WIDTH,
|
let mask_framebuffer_size = Point2DI32::new(MASK_FRAMEBUFFER_WIDTH,
|
||||||
MASK_FRAMEBUFFER_HEIGHT);
|
MASK_FRAMEBUFFER_HEIGHT);
|
||||||
|
@ -176,6 +187,9 @@ impl<D> Renderer<D> where D: Device {
|
||||||
stencil_program,
|
stencil_program,
|
||||||
stencil_vertex_array,
|
stencil_vertex_array,
|
||||||
|
|
||||||
|
reprojection_program,
|
||||||
|
reprojection_vertex_array,
|
||||||
|
|
||||||
stats: RenderStats::default(),
|
stats: RenderStats::default(),
|
||||||
current_timer_query: None,
|
current_timer_query: None,
|
||||||
pending_timer_queries: VecDeque::new(),
|
pending_timer_queries: VecDeque::new(),
|
||||||
|
@ -240,7 +254,7 @@ impl<D> Renderer<D> where D: Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_debug_ui(&self) {
|
pub fn draw_debug_ui(&self) {
|
||||||
self.bind_main_framebuffer();
|
self.bind_dest_framebuffer();
|
||||||
self.debug_ui.draw(&self.device);
|
self.debug_ui.draw(&self.device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,8 +270,14 @@ impl<D> Renderer<D> where D: Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_dest_framebuffer(&mut self, new_dest_framebuffer: DestFramebuffer<D>) {
|
pub fn dest_framebuffer(&self) -> &DestFramebuffer<D> {
|
||||||
self.dest_framebuffer = new_dest_framebuffer;
|
&self.dest_framebuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn replace_dest_framebuffer(&mut self, new_dest_framebuffer: DestFramebuffer<D>)
|
||||||
|
-> DestFramebuffer<D> {
|
||||||
|
mem::replace(&mut self.dest_framebuffer, new_dest_framebuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -315,7 +335,10 @@ impl<D> Renderer<D> where D: Device {
|
||||||
self.device.bind_framebuffer(&self.mask_framebuffer);
|
self.device.bind_framebuffer(&self.mask_framebuffer);
|
||||||
|
|
||||||
// TODO(pcwalton): Only clear the appropriate portion?
|
// TODO(pcwalton): Only clear the appropriate portion?
|
||||||
self.device.clear(Some(F32x4::splat(0.0)), None, None);
|
self.device.clear(&ClearParams {
|
||||||
|
color: Some(ColorF::transparent_black()),
|
||||||
|
..ClearParams::default()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_fills(&mut self, mut fills: &[FillBatchPrimitive]) {
|
fn add_fills(&mut self, mut fills: &[FillBatchPrimitive]) {
|
||||||
|
@ -504,7 +527,7 @@ impl<D> Renderer<D> where D: Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.bind_main_framebuffer();
|
self.bind_dest_framebuffer();
|
||||||
|
|
||||||
self.device.bind_vertex_array(&self.postprocess_vertex_array.vertex_array);
|
self.device.bind_vertex_array(&self.postprocess_vertex_array.vertex_array);
|
||||||
self.device.use_program(&self.postprocess_program.program);
|
self.device.use_program(&self.postprocess_program.program);
|
||||||
|
@ -596,15 +619,37 @@ impl<D> Renderer<D> where D: Device {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_draw_framebuffer(&self) {
|
pub fn reproject_texture(&self,
|
||||||
|
texture: &D::Texture,
|
||||||
|
old_transform: &Transform3DF32,
|
||||||
|
new_transform: &Transform3DF32) {
|
||||||
|
self.bind_draw_framebuffer();
|
||||||
|
|
||||||
|
self.device.bind_vertex_array(&self.reprojection_vertex_array.vertex_array);
|
||||||
|
self.device.use_program(&self.reprojection_program.program);
|
||||||
|
self.device.set_uniform(&self.reprojection_program.old_transform_uniform,
|
||||||
|
UniformData::from_transform_3d(old_transform));
|
||||||
|
self.device.set_uniform(&self.reprojection_program.new_transform_uniform,
|
||||||
|
UniformData::from_transform_3d(new_transform));
|
||||||
|
self.device.bind_texture(texture, 0);
|
||||||
|
self.device.set_uniform(&self.reprojection_program.texture_uniform,
|
||||||
|
UniformData::TextureUnit(0));
|
||||||
|
self.device.draw_arrays(Primitive::TriangleFan, 4, &RenderState {
|
||||||
|
blend: BlendState::RGBSrcAlphaAlphaOneMinusSrcAlpha,
|
||||||
|
depth: Some(DepthState { func: DepthFunc::Less, write: false }),
|
||||||
|
..RenderState::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_draw_framebuffer(&self) {
|
||||||
if self.postprocessing_needed() {
|
if self.postprocessing_needed() {
|
||||||
self.device.bind_framebuffer(self.postprocess_source_framebuffer.as_ref().unwrap());
|
self.device.bind_framebuffer(self.postprocess_source_framebuffer.as_ref().unwrap());
|
||||||
} else {
|
} else {
|
||||||
self.bind_main_framebuffer();
|
self.bind_dest_framebuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_main_framebuffer(&self) {
|
pub fn bind_dest_framebuffer(&self) {
|
||||||
match self.dest_framebuffer {
|
match self.dest_framebuffer {
|
||||||
DestFramebuffer::Default { viewport, .. } => {
|
DestFramebuffer::Default { viewport, .. } => {
|
||||||
self.device.bind_default_framebuffer(viewport)
|
self.device.bind_default_framebuffer(viewport)
|
||||||
|
@ -634,7 +679,10 @@ impl<D> Renderer<D> where D: Device {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.device.bind_framebuffer(self.postprocess_source_framebuffer.as_ref().unwrap());
|
self.device.bind_framebuffer(self.postprocess_source_framebuffer.as_ref().unwrap());
|
||||||
self.device.clear(Some(F32x4::default()), None, None);
|
self.device.clear(&ClearParams {
|
||||||
|
color: Some(ColorF::transparent_black()),
|
||||||
|
..ClearParams::default()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn postprocessing_needed(&self) -> bool {
|
fn postprocessing_needed(&self) -> bool {
|
||||||
|
@ -1099,6 +1147,51 @@ impl<D> StencilVertexArray<D> where D: Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ReprojectionProgram<D> where D: Device {
|
||||||
|
program: D::Program,
|
||||||
|
old_transform_uniform: D::Uniform,
|
||||||
|
new_transform_uniform: D::Uniform,
|
||||||
|
texture_uniform: D::Uniform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> ReprojectionProgram<D> where D: Device {
|
||||||
|
fn new(device: &D, resources: &dyn ResourceLoader) -> ReprojectionProgram<D> {
|
||||||
|
let program = device.create_program(resources, "reproject");
|
||||||
|
let old_transform_uniform = device.get_uniform(&program, "OldTransform");
|
||||||
|
let new_transform_uniform = device.get_uniform(&program, "NewTransform");
|
||||||
|
let texture_uniform = device.get_uniform(&program, "Texture");
|
||||||
|
|
||||||
|
ReprojectionProgram {
|
||||||
|
program,
|
||||||
|
old_transform_uniform,
|
||||||
|
new_transform_uniform,
|
||||||
|
texture_uniform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ReprojectionVertexArray<D> where D: Device {
|
||||||
|
vertex_array: D::VertexArray,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> ReprojectionVertexArray<D> where D: Device {
|
||||||
|
fn new(device: &D,
|
||||||
|
reprojection_program: &ReprojectionProgram<D>,
|
||||||
|
quad_vertex_positions_buffer: &D::Buffer)
|
||||||
|
-> ReprojectionVertexArray<D> {
|
||||||
|
let vertex_array = device.create_vertex_array();
|
||||||
|
|
||||||
|
let position_attr = device.get_vertex_attr(&reprojection_program.program, "Position");
|
||||||
|
|
||||||
|
device.bind_vertex_array(&vertex_array);
|
||||||
|
device.use_program(&reprojection_program.program);
|
||||||
|
device.bind_buffer(quad_vertex_positions_buffer, BufferTarget::Vertex);
|
||||||
|
device.configure_float_vertex_attr(&position_attr, 2, VertexAttrType::U8, false, 0, 0, 0);
|
||||||
|
|
||||||
|
ReprojectionVertexArray { vertex_array }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum DestFramebuffer<D> where D: Device {
|
pub enum DestFramebuffer<D> where D: Device {
|
||||||
Default { viewport: RectI32, window_size: Point2DI32 },
|
Default { viewport: RectI32, window_size: Point2DI32 },
|
||||||
|
|
|
@ -83,11 +83,6 @@ impl Scene {
|
||||||
outline.clip_against_polygon(clip_polygon);
|
outline.clip_against_polygon(clip_polygon);
|
||||||
outline.apply_perspective(perspective);
|
outline.apply_perspective(perspective);
|
||||||
|
|
||||||
// TODO(pcwalton): Support this in 2D too.
|
|
||||||
if let Some(barrel_distortion) = options.barrel_distortion {
|
|
||||||
outline.barrel_distort(barrel_distortion, perspective.window_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(pcwalton): Support subpixel AA in 3D.
|
// TODO(pcwalton): Support subpixel AA in 3D.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#version {{version}}
|
#version {{version}}
|
||||||
|
|
||||||
// pathfinder/demo/shaders/debug_texture.fs.glsl
|
// pathfinder/resources/shaders/debug_texture.fs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#version {{version}}
|
#version {{version}}
|
||||||
|
|
||||||
// pathfinder/demo/shaders/post.vs.glsl
|
// pathfinder/resources/shaders/post.vs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
//
|
//
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#version {{version}}
|
||||||
|
|
||||||
|
// pathfinder/resources/shaders/reproject.fs.glsl
|
||||||
|
//
|
||||||
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform mat4 uOldTransform;
|
||||||
|
uniform sampler2D uTexture;
|
||||||
|
|
||||||
|
in vec2 vTexCoord;
|
||||||
|
|
||||||
|
out vec4 oFragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 normTexCoord = uOldTransform * vec4(vTexCoord, 0.0, 1.0);
|
||||||
|
vec2 texCoord = ((normTexCoord.xy / normTexCoord.w) + 1.0) * 0.5;
|
||||||
|
oFragColor = texture(uTexture, texCoord);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#version {{version}}
|
||||||
|
|
||||||
|
// pathfinder/resources/shaders/reproject.vs.glsl
|
||||||
|
//
|
||||||
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform mat4 uNewTransform;
|
||||||
|
|
||||||
|
in vec2 aPosition;
|
||||||
|
|
||||||
|
out vec2 vTexCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vTexCoord = aPosition;
|
||||||
|
gl_Position = uNewTransform * vec4(aPosition, 0.0, 1.0);
|
||||||
|
}
|
Loading…
Reference in New Issue