Implement a third demo with native code, not working yet
This commit is contained in:
parent
821b54b8f4
commit
a4c2796883
|
@ -46,6 +46,11 @@ dependencies = [
|
|||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.9.3"
|
||||
|
@ -150,6 +155,23 @@ dependencies = [
|
|||
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "demo3"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pathfinder_geometry 0.3.0",
|
||||
"pathfinder_renderer 0.1.0",
|
||||
"pathfinder_svg 0.1.0",
|
||||
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.0"
|
||||
|
@ -225,6 +247,24 @@ dependencies = [
|
|||
"lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gl"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gl_generator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gl_generator"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.1.7"
|
||||
|
@ -259,6 +299,20 @@ dependencies = [
|
|||
"scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inflate"
|
||||
version = "0.4.4"
|
||||
|
@ -295,6 +349,11 @@ dependencies = [
|
|||
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "khronos_api"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.2.0"
|
||||
|
@ -374,6 +433,16 @@ name = "nodrop"
|
|||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.2.3"
|
||||
|
@ -411,6 +480,15 @@ dependencies = [
|
|||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.6"
|
||||
|
@ -495,6 +573,17 @@ dependencies = [
|
|||
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"inflate 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.24"
|
||||
|
@ -539,6 +628,32 @@ dependencies = [
|
|||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_os 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.2.2"
|
||||
|
@ -552,6 +667,52 @@ name = "rand_core"
|
|||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.0.3"
|
||||
|
@ -578,6 +739,14 @@ name = "rctree"
|
|||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.50"
|
||||
|
@ -619,6 +788,19 @@ dependencies = [
|
|||
"xmlparser 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "safe-transmute"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.3.0"
|
||||
|
@ -634,6 +816,40 @@ name = "scopeguard"
|
|||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "sdl2"
|
||||
version = "0.32.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.4 (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 = "sdl2-sys"
|
||||
version = "0.32.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.84"
|
||||
|
@ -842,6 +1058,14 @@ dependencies = [
|
|||
"winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xmlparser"
|
||||
version = "0.8.1"
|
||||
|
@ -853,6 +1077,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
|
||||
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||
"checksum autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e5f34df7a019573fb8bdc7e24a2bfebe51a2a1d6bfdbaeccedb3c41fc574727"
|
||||
"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 byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
|
||||
|
@ -875,13 +1100,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum gif 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4bca55ac1f213920ce3527ccd62386f1f15fa3f1714aeee1cf93f2c416903f"
|
||||
"checksum gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1c73b90c285f02059b34a6c66bc645ba5faa18c0e3ab332e0725654fc71db441"
|
||||
"checksum gl_generator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "75d69f914b49d9ff32fdf394cbd798f8c716d74fd19f9cc29da3e99797b2a78d"
|
||||
"checksum hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "64b7d419d0622ae02fe5da6b9a5e1964b610a65bb37923b976aeebb6dbb8f86e"
|
||||
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
|
||||
"checksum image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebdff791af04e30089bde8ad2a632b86af433b40c04db8d70ad4b21487db7a6a"
|
||||
"checksum image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52fb0666a1273dac46f9725aa4859bcd5595fc3554cf3495051b4de8db745e7d"
|
||||
"checksum inflate 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "84c683bde2d8413b8f1be3e459c30e4817672b6e7a31d9212b0323154e76eba7"
|
||||
"checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae"
|
||||
"checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3"
|
||||
"checksum jpeg-decoder 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c8b7d43206b34b3f94ea9445174bda196e772049b9bddbc620c9d29b2d20110d"
|
||||
"checksum khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554"
|
||||
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||
"checksum libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)" = "023a4cd09b2ff695f9734c1934145a315594b7986398496841c7031a5a1bbdbd"
|
||||
"checksum libflate 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "bff3ac7d6f23730d3b533c35ed75eef638167634476a499feef16c428d74b57b"
|
||||
|
@ -893,33 +1122,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9"
|
||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
|
||||
"checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d"
|
||||
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||
"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124"
|
||||
"checksum num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e"
|
||||
"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10"
|
||||
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
|
||||
"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238"
|
||||
"checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
|
||||
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
|
||||
"checksum png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f54b9600d584d3b8a739e1662a595fab051329eff43f20e7d8cc22872962145b"
|
||||
"checksum png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9adebf7fb91ccf5eac9da1a8e00e83cb8ae882c3e8d8e4ad59da73cb8c82a2c9"
|
||||
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
|
||||
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
||||
"checksum quickcheck 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4537d3e4edf73a15dd059b75bed1c292d17d3ea7517f583cebe716794fcf816"
|
||||
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
|
||||
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
|
||||
"checksum rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3906503e80ac6cbcacb2c2973fa8e473f24d7e2747c8c92bb230c2441cad96b5"
|
||||
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
|
||||
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
|
||||
"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
"checksum rand_os 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46fbd5550acf75b0c2730f5dd1873751daf9beb8f11b44027778fae50d7feca"
|
||||
"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05"
|
||||
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473"
|
||||
"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356"
|
||||
"checksum rctree 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1817e0f0056f95bce0d6ab1a5be62ca24bd756b5547c20637ef47cc9a2065f4b"
|
||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
"checksum redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)" = "52ee9a534dc1301776eff45b4fa92d2c39b1d8c3d3357e6eb593e0d795506fc2"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
|
||||
"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
|
||||
"checksum roxmltree 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02660467d0c2da1b6276042501aee6e15ec5b8ff59423243f185b294cd53acf3"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9604873ffe1980bc1f179103704a65c8aca141c248d9e52b7af95ff10578166e"
|
||||
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
|
||||
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebf85f207d42e4da59fa31fff977be5ff0b224873506c4bd70cc1c94b331593"
|
||||
"checksum sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e82803e85c2e6178d28886cef25b2c53afc2eecaeff739f2247f23ed3352e6c1"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "0e732ed5a5592c17d961555e3b552985baf98d50ce418b7b655f31f6ba7eb1b7"
|
||||
"checksum serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d6115a3ca25c224e409185325afc16a0d5aaaabc15c42b09587d6f1ba39a5b"
|
||||
"checksum simplecss 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "135685097a85a64067df36e28a243e94a94f76d829087ce0be34eeb014260c0e"
|
||||
|
@ -946,4 +1192,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba"
|
||||
"checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2"
|
||||
"checksum xmlparser 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d78a7f29bb57edf63321d545d84f99360df71df36929a090bc067e1bcb65e34d"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"demo3",
|
||||
"geometry",
|
||||
"gfx-utils",
|
||||
"renderer",
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
[package]
|
||||
name = "demo3"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
||||
|
||||
[dependencies]
|
||||
clap = "2.32"
|
||||
euclid = "0.19"
|
||||
gl = "0.6"
|
||||
jemallocator = "0.1"
|
||||
rayon = "1.0"
|
||||
sdl2 = "0.32"
|
||||
usvg = "0.4"
|
||||
|
||||
[dependencies.image]
|
||||
version = "0.21"
|
||||
default-features = false
|
||||
features = ["png_codec"]
|
||||
|
||||
[dependencies.pathfinder_geometry]
|
||||
path = "../geometry"
|
||||
|
||||
[dependencies.pathfinder_renderer]
|
||||
path = "../renderer"
|
||||
|
||||
[dependencies.pathfinder_svg]
|
||||
path = "../svg"
|
|
@ -0,0 +1,42 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/stencil.fs.glsl
|
||||
//
|
||||
// Copyright © 2018 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 sampler2D uAreaLUT;
|
||||
|
||||
in vec2 vFrom;
|
||||
in vec2 vTo;
|
||||
|
||||
out vec4 oFragColor;
|
||||
|
||||
void main() {
|
||||
// Unpack.
|
||||
vec2 from = vFrom, to = vTo;
|
||||
|
||||
// Determine winding, and sort into a consistent order so we only need to find one root below.
|
||||
bool winding = from.x < to.x;
|
||||
vec2 left = winding ? from : to, right = winding ? to : from;
|
||||
|
||||
// Shoot a vertical ray toward the curve.
|
||||
vec2 window = clamp(vec2(from.x, to.x), -0.5, 0.5);
|
||||
float offset = mix(window.x, window.y, 0.5) - left.x;
|
||||
float t = offset / (right.x - left.x);
|
||||
|
||||
// Compute position and derivative to form a line approximation.
|
||||
float y = mix(left.y, right.y, t);
|
||||
float d = (right.y - left.y) / (right.x - left.x);
|
||||
|
||||
// Look up area under that line, and scale horizontally to the window size.
|
||||
float dX = window.x - window.y;
|
||||
oFragColor = vec4(texture(uAreaLUT, vec2(y + 8.0, abs(d * dX)) / 16.0).r * dX);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/stencil.vs.glsl
|
||||
//
|
||||
// Copyright © 2018 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 vec2 uFramebufferSize;
|
||||
uniform vec2 uTileSize;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in uint aFromPx;
|
||||
in uint aToPx;
|
||||
in vec2 aFromSubpx;
|
||||
in vec2 aToSubpx;
|
||||
in uint aTileIndex;
|
||||
|
||||
out vec2 vFrom;
|
||||
out vec2 vTo;
|
||||
|
||||
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
||||
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
|
||||
uvec2 tileOffset = uvec2(aTileIndex % tilesPerRow, aTileIndex / tilesPerRow);
|
||||
return vec2(tileOffset) * uTileSize;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize.x);
|
||||
|
||||
vec2 from = vec2(aFromPx & 15u, aFromPx >> 4u) + aFromSubpx;
|
||||
vec2 to = vec2(aToPx & 15u, aToPx >> 4u) + aToSubpx;
|
||||
|
||||
vec2 position;
|
||||
bool zeroArea = !(abs(from.x - to.x) > 0.1) || !(abs(uTileSize.y - min(from.y, to.y)) > 0.1);
|
||||
if (aTessCoord.x < 0.5)
|
||||
position.x = floor(min(from.x, to.x));
|
||||
else
|
||||
position.x = ceil(max(from.x, to.x));
|
||||
if (aTessCoord.y < 0.5)
|
||||
position.y = floor(min(from.y, to.y));
|
||||
else
|
||||
position.y = uTileSize.y;
|
||||
|
||||
vFrom = from - position;
|
||||
vTo = to - position;
|
||||
|
||||
if (zeroArea)
|
||||
gl_Position = vec4(0.0);
|
||||
else
|
||||
gl_Position = vec4((tileOrigin + position) / uFramebufferSize * 2.0 - 1.0, 0.0, 1.0);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/cover.fs.glsl
|
||||
//
|
||||
// Copyright © 2018 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 sampler2D uStencilTexture;
|
||||
|
||||
in vec2 vTexCoord;
|
||||
in float vBackdrop;
|
||||
in vec4 vColor;
|
||||
|
||||
out vec4 oFragColor;
|
||||
|
||||
void main() {
|
||||
float coverage = abs(texture(uStencilTexture, vTexCoord).r + vBackdrop);
|
||||
vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
//oFragColor = vec4(vColor.rgb, vColor.a * coverage);
|
||||
oFragColor = vec4(color.rgb, color.a * coverage);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/cover.vs.glsl
|
||||
//
|
||||
// Copyright © 2018 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 vec2 uFramebufferSize;
|
||||
uniform vec2 uTileSize;
|
||||
uniform vec2 uStencilTextureSize;
|
||||
uniform sampler2D uFillColorsTexture;
|
||||
uniform vec2 uFillColorsTextureSize;
|
||||
uniform vec2 uViewBoxOrigin;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in vec2 aTileOrigin;
|
||||
in int aBackdrop;
|
||||
in uint aObject;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
out float vBackdrop;
|
||||
out vec4 vColor;
|
||||
|
||||
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
||||
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
|
||||
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
|
||||
return vec2(tileOffset) * uTileSize;
|
||||
}
|
||||
|
||||
void main() {
|
||||
uint tileIndex = uint(gl_InstanceID);
|
||||
vec2 position = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||
vec2 texCoord = computeTileOffset(tileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize;
|
||||
vTexCoord = texCoord / uStencilTextureSize;
|
||||
vBackdrop = float(aBackdrop);
|
||||
vColor = texture(uFillColorsTexture, vec2(float(aObject) / uFillColorsTextureSize.x, 0.0));
|
||||
gl_Position = vec4((position / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0), 0.0, 1.0);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/opaque.fs.glsl
|
||||
//
|
||||
// Copyright © 2018 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;
|
||||
|
||||
in vec4 vColor;
|
||||
|
||||
out vec4 oFragColor;
|
||||
|
||||
void main() {
|
||||
oFragColor = vColor;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/opaque.vs.glsl
|
||||
//
|
||||
// Copyright © 2018 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 vec2 uFramebufferSize;
|
||||
uniform vec2 uTileSize;
|
||||
uniform sampler2D uFillColorsTexture;
|
||||
uniform vec2 uFillColorsTextureSize;
|
||||
uniform vec2 uViewBoxOrigin;
|
||||
|
||||
in vec2 aTessCoord;
|
||||
in vec2 aTileOrigin;
|
||||
in uint aObject;
|
||||
|
||||
out vec4 vColor;
|
||||
|
||||
void main() {
|
||||
vec2 position = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||
vColor = texture(uFillColorsTexture, vec2(float(aObject) / uFillColorsTextureSize.x, 0.0));
|
||||
gl_Position = vec4((position / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0), 0.0, 1.0);
|
||||
}
|
|
@ -0,0 +1,769 @@
|
|||
// pathfinder/demo3/src/main.rs
|
||||
//
|
||||
// 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.
|
||||
|
||||
use clap::{App, Arg};
|
||||
use euclid::Size2D;
|
||||
use gl::types::{GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
||||
use jemallocator;
|
||||
use pathfinder_renderer::builder::SceneBuilder;
|
||||
use pathfinder_renderer::gpu_data::{Batch, BuiltScene, FillBatchPrimitive};
|
||||
use pathfinder_renderer::scene::Scene;
|
||||
use pathfinder_renderer::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
||||
use pathfinder_renderer::z_buffer::ZBuffer;
|
||||
use pathfinder_svg::SceneExt;
|
||||
use rayon::ThreadPoolBuilder;
|
||||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::video::GLProfile;
|
||||
use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
use std::ptr;
|
||||
use std::time::{Duration, Instant};
|
||||
use usvg::{Options as UsvgOptions, Tree};
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
||||
|
||||
static QUAD_VERTEX_POSITIONS: [u8; 8] = [0, 0, 1, 0, 1, 1, 0, 1];
|
||||
|
||||
// TODO(pcwalton): Replace with `mem::size_of` calls?
|
||||
const FILL_INSTANCE_SIZE: GLint = 8;
|
||||
const SOLID_TILE_INSTANCE_SIZE: GLint = 6;
|
||||
const MASK_TILE_INSTANCE_SIZE: GLint = 8;
|
||||
|
||||
const MASK_FRAMEBUFFER_WIDTH: u32 = TILE_WIDTH * 256;
|
||||
const MASK_FRAMEBUFFER_HEIGHT: u32 = TILE_HEIGHT * 256;
|
||||
|
||||
// FIXME(pcwalton): Make this dynamic!
|
||||
const MAIN_FRAMEBUFFER_WIDTH: u32 = 800;
|
||||
const MAIN_FRAMEBUFFER_HEIGHT: u32 = 800;
|
||||
|
||||
fn main() {
|
||||
let scene = load_scene();
|
||||
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let sdl_video = sdl_context.video().unwrap();
|
||||
|
||||
let gl_attributes = sdl_video.gl_attr();
|
||||
gl_attributes.set_context_profile(GLProfile::Core);
|
||||
gl_attributes.set_context_version(3, 3);
|
||||
|
||||
let window =
|
||||
sdl_video.window("Pathfinder Demo", MAIN_FRAMEBUFFER_WIDTH, MAIN_FRAMEBUFFER_HEIGHT)
|
||||
.opengl()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let gl_context = window.gl_create_context().unwrap();
|
||||
gl::load_with(|name| sdl_video.gl_get_proc_address(name) as *const _);
|
||||
|
||||
let mut sdl_event_pump = sdl_context.event_pump().unwrap();
|
||||
let mut exit = false;
|
||||
while !exit {
|
||||
let mut renderer = Renderer::new();
|
||||
|
||||
unsafe {
|
||||
gl::ClearColor(1.0, 1.0, 1.0, 1.0);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
renderer.render_scene(&scene);
|
||||
}
|
||||
|
||||
window.gl_swap_window();
|
||||
|
||||
for event in sdl_event_pump.poll_iter() {
|
||||
match event {
|
||||
Event::Quit { .. } | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
|
||||
exit = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_scene() -> BuiltScene {
|
||||
let matches = App::new("tile-svg")
|
||||
.arg(
|
||||
Arg::with_name("jobs")
|
||||
.short("j")
|
||||
.long("jobs")
|
||||
.value_name("THREADS")
|
||||
.takes_value(true)
|
||||
.help("Number of threads to use"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("INPUT")
|
||||
.help("Path to the SVG file to render")
|
||||
.required(true)
|
||||
.index(1),
|
||||
)
|
||||
.get_matches();
|
||||
let jobs: Option<usize> = matches
|
||||
.value_of("jobs")
|
||||
.map(|string| string.parse().unwrap());
|
||||
let input_path = PathBuf::from(matches.value_of("INPUT").unwrap());
|
||||
|
||||
// Set up Rayon.
|
||||
let mut thread_pool_builder = ThreadPoolBuilder::new();
|
||||
if let Some(jobs) = jobs {
|
||||
thread_pool_builder = thread_pool_builder.num_threads(jobs);
|
||||
}
|
||||
thread_pool_builder.build_global().unwrap();
|
||||
|
||||
// Build scene.
|
||||
let usvg = Tree::from_file(&input_path, &UsvgOptions::default()).unwrap();
|
||||
let scene = Scene::from_tree(usvg);
|
||||
|
||||
println!(
|
||||
"Scene bounds: {:?} View box: {:?}",
|
||||
scene.bounds, scene.view_box
|
||||
);
|
||||
println!(
|
||||
"{} objects, {} paints",
|
||||
scene.objects.len(),
|
||||
scene.paints.len()
|
||||
);
|
||||
|
||||
let (mut elapsed_object_build_time, mut elapsed_scene_build_time) = (0.0, 0.0);
|
||||
|
||||
let mut built_scene = BuiltScene::new(&scene.view_box);
|
||||
let z_buffer = ZBuffer::new(&scene.view_box);
|
||||
|
||||
let start_time = Instant::now();
|
||||
let built_objects = match jobs {
|
||||
Some(1) => scene.build_objects_sequentially(&z_buffer),
|
||||
_ => scene.build_objects(&z_buffer),
|
||||
};
|
||||
elapsed_object_build_time += duration_to_ms(&(Instant::now() - start_time));
|
||||
|
||||
let start_time = Instant::now();
|
||||
built_scene = BuiltScene::new(&scene.view_box);
|
||||
built_scene.shaders = scene.build_shaders();
|
||||
let mut scene_builder = SceneBuilder::new(built_objects, z_buffer, &scene.view_box);
|
||||
built_scene.solid_tiles = scene_builder.build_solid_tiles();
|
||||
while let Some(batch) = scene_builder.build_batch() {
|
||||
built_scene.batches.push(batch);
|
||||
}
|
||||
elapsed_scene_build_time += duration_to_ms(&(Instant::now() - start_time));
|
||||
|
||||
let total_elapsed_time = elapsed_object_build_time + elapsed_scene_build_time;
|
||||
|
||||
println!(
|
||||
"{:.3}ms ({:.3}ms objects, {:.3}ms scene) elapsed",
|
||||
total_elapsed_time, elapsed_object_build_time, elapsed_scene_build_time
|
||||
);
|
||||
|
||||
println!("{} solid tiles", built_scene.solid_tiles.len());
|
||||
for (batch_index, batch) in built_scene.batches.iter().enumerate() {
|
||||
println!(
|
||||
"Batch {}: {} fills, {} mask tiles",
|
||||
batch_index,
|
||||
batch.fills.len(),
|
||||
batch.mask_tiles.len()
|
||||
);
|
||||
}
|
||||
|
||||
built_scene
|
||||
}
|
||||
|
||||
fn duration_to_ms(duration: &Duration) -> f64 {
|
||||
duration.as_secs() as f64 * 1000.0 + f64::from(duration.subsec_micros()) / 1000.0
|
||||
}
|
||||
|
||||
struct Renderer {
|
||||
fill_program: FillProgram,
|
||||
solid_tile_program: SolidTileProgram,
|
||||
mask_tile_program: MaskTileProgram,
|
||||
area_lut_texture: Texture,
|
||||
quad_vertex_positions_buffer: Buffer,
|
||||
fill_vertex_array: FillVertexArray,
|
||||
mask_tile_vertex_array: MaskTileVertexArray,
|
||||
solid_tile_vertex_array: SolidTileVertexArray,
|
||||
mask_framebuffer: Framebuffer,
|
||||
}
|
||||
|
||||
impl Renderer {
|
||||
fn new() -> Renderer {
|
||||
let fill_program = FillProgram::new();
|
||||
let solid_tile_program = SolidTileProgram::new();
|
||||
let mask_tile_program = MaskTileProgram::new();
|
||||
|
||||
let area_lut_texture = Texture::from_png("area-lut");
|
||||
|
||||
let quad_vertex_positions_buffer = Buffer::new();
|
||||
quad_vertex_positions_buffer.upload(&QUAD_VERTEX_POSITIONS, BufferUploadMode::Static);
|
||||
|
||||
let fill_vertex_array = FillVertexArray::new(&fill_program, &quad_vertex_positions_buffer);
|
||||
let mask_tile_vertex_array = MaskTileVertexArray::new(&mask_tile_program,
|
||||
&quad_vertex_positions_buffer);
|
||||
let solid_tile_vertex_array = SolidTileVertexArray::new(&solid_tile_program,
|
||||
&quad_vertex_positions_buffer);
|
||||
|
||||
let mask_framebuffer = Framebuffer::new(&Size2D::new(MASK_FRAMEBUFFER_WIDTH,
|
||||
MASK_FRAMEBUFFER_HEIGHT));
|
||||
|
||||
Renderer {
|
||||
fill_program,
|
||||
solid_tile_program,
|
||||
mask_tile_program,
|
||||
area_lut_texture,
|
||||
quad_vertex_positions_buffer,
|
||||
fill_vertex_array,
|
||||
mask_tile_vertex_array,
|
||||
solid_tile_vertex_array,
|
||||
mask_framebuffer,
|
||||
}
|
||||
}
|
||||
|
||||
fn render_scene(&mut self, built_scene: &BuiltScene) {
|
||||
for batch in &built_scene.batches {
|
||||
self.upload_batch(batch);
|
||||
self.draw_batch_fills(batch);
|
||||
self.draw_batch_mask_tiles(batch);
|
||||
}
|
||||
}
|
||||
|
||||
fn upload_batch(&mut self, batch: &Batch) {
|
||||
self.fill_vertex_array.vertex_buffer.upload(&batch.fills, BufferUploadMode::Dynamic);
|
||||
self.mask_tile_vertex_array.vertex_buffer.upload(&batch.mask_tiles,
|
||||
BufferUploadMode::Dynamic);
|
||||
}
|
||||
|
||||
fn draw_batch_fills(&mut self, batch: &Batch) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.mask_framebuffer.gl_framebuffer);
|
||||
gl::Viewport(0, 0, MASK_FRAMEBUFFER_WIDTH as GLint, MASK_FRAMEBUFFER_HEIGHT as GLint);
|
||||
// TODO(pcwalton): Only clear the appropriate portion?
|
||||
gl::ClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
||||
gl::BindVertexArray(self.fill_vertex_array.gl_vertex_array);
|
||||
gl::UseProgram(self.fill_program.program.gl_program);
|
||||
gl::Uniform2f(self.fill_program.framebuffer_size_uniform.location,
|
||||
MASK_FRAMEBUFFER_WIDTH as GLfloat,
|
||||
MASK_FRAMEBUFFER_HEIGHT as GLfloat);
|
||||
gl::Uniform2f(self.fill_program.tile_size_uniform.location,
|
||||
TILE_WIDTH as GLfloat,
|
||||
TILE_HEIGHT as GLfloat);
|
||||
self.area_lut_texture.bind(0);
|
||||
gl::Uniform1i(self.fill_program.area_lut_uniform.location, 0);
|
||||
gl::BlendEquation(gl::FUNC_ADD);
|
||||
gl::BlendFunc(gl::ONE, gl::ONE);
|
||||
gl::Enable(gl::BLEND);
|
||||
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, batch.fills.len() as GLint);
|
||||
gl::Disable(gl::BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_batch_mask_tiles(&mut self, batch: &Batch) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl::Viewport(0, 0, MAIN_FRAMEBUFFER_WIDTH as GLint, MAIN_FRAMEBUFFER_HEIGHT as GLint);
|
||||
|
||||
gl::BindVertexArray(self.mask_tile_vertex_array.gl_vertex_array);
|
||||
gl::UseProgram(self.mask_tile_program.program.gl_program);
|
||||
gl::Uniform2f(self.mask_tile_program.framebuffer_size_uniform.location,
|
||||
MAIN_FRAMEBUFFER_WIDTH as GLfloat,
|
||||
MAIN_FRAMEBUFFER_HEIGHT as GLfloat);
|
||||
gl::Uniform2f(self.mask_tile_program.tile_size_uniform.location,
|
||||
TILE_WIDTH as GLfloat,
|
||||
TILE_HEIGHT as GLfloat);
|
||||
self.mask_framebuffer.texture.bind(0);
|
||||
gl::Uniform1i(self.mask_tile_program.stencil_texture_uniform.location, 0);
|
||||
gl::Uniform2f(self.mask_tile_program.stencil_texture_size_uniform.location,
|
||||
MASK_FRAMEBUFFER_WIDTH as GLfloat,
|
||||
MASK_FRAMEBUFFER_HEIGHT as GLfloat);
|
||||
// FIXME(pcwalton): Fill this in properly!
|
||||
gl::Uniform2f(self.mask_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
||||
gl::BlendEquation(gl::FUNC_ADD);
|
||||
gl::BlendFuncSeparate(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA, gl::ONE, gl::ONE);
|
||||
gl::Enable(gl::BLEND);
|
||||
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, batch.mask_tiles.len() as GLint);
|
||||
gl::Disable(gl::BLEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct FillVertexArray {
|
||||
gl_vertex_array: GLuint,
|
||||
vertex_buffer: Buffer,
|
||||
}
|
||||
|
||||
impl FillVertexArray {
|
||||
fn new(fill_program: &FillProgram, quad_vertex_positions_buffer: &Buffer) -> FillVertexArray {
|
||||
let vertex_buffer = Buffer::new();
|
||||
let mut gl_vertex_array = 0;
|
||||
unsafe {
|
||||
let tess_coord_attr = VertexAttr::new(&fill_program.program, "TessCoord");
|
||||
let from_px_attr = VertexAttr::new(&fill_program.program, "FromPx");
|
||||
let to_px_attr = VertexAttr::new(&fill_program.program, "ToPx");
|
||||
let from_subpx_attr = VertexAttr::new(&fill_program.program, "FromSubpx");
|
||||
let to_subpx_attr = VertexAttr::new(&fill_program.program, "ToSubpx");
|
||||
let tile_index_attr = VertexAttr::new(&fill_program.program, "TileIndex");
|
||||
|
||||
gl::GenVertexArrays(1, &mut gl_vertex_array);
|
||||
gl::BindVertexArray(gl_vertex_array);
|
||||
gl::UseProgram(fill_program.program.gl_program);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
||||
tess_coord_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer.gl_buffer);
|
||||
from_px_attr.configure_int(1, gl::UNSIGNED_BYTE, FILL_INSTANCE_SIZE, 0, 1);
|
||||
to_px_attr.configure_int(1, gl::UNSIGNED_BYTE, FILL_INSTANCE_SIZE, 1, 1);
|
||||
from_subpx_attr.configure_float(2, gl::UNSIGNED_BYTE, true, FILL_INSTANCE_SIZE, 2, 1);
|
||||
to_subpx_attr.configure_float(2, gl::UNSIGNED_BYTE, true, FILL_INSTANCE_SIZE, 4, 1);
|
||||
tile_index_attr.configure_int(1, gl::UNSIGNED_SHORT, FILL_INSTANCE_SIZE, 6, 1);
|
||||
}
|
||||
|
||||
FillVertexArray { gl_vertex_array, vertex_buffer }
|
||||
}
|
||||
}
|
||||
|
||||
struct MaskTileVertexArray {
|
||||
gl_vertex_array: GLuint,
|
||||
vertex_buffer: Buffer,
|
||||
}
|
||||
|
||||
impl MaskTileVertexArray {
|
||||
fn new(mask_tile_program: &MaskTileProgram, quad_vertex_positions_buffer: &Buffer)
|
||||
-> MaskTileVertexArray {
|
||||
let vertex_buffer = Buffer::new();
|
||||
let mut gl_vertex_array = 0;
|
||||
unsafe {
|
||||
let tess_coord_attr = VertexAttr::new(&mask_tile_program.program, "TessCoord");
|
||||
let tile_origin_attr = VertexAttr::new(&mask_tile_program.program, "TileOrigin");
|
||||
let backdrop_attr = VertexAttr::new(&mask_tile_program.program, "Backdrop");
|
||||
let object_attr = VertexAttr::new(&mask_tile_program.program, "Object");
|
||||
|
||||
gl::GenVertexArrays(1, &mut gl_vertex_array);
|
||||
gl::BindVertexArray(gl_vertex_array);
|
||||
gl::UseProgram(mask_tile_program.program.gl_program);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
||||
tess_coord_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer.gl_buffer);
|
||||
tile_origin_attr.configure_float(2, gl::SHORT, false, MASK_TILE_INSTANCE_SIZE, 0, 1);
|
||||
backdrop_attr.configure_int(1, gl::SHORT, MASK_TILE_INSTANCE_SIZE, 4, 1);
|
||||
object_attr.configure_int(2, gl::UNSIGNED_SHORT, MASK_TILE_INSTANCE_SIZE, 6, 1);
|
||||
}
|
||||
|
||||
MaskTileVertexArray { gl_vertex_array, vertex_buffer }
|
||||
}
|
||||
}
|
||||
|
||||
struct SolidTileVertexArray {
|
||||
gl_vertex_array: GLuint,
|
||||
vertex_buffer: Buffer,
|
||||
}
|
||||
|
||||
impl SolidTileVertexArray {
|
||||
fn new(solid_tile_program: &SolidTileProgram, quad_vertex_positions_buffer: &Buffer)
|
||||
-> SolidTileVertexArray {
|
||||
let vertex_buffer = Buffer::new();
|
||||
let mut gl_vertex_array = 0;
|
||||
unsafe {
|
||||
let tess_coord_attr = VertexAttr::new(&solid_tile_program.program, "TessCoord");
|
||||
let tile_origin_attr = VertexAttr::new(&solid_tile_program.program, "TileOrigin");
|
||||
let object_attr = VertexAttr::new(&solid_tile_program.program, "Object");
|
||||
|
||||
gl::GenVertexArrays(1, &mut gl_vertex_array);
|
||||
gl::BindVertexArray(gl_vertex_array);
|
||||
gl::UseProgram(solid_tile_program.program.gl_program);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, quad_vertex_positions_buffer.gl_buffer);
|
||||
tess_coord_attr.configure_float(2, gl::UNSIGNED_BYTE, false, 0, 0, 0);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer.gl_buffer);
|
||||
tile_origin_attr.configure_float(2, gl::SHORT, false, SOLID_TILE_INSTANCE_SIZE, 0, 1);
|
||||
object_attr.configure_int(1, gl::UNSIGNED_SHORT, SOLID_TILE_INSTANCE_SIZE, 4, 1);
|
||||
}
|
||||
|
||||
SolidTileVertexArray { gl_vertex_array, vertex_buffer }
|
||||
}
|
||||
}
|
||||
|
||||
struct VertexAttr {
|
||||
attr: GLuint,
|
||||
}
|
||||
|
||||
impl VertexAttr {
|
||||
fn new(program: &Program, name: &str) -> VertexAttr {
|
||||
let name = CString::new(format!("a{}", name)).unwrap();
|
||||
let attr = unsafe {
|
||||
gl::GetAttribLocation(program.gl_program, name.as_ptr() as *const GLchar) as GLuint
|
||||
};
|
||||
VertexAttr { attr }
|
||||
}
|
||||
|
||||
fn configure_float(&self,
|
||||
size: GLint,
|
||||
gl_type: GLuint,
|
||||
normalized: bool,
|
||||
stride: GLsizei,
|
||||
offset: usize,
|
||||
divisor: GLuint) {
|
||||
unsafe {
|
||||
gl::VertexAttribPointer(self.attr,
|
||||
size,
|
||||
gl_type,
|
||||
if normalized { gl::TRUE } else { gl::FALSE },
|
||||
stride,
|
||||
offset as *const GLvoid);
|
||||
gl::VertexAttribDivisor(self.attr, divisor);
|
||||
gl::EnableVertexAttribArray(self.attr);
|
||||
}
|
||||
}
|
||||
|
||||
fn configure_int(&self,
|
||||
size: GLint,
|
||||
gl_type: GLuint,
|
||||
stride: GLsizei,
|
||||
offset: usize,
|
||||
divisor: GLuint) {
|
||||
unsafe {
|
||||
gl::VertexAttribIPointer(self.attr, size, gl_type, stride, offset as *const GLvoid);
|
||||
gl::VertexAttribDivisor(self.attr, divisor);
|
||||
gl::EnableVertexAttribArray(self.attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Framebuffer {
|
||||
gl_framebuffer: GLuint,
|
||||
texture: Texture,
|
||||
}
|
||||
|
||||
impl Framebuffer {
|
||||
fn new(size: &Size2D<u32>) -> Framebuffer {
|
||||
let texture = Texture::new_r16f(size);
|
||||
let mut gl_framebuffer = 0;
|
||||
unsafe {
|
||||
gl::GenFramebuffers(1, &mut gl_framebuffer);
|
||||
assert_eq!(gl::GetError(), gl::NO_ERROR);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, gl_framebuffer);
|
||||
texture.bind(0);
|
||||
gl::FramebufferTexture2D(gl::FRAMEBUFFER,
|
||||
gl::COLOR_ATTACHMENT0,
|
||||
gl::TEXTURE_2D,
|
||||
texture.gl_texture,
|
||||
0);
|
||||
assert_eq!(gl::CheckFramebufferStatus(gl::FRAMEBUFFER), gl::FRAMEBUFFER_COMPLETE);
|
||||
}
|
||||
Framebuffer { gl_framebuffer, texture }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Framebuffer {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
gl::DeleteFramebuffers(1, &mut self.gl_framebuffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Buffer {
|
||||
gl_buffer: GLuint,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
fn new() -> Buffer {
|
||||
unsafe {
|
||||
let mut gl_buffer = 0;
|
||||
gl::GenBuffers(1, &mut gl_buffer);
|
||||
Buffer { gl_buffer }
|
||||
}
|
||||
}
|
||||
|
||||
fn upload<T>(&self, data: &[T], mode: BufferUploadMode) {
|
||||
let mode = match mode {
|
||||
BufferUploadMode::Static => gl::STATIC_DRAW,
|
||||
BufferUploadMode::Dynamic => gl::DYNAMIC_DRAW,
|
||||
};
|
||||
unsafe {
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, self.gl_buffer);
|
||||
gl::BufferData(gl::ARRAY_BUFFER,
|
||||
(data.len() * mem::size_of::<T>()) as GLsizeiptr,
|
||||
data.as_ptr() as *const GLvoid,
|
||||
mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Buffer {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
gl::DeleteBuffers(1, &mut self.gl_buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum BufferUploadMode {
|
||||
Static,
|
||||
Dynamic,
|
||||
}
|
||||
|
||||
struct FillProgram {
|
||||
program: Program,
|
||||
framebuffer_size_uniform: Uniform,
|
||||
tile_size_uniform: Uniform,
|
||||
area_lut_uniform: Uniform,
|
||||
}
|
||||
|
||||
impl FillProgram {
|
||||
fn new() -> FillProgram {
|
||||
let program = Program::new("fill");
|
||||
let framebuffer_size_uniform = Uniform::new(&program, "FramebufferSize");
|
||||
let tile_size_uniform = Uniform::new(&program, "TileSize");
|
||||
let area_lut_uniform = Uniform::new(&program, "AreaLUT");
|
||||
FillProgram { program, framebuffer_size_uniform, tile_size_uniform, area_lut_uniform }
|
||||
}
|
||||
}
|
||||
|
||||
struct SolidTileProgram {
|
||||
program: Program,
|
||||
framebuffer_size_uniform: Uniform,
|
||||
tile_size_uniform: Uniform,
|
||||
fill_colors_texture_uniform: Uniform,
|
||||
fill_colors_texture_size_uniform: Uniform,
|
||||
view_box_origin_uniform: Uniform,
|
||||
}
|
||||
|
||||
impl SolidTileProgram {
|
||||
fn new() -> SolidTileProgram {
|
||||
let program = Program::new("solid_tile");
|
||||
let framebuffer_size_uniform = Uniform::new(&program, "FramebufferSize");
|
||||
let tile_size_uniform = Uniform::new(&program, "TileSize");
|
||||
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
||||
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
||||
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
||||
SolidTileProgram {
|
||||
program,
|
||||
framebuffer_size_uniform,
|
||||
tile_size_uniform,
|
||||
fill_colors_texture_uniform,
|
||||
fill_colors_texture_size_uniform,
|
||||
view_box_origin_uniform,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MaskTileProgram {
|
||||
program: Program,
|
||||
framebuffer_size_uniform: Uniform,
|
||||
tile_size_uniform: Uniform,
|
||||
stencil_texture_uniform: Uniform,
|
||||
stencil_texture_size_uniform: Uniform,
|
||||
fill_colors_texture_uniform: Uniform,
|
||||
fill_colors_texture_size_uniform: Uniform,
|
||||
view_box_origin_uniform: Uniform,
|
||||
}
|
||||
|
||||
impl MaskTileProgram {
|
||||
fn new() -> MaskTileProgram {
|
||||
let program = Program::new("mask_tile");
|
||||
let framebuffer_size_uniform = Uniform::new(&program, "FramebufferSize");
|
||||
let tile_size_uniform = Uniform::new(&program, "TileSize");
|
||||
let stencil_texture_uniform = Uniform::new(&program, "StencilTexture");
|
||||
let stencil_texture_size_uniform = Uniform::new(&program, "StencilTextureSize");
|
||||
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
||||
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
||||
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
||||
MaskTileProgram {
|
||||
program,
|
||||
framebuffer_size_uniform,
|
||||
tile_size_uniform,
|
||||
stencil_texture_uniform,
|
||||
stencil_texture_size_uniform,
|
||||
fill_colors_texture_uniform,
|
||||
fill_colors_texture_size_uniform,
|
||||
view_box_origin_uniform,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Uniform {
|
||||
location: GLint,
|
||||
}
|
||||
|
||||
impl Uniform {
|
||||
fn new(program: &Program, name: &str) -> Uniform {
|
||||
let name = CString::new(format!("u{}", name)).unwrap();
|
||||
let location = unsafe {
|
||||
gl::GetUniformLocation(program.gl_program, name.as_ptr() as *const GLchar)
|
||||
};
|
||||
Uniform { location }
|
||||
}
|
||||
}
|
||||
|
||||
struct Program {
|
||||
gl_program: GLuint,
|
||||
vertex_shader: Shader,
|
||||
fragment_shader: Shader,
|
||||
}
|
||||
|
||||
impl Program {
|
||||
fn new(name: &'static str) -> Program {
|
||||
let vertex_shader = Shader::new(name, ShaderKind::Vertex);
|
||||
let fragment_shader = Shader::new(name, ShaderKind::Fragment);
|
||||
|
||||
let gl_program;
|
||||
unsafe {
|
||||
gl_program = gl::CreateProgram();
|
||||
gl::AttachShader(gl_program, vertex_shader.gl_shader);
|
||||
gl::AttachShader(gl_program, fragment_shader.gl_shader);
|
||||
gl::LinkProgram(gl_program);
|
||||
|
||||
let mut link_status = 0;
|
||||
gl::GetProgramiv(gl_program, gl::LINK_STATUS, &mut link_status);
|
||||
if link_status != gl::TRUE as GLint {
|
||||
let mut info_log_length = 0;
|
||||
gl::GetProgramiv(gl_program, gl::INFO_LOG_LENGTH, &mut info_log_length);
|
||||
let mut info_log = vec![0; info_log_length as usize];
|
||||
gl::GetProgramInfoLog(gl_program,
|
||||
info_log.len() as GLint,
|
||||
ptr::null_mut(),
|
||||
info_log.as_mut_ptr() as *mut GLchar);
|
||||
eprintln!("Program info log:\n{}", String::from_utf8_lossy(&info_log));
|
||||
panic!("Program '{}' linking failed", name);
|
||||
}
|
||||
}
|
||||
|
||||
Program { gl_program, vertex_shader, fragment_shader }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Program {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
gl::DeleteProgram(self.gl_program)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Shader {
|
||||
gl_shader: GLuint,
|
||||
}
|
||||
|
||||
impl Shader {
|
||||
fn new(name: &str, kind: ShaderKind) -> Shader {
|
||||
let suffix = match kind { ShaderKind::Vertex => 'v', ShaderKind::Fragment => 'f' };
|
||||
// FIXME(pcwalton): Put the shaders somewhere else. Maybe compile them in?
|
||||
let path = format!("shaders/{}.{}s.glsl", name, suffix);
|
||||
let mut source = vec![];
|
||||
File::open(&path).unwrap().read_to_end(&mut source).unwrap();
|
||||
unsafe {
|
||||
let gl_shader_kind = match kind {
|
||||
ShaderKind::Vertex => gl::VERTEX_SHADER,
|
||||
ShaderKind::Fragment => gl::FRAGMENT_SHADER,
|
||||
};
|
||||
let gl_shader = gl::CreateShader(gl_shader_kind);
|
||||
gl::ShaderSource(gl_shader,
|
||||
1,
|
||||
[source.as_ptr() as *const GLchar].as_ptr(),
|
||||
[source.len() as GLint].as_ptr());
|
||||
gl::CompileShader(gl_shader);
|
||||
|
||||
let mut compile_status = 0;
|
||||
gl::GetShaderiv(gl_shader, gl::COMPILE_STATUS, &mut compile_status);
|
||||
if compile_status != gl::TRUE as GLint {
|
||||
let mut info_log_length = 0;
|
||||
gl::GetShaderiv(gl_shader, gl::INFO_LOG_LENGTH, &mut info_log_length);
|
||||
let mut info_log = vec![0; info_log_length as usize];
|
||||
gl::GetShaderInfoLog(gl_shader,
|
||||
info_log.len() as GLint,
|
||||
ptr::null_mut(),
|
||||
info_log.as_mut_ptr() as *mut GLchar);
|
||||
eprintln!("Shader info log:\n{}", String::from_utf8_lossy(&info_log));
|
||||
panic!("{:?} shader '{}' compilation failed", kind, name);
|
||||
}
|
||||
|
||||
Shader { gl_shader }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Shader {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
gl::DeleteShader(self.gl_shader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum ShaderKind {
|
||||
Vertex,
|
||||
Fragment,
|
||||
}
|
||||
|
||||
struct Texture {
|
||||
gl_texture: GLuint,
|
||||
}
|
||||
|
||||
impl Texture {
|
||||
fn new_r16f(size: &Size2D<u32>) -> Texture {
|
||||
let mut texture = Texture { gl_texture: 0 };
|
||||
unsafe {
|
||||
gl::GenTextures(1, &mut texture.gl_texture);
|
||||
texture.bind(0);
|
||||
gl::TexImage2D(gl::TEXTURE_2D,
|
||||
0,
|
||||
gl::R16F as GLint,
|
||||
size.width as GLsizei,
|
||||
size.height as GLsizei,
|
||||
0,
|
||||
gl::RED,
|
||||
gl::HALF_FLOAT,
|
||||
ptr::null());
|
||||
}
|
||||
|
||||
texture.set_parameters();
|
||||
texture
|
||||
}
|
||||
|
||||
fn from_png(name: &str) -> Texture {
|
||||
let path = format!("textures/{}.png", name);
|
||||
let image = image::open(&path).unwrap().to_luma();
|
||||
|
||||
let mut texture = Texture { gl_texture: 0 };
|
||||
unsafe {
|
||||
gl::GenTextures(1, &mut texture.gl_texture);
|
||||
texture.bind(0);
|
||||
gl::TexImage2D(gl::TEXTURE_2D,
|
||||
0,
|
||||
gl::RED as GLint,
|
||||
image.width() as GLsizei,
|
||||
image.height() as GLsizei,
|
||||
0,
|
||||
gl::RED,
|
||||
gl::UNSIGNED_BYTE,
|
||||
image.as_ptr() as *const GLvoid);
|
||||
}
|
||||
|
||||
texture.set_parameters();
|
||||
texture
|
||||
}
|
||||
|
||||
fn bind(&self, unit: u32) {
|
||||
unsafe {
|
||||
gl::ActiveTexture(gl::TEXTURE0 + unit);
|
||||
gl::BindTexture(gl::TEXTURE_2D, self.gl_texture);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_parameters(&self) {
|
||||
self.bind(0);
|
||||
unsafe {
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as GLint);
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as GLint);
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as GLint);
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as GLint);
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
|
@ -161,7 +161,9 @@ impl Sub<Point2DF32> for LineSegmentF32 {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct LineSegmentU4(pub u16);
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct LineSegmentU8(pub u32);
|
||||
|
|
|
@ -52,6 +52,7 @@ pub struct FillObjectPrimitive {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct TileObjectPrimitive {
|
||||
pub tile_x: i16,
|
||||
pub tile_y: i16,
|
||||
|
@ -59,6 +60,7 @@ pub struct TileObjectPrimitive {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct FillBatchPrimitive {
|
||||
pub px: LineSegmentU4,
|
||||
pub subpx: LineSegmentU8,
|
||||
|
@ -66,6 +68,7 @@ pub struct FillBatchPrimitive {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct SolidTileScenePrimitive {
|
||||
pub tile_x: i16,
|
||||
pub tile_y: i16,
|
||||
|
@ -73,6 +76,7 @@ pub struct SolidTileScenePrimitive {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct MaskTileBatchPrimitive {
|
||||
pub tile: TileObjectPrimitive,
|
||||
pub shader: ShaderId,
|
||||
|
|
Loading…
Reference in New Issue