mirror of https://github.com/AxioDL/metaforce.git
Splash screen rendering
This commit is contained in:
parent
8d01afc632
commit
509252a17f
|
@ -72,9 +72,9 @@ checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ash"
|
name = "ash"
|
||||||
version = "0.34.0+1.2.203"
|
version = "0.35.1+1.2.203"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0f780da53d0063880d45554306489f09dd8d1bda47688b4a57bc579119356df"
|
checksum = "b7fd04def1c9101b5fb488c131022d2d6f87753ef4b1b11b279e2af404fae6b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
|
@ -96,7 +96,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_logger",
|
"android_logger",
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"binread",
|
"binrw",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"bytemuck_derive",
|
"bytemuck_derive",
|
||||||
"cgmath",
|
"cgmath",
|
||||||
|
@ -109,9 +109,8 @@ dependencies = [
|
||||||
"imgui-winit-support",
|
"imgui-winit-support",
|
||||||
"log",
|
"log",
|
||||||
"log-panics",
|
"log-panics",
|
||||||
"mobile-entry-point",
|
|
||||||
"modular-bitfield",
|
"modular-bitfield",
|
||||||
"naga",
|
"naga 0.8.0 (git+https://github.com/gfx-rs/naga?rev=d6f8958b346676396db97053771b8d95684c47ee)",
|
||||||
"ndk-glue",
|
"ndk-glue",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"num_enum",
|
"num_enum",
|
||||||
|
@ -120,7 +119,6 @@ dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"twox-hash",
|
"twox-hash",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"web-sys",
|
|
||||||
"wgpu",
|
"wgpu",
|
||||||
"wgpu-subscriber",
|
"wgpu-subscriber",
|
||||||
"winit",
|
"winit",
|
||||||
|
@ -156,23 +154,22 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "binread"
|
name = "binrw"
|
||||||
version = "2.2.0"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16598dfc8e6578e9b597d9910ba2e73618385dc9f4b1d43dd92c349d6be6418f"
|
checksum = "a13d2fa8772b88ee64a0d84602c636ad2bae9c176873f6c440e2b0a1df4c8c43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"array-init",
|
"array-init",
|
||||||
"binread_derive",
|
"binrw_derive",
|
||||||
"rustversion",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "binread_derive"
|
name = "binrw_derive"
|
||||||
version = "2.1.0"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1d9672209df1714ee804b1f4d4f68c8eb2a90b1f7a07acf472f88ce198ef1fed"
|
checksum = "193bcff2709da50edf2e9a89e0f9a2118eea70f257b1f4380ccf27d3d8578302"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"owo-colors",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
@ -488,9 +485,9 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx"
|
name = "cxx"
|
||||||
version = "1.0.60"
|
version = "1.0.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af5f0799eb4abbd9c46cb58dfaa781386f852386ad6681e65c66a8101b8562af"
|
checksum = "fcd554072878dec8c16f59839336bf712d6d1f0d8d27cf9b471c10a484a3290f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cxxbridge-flags",
|
"cxxbridge-flags",
|
||||||
|
@ -500,13 +497,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-build"
|
name = "cxx-build"
|
||||||
version = "1.0.60"
|
version = "1.0.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2c8f82eb643890f29750b559497cd5dc8c82019e5c6ff0284a1d14e85e8c44c7"
|
checksum = "bae954f28208a9c31eb37623d435bdfcdd28fe93ffb5a34dfe6af9a2f1a1ca66"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
"lazy_static",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"scratch",
|
"scratch",
|
||||||
|
@ -515,15 +512,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-flags"
|
name = "cxxbridge-flags"
|
||||||
version = "1.0.60"
|
version = "1.0.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "394474c4844c6df346936204bda4a45e4cf524d0b7050eb70e4b81fc568ab125"
|
checksum = "1cc629121d3f01cd7c85ba046b3bcef66d182429b495eeb1080396ba4bfb8ae4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-macro"
|
name = "cxxbridge-macro"
|
||||||
version = "1.0.60"
|
version = "1.0.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05055753924c7b4ae9b038eb7823d4d9c64a045a727cb581764a4454a60d0805"
|
checksum = "93a8fa39ee5a91d04a99fc09fc3f1dd780ebfe31817721abcaecd823e00c9f3b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -576,17 +573,6 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derivative"
|
|
||||||
version = "2.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dispatch"
|
name = "dispatch"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -860,6 +846,7 @@ checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading",
|
||||||
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -971,8 +958,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metal"
|
name = "metal"
|
||||||
version = "0.23.1"
|
version = "0.23.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/gfx-rs/metal-rs?rev=140c8f4#140c8f4e39001ae154f153ffc767da6c0c9d7f06"
|
||||||
checksum = "e0514f491f4cc03632ab399ee01e2c1c1b12d3e1cf2d667c1ff5f87d6dcd2084"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"block",
|
"block",
|
||||||
|
@ -1010,17 +996,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mobile-entry-point"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "81bef5a90018326583471cccca10424d7b3e770397b02f03276543cbb9b6a1a6"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "modular-bitfield"
|
name = "modular-bitfield"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
|
@ -1045,7 +1020,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "naga"
|
name = "naga"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+https://github.com/gfx-rs/naga?rev=8df5421#8df5421e2e9d33e092c19779adfdc42e7f8a74e6"
|
source = "git+https://github.com/gfx-rs/naga?rev=81dc674#81dc67402a743b4dc6b2d24c0d306cd18799238b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-set",
|
"bit-set",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
@ -1060,6 +1035,23 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "naga"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "git+https://github.com/gfx-rs/naga?rev=d6f8958b346676396db97053771b8d95684c47ee#d6f8958b346676396db97053771b8d95684c47ee"
|
||||||
|
dependencies = [
|
||||||
|
"bit-set",
|
||||||
|
"bitflags",
|
||||||
|
"codespan-reporting",
|
||||||
|
"hexf-parse",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"num-traits",
|
||||||
|
"rustc-hash",
|
||||||
|
"spirv",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ndk"
|
name = "ndk"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -1160,19 +1152,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_enum"
|
name = "num_enum"
|
||||||
version = "0.5.5"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "085fe377a4b2805c0fbc09484415ec261174614b7f080b0e0d520456ac421a67"
|
checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"derivative",
|
|
||||||
"num_enum_derive",
|
"num_enum_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_enum_derive"
|
name = "num_enum_derive"
|
||||||
version = "0.5.5"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5249369707a1e07b39f78d98c8f34e00aca7dcb053812fdbb5ad7be82c1bba38"
|
checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -1205,6 +1196,12 @@ version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "owo-colors"
|
||||||
|
version = "3.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20448fd678ec04e6ea15bbe0476874af65e98a01515d667aa49f1434dc44ebf4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
|
@ -1272,9 +1269,9 @@ checksum = "bb20dcc30536a1508e75d47dd0e399bb2fe7354dcf35cda9127f2bf1ed92e30e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.15"
|
version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
|
@ -1418,12 +1415,6 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustversion"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.9"
|
version = "1.0.9"
|
||||||
|
@ -1876,12 +1867,12 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu"
|
name = "wgpu"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/gfx-rs/wgpu?rev=39b7a8a202c21da43035ec8dd5570a58cf4e8ef1#39b7a8a202c21da43035ec8dd5570a58cf4e8ef1"
|
source = "git+https://github.com/gfx-rs/wgpu?rev=766c6cda1917c1265fa8a5f610ef7516d4314d1b#766c6cda1917c1265fa8a5f610ef7516d4314d1b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"naga",
|
"naga 0.8.0 (git+https://github.com/gfx-rs/naga?rev=81dc674)",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
@ -1896,7 +1887,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core"
|
name = "wgpu-core"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/gfx-rs/wgpu?rev=39b7a8a202c21da43035ec8dd5570a58cf4e8ef1#39b7a8a202c21da43035ec8dd5570a58cf4e8ef1"
|
source = "git+https://github.com/gfx-rs/wgpu?rev=766c6cda1917c1265fa8a5f610ef7516d4314d1b#766c6cda1917c1265fa8a5f610ef7516d4314d1b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
@ -1905,7 +1896,7 @@ dependencies = [
|
||||||
"copyless",
|
"copyless",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"log",
|
"log",
|
||||||
"naga",
|
"naga 0.8.0 (git+https://github.com/gfx-rs/naga?rev=81dc674)",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"profiling",
|
"profiling",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
|
@ -1918,7 +1909,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-hal"
|
name = "wgpu-hal"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/gfx-rs/wgpu?rev=39b7a8a202c21da43035ec8dd5570a58cf4e8ef1#39b7a8a202c21da43035ec8dd5570a58cf4e8ef1"
|
source = "git+https://github.com/gfx-rs/wgpu?rev=766c6cda1917c1265fa8a5f610ef7516d4314d1b#766c6cda1917c1265fa8a5f610ef7516d4314d1b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"ash",
|
"ash",
|
||||||
|
@ -1938,7 +1929,7 @@ dependencies = [
|
||||||
"libloading",
|
"libloading",
|
||||||
"log",
|
"log",
|
||||||
"metal",
|
"metal",
|
||||||
"naga",
|
"naga 0.8.0 (git+https://github.com/gfx-rs/naga?rev=81dc674)",
|
||||||
"objc",
|
"objc",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"profiling",
|
"profiling",
|
||||||
|
@ -1968,7 +1959,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-types"
|
name = "wgpu-types"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/gfx-rs/wgpu?rev=39b7a8a202c21da43035ec8dd5570a58cf4e8ef1#39b7a8a202c21da43035ec8dd5570a58cf4e8ef1"
|
source = "git+https://github.com/gfx-rs/wgpu?rev=766c6cda1917c1265fa8a5f610ef7516d4314d1b#766c6cda1917c1265fa8a5f610ef7516d4314d1b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
@ -2017,12 +2008,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winit"
|
name = "winit"
|
||||||
version = "0.26.0"
|
version = "0.26.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "70466a5f4825cc88c92963591b06dbc255420bffe19d847bfcda475e82d079c0"
|
checksum = "9b43cc931d58b99461188607efd7acb2a093e65fc621f54cad78517a6063e73a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"block",
|
|
||||||
"cocoa",
|
"cocoa",
|
||||||
"core-foundation 0.9.2",
|
"core-foundation 0.9.2",
|
||||||
"core-graphics 0.22.3",
|
"core-graphics 0.22.3",
|
||||||
|
|
|
@ -13,15 +13,13 @@ crate-type = ["staticlib"]
|
||||||
#path = "src/main.rs"
|
#path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cxx = "1.0.60"
|
cxx = "1.0.64"
|
||||||
web-sys = "0.3.55"
|
|
||||||
env_logger = "0.9.0"
|
env_logger = "0.9.0"
|
||||||
mobile-entry-point = "0.1.1"
|
|
||||||
pollster = "0.2.4"
|
pollster = "0.2.4"
|
||||||
binread = { version = "2.2.0", features = ['const_generics'] }
|
binrw = "0.8.4"
|
||||||
modular-bitfield = "0.11.2"
|
modular-bitfield = "0.11.2"
|
||||||
num-traits = "0.2.14"
|
num-traits = "0.2.14"
|
||||||
num_enum = "0.5.5"
|
num_enum = "0.5.6"
|
||||||
bytemuck = "1.7.3"
|
bytemuck = "1.7.3"
|
||||||
bytemuck_derive = "1.0.1"
|
bytemuck_derive = "1.0.1"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
|
@ -30,7 +28,7 @@ cgmath = "0.18.0"
|
||||||
smallvec = "1.7.0"
|
smallvec = "1.7.0"
|
||||||
scopeguard = "1.1.0"
|
scopeguard = "1.1.0"
|
||||||
twox-hash = "1.6.2"
|
twox-hash = "1.6.2"
|
||||||
winit = "0.26.0"
|
winit = "0.26.1"
|
||||||
|
|
||||||
[dependencies.imgui]
|
[dependencies.imgui]
|
||||||
git = "https://github.com/imgui-rs/imgui-rs"
|
git = "https://github.com/imgui-rs/imgui-rs"
|
||||||
|
@ -44,11 +42,12 @@ features = ["winit-26"]
|
||||||
imgui-sys = { path = "../imgui-sys" }
|
imgui-sys = { path = "../imgui-sys" }
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
imgui-sys = { path = "../imgui-sys" }
|
imgui-sys = { path = "../imgui-sys" }
|
||||||
|
naga = { git = "https://github.com/gfx-rs/naga", rev = "d6f8958b346676396db97053771b8d95684c47ee" }
|
||||||
|
|
||||||
[dependencies.wgpu]
|
[dependencies.wgpu]
|
||||||
#path = "../../wgpu/wgpu"
|
#path = "../../wgpu/wgpu"
|
||||||
git = "https://github.com/gfx-rs/wgpu"
|
git = "https://github.com/gfx-rs/wgpu"
|
||||||
rev = "39b7a8a202c21da43035ec8dd5570a58cf4e8ef1"
|
rev = "766c6cda1917c1265fa8a5f610ef7516d4314d1b"
|
||||||
features = ["spirv"]
|
features = ["spirv"]
|
||||||
|
|
||||||
#[patch.'https://github.com/gfx-rs/naga']
|
#[patch.'https://github.com/gfx-rs/naga']
|
||||||
|
@ -56,9 +55,9 @@ features = ["spirv"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
#naga = { path = "../../naga", features = ['spv-out', 'wgsl-in'] }
|
#naga = { path = "../../naga", features = ['spv-out', 'wgsl-in'] }
|
||||||
naga = { git = "https://github.com/gfx-rs/naga", rev = "8df5421", features = ['spv-out', 'wgsl-in'] }
|
naga = { git = "https://github.com/gfx-rs/naga", rev = "d6f8958b346676396db97053771b8d95684c47ee", features = ['spv-out', 'wgsl-in'] }
|
||||||
bytemuck = "1.7.3"
|
bytemuck = "1.7.3"
|
||||||
cxx-build = "1.0.60"
|
cxx-build = "1.0.64"
|
||||||
bindgen = "0.59.2"
|
bindgen = "0.59.2"
|
||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
|
|
|
@ -59,6 +59,7 @@ pub(crate) fn initialize_imgui(window: &winit::window::Window, gpu: &DeviceHolde
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
fn ImGuiEngine_AddTexture(
|
fn ImGuiEngine_AddTexture(
|
||||||
state: &mut ImGuiState,
|
state: &mut ImGuiState,
|
||||||
gpu: &DeviceHolder,
|
gpu: &DeviceHolder,
|
||||||
|
|
|
@ -3,21 +3,21 @@ struct Uniforms {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexInput {
|
struct VertexInput {
|
||||||
[[location(0)]] a_Pos: vec2<f32>;
|
@location(0) a_Pos: vec2<f32>;
|
||||||
[[location(1)]] a_UV: vec2<f32>;
|
@location(1) a_UV: vec2<f32>;
|
||||||
[[location(2)]] a_Color: vec4<f32>;
|
@location(2) a_Color: vec4<f32>;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
[[location(0)]] v_UV: vec2<f32>;
|
@location(0) v_UV: vec2<f32>;
|
||||||
[[location(1)]] v_Color: vec4<f32>;
|
@location(1) v_Color: vec4<f32>;
|
||||||
[[builtin(position)]] v_Position: vec4<f32>;
|
@builtin(position) v_Position: vec4<f32>;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[group(0), binding(0)]]
|
@group(0) @binding(0)
|
||||||
var<uniform> uniforms: Uniforms;
|
var<uniform> uniforms: Uniforms;
|
||||||
|
|
||||||
[[stage(vertex)]]
|
@stage(vertex)
|
||||||
fn vs_main(in: VertexInput) -> VertexOutput {
|
fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.v_UV = in.a_UV;
|
out.v_UV = in.a_UV;
|
||||||
|
@ -26,9 +26,9 @@ fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[group(1), binding(0)]]
|
@group(1) @binding(0)
|
||||||
var u_Texture: texture_2d<f32>;
|
var u_Texture: texture_2d<f32>;
|
||||||
[[group(1), binding(1)]]
|
@group(1) @binding(1)
|
||||||
var u_Sampler: sampler;
|
var u_Sampler: sampler;
|
||||||
|
|
||||||
fn srgb_to_linear(srgb: vec4<f32>) -> vec4<f32> {
|
fn srgb_to_linear(srgb: vec4<f32>) -> vec4<f32> {
|
||||||
|
@ -40,14 +40,14 @@ fn srgb_to_linear(srgb: vec4<f32>) -> vec4<f32> {
|
||||||
return vec4<f32>(result, srgb.a);
|
return vec4<f32>(result, srgb.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[stage(fragment)]]
|
@stage(fragment)
|
||||||
fn fs_main_linear(in: VertexOutput) -> [[location(0)]] vec4<f32> {
|
fn fs_main_linear(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
let color = srgb_to_linear(in.v_Color);
|
let color = srgb_to_linear(in.v_Color);
|
||||||
return color * textureSample(u_Texture, u_Sampler, in.v_UV);
|
return color * textureSample(u_Texture, u_Sampler, in.v_UV);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[stage(fragment)]]
|
@stage(fragment)
|
||||||
fn fs_main_srgb(in: VertexOutput) -> [[location(0)]] vec4<f32> {
|
fn fs_main_srgb(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
let color = in.v_Color;
|
let color = in.v_Color;
|
||||||
return color * textureSample(u_Texture, u_Sampler, in.v_UV);
|
return color * textureSample(u_Texture, u_Sampler, in.v_UV);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ mod imgui;
|
||||||
mod imgui_backend;
|
mod imgui_backend;
|
||||||
mod shaders;
|
mod shaders;
|
||||||
mod zeus;
|
mod zeus;
|
||||||
|
mod util;
|
||||||
|
|
||||||
#[cxx::bridge(namespace = "aurora")]
|
#[cxx::bridge(namespace = "aurora")]
|
||||||
mod ffi {
|
mod ffi {
|
||||||
|
@ -143,6 +144,8 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>) {
|
||||||
APP.replace(app);
|
APP.replace(app);
|
||||||
ffi::App_onAppLaunched(delegate.as_mut().unwrap());
|
ffi::App_onAppLaunched(delegate.as_mut().unwrap());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut last_frame: Option<Instant> = None;
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
// Have the closure take ownership of the resources.
|
// Have the closure take ownership of the resources.
|
||||||
// `event_loop.run` never returns, therefore we must do this to ensure
|
// `event_loop.run` never returns, therefore we must do this to ensure
|
||||||
|
@ -153,7 +156,6 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>) {
|
||||||
let imgui = &mut app.imgui;
|
let imgui = &mut app.imgui;
|
||||||
let window_ctx = get_window_context();
|
let window_ctx = get_window_context();
|
||||||
let gpu = &mut app.gpu;
|
let gpu = &mut app.gpu;
|
||||||
let mut last_frame: Option<Instant> = None;
|
|
||||||
|
|
||||||
*control_flow = ControlFlow::Poll;
|
*control_flow = ControlFlow::Poll;
|
||||||
match event {
|
match event {
|
||||||
|
@ -183,7 +185,7 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>) {
|
||||||
Event::Suspended => {}
|
Event::Suspended => {}
|
||||||
Event::Resumed => {}
|
Event::Resumed => {}
|
||||||
Event::MainEventsCleared => {
|
Event::MainEventsCleared => {
|
||||||
log::info!("Requesting redraw");
|
log::trace!("Requesting redraw");
|
||||||
window_ctx.window.request_redraw();
|
window_ctx.window.request_redraw();
|
||||||
}
|
}
|
||||||
Event::RedrawRequested(_) => {
|
Event::RedrawRequested(_) => {
|
||||||
|
@ -208,7 +210,7 @@ fn app_run(mut delegate: cxx::UniquePtr<ffi::AppDelegate>) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("Redrawing");
|
log::trace!("Redrawing");
|
||||||
let frame_result = gpu.surface.get_current_texture();
|
let frame_result = gpu.surface.get_current_texture();
|
||||||
if let Err(err) = frame_result {
|
if let Err(err) = frame_result {
|
||||||
log::warn!("Failed to acquire frame {}", err);
|
log::warn!("Failed to acquire frame {}", err);
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
struct Uniform {
|
|
||||||
xf: mat4x4<f32>;
|
|
||||||
color: vec4<f32>;
|
|
||||||
};
|
|
||||||
[[group(0), binding(0)]]
|
|
||||||
var<uniform> ubuf: Uniform;
|
|
||||||
|
|
||||||
[[stage(vertex)]]
|
|
||||||
fn vs_main([[location(0)]] in_pos: vec3<f32>) -> [[builtin(position)]] vec4<f32> {
|
|
||||||
return ubuf.xf * vec4<f32>(in_pos, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[stage(fragment)]]
|
|
||||||
fn fs_main() -> [[location(0)]] vec4<f32> {
|
|
||||||
return ubuf.color;
|
|
||||||
}
|
|
|
@ -24,8 +24,10 @@ pub(crate) struct DrawData {
|
||||||
pub(crate) struct PipelineConfig {
|
pub(crate) struct PipelineConfig {
|
||||||
z_only: bool,
|
z_only: bool,
|
||||||
}
|
}
|
||||||
pub(crate) const INITIAL_PIPELINES: &[PipelineConfig] =
|
pub(crate) const INITIAL_PIPELINES: &[PipelineCreateCommand] = &[
|
||||||
&[PipelineConfig { z_only: false }, PipelineConfig { z_only: true }];
|
PipelineCreateCommand::Aabb(PipelineConfig { z_only: false }),
|
||||||
|
PipelineCreateCommand::Aabb(PipelineConfig { z_only: true }),
|
||||||
|
];
|
||||||
|
|
||||||
pub(crate) struct State {
|
pub(crate) struct State {
|
||||||
shader: wgpu::ShaderModule,
|
shader: wgpu::ShaderModule,
|
||||||
|
@ -39,7 +41,7 @@ pub(crate) fn construct_state(
|
||||||
_queue: &wgpu::Queue,
|
_queue: &wgpu::Queue,
|
||||||
buffers: &BuiltBuffers,
|
buffers: &BuiltBuffers,
|
||||||
) -> State {
|
) -> State {
|
||||||
let shader = device.create_shader_module(&include_wgsl!("aabb.wgsl"));
|
let shader = device.create_shader_module(&include_wgsl!("shader.wgsl"));
|
||||||
let uniform_size = wgpu::BufferSize::new(std::mem::size_of::<Uniform>() as u64);
|
let uniform_size = wgpu::BufferSize::new(std::mem::size_of::<Uniform>() as u64);
|
||||||
let uniform_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
let uniform_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
label: Some("AABB Bind Group Layout"),
|
label: Some("AABB Bind Group Layout"),
|
||||||
|
@ -145,7 +147,7 @@ struct Uniform {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn queue_aabb(aabb: CAABox, color: CColor, z_only: bool) {
|
pub(crate) fn queue_aabb(aabb: CAABox, color: CColor, z_only: bool) {
|
||||||
let pipeline = pipeline_ref(PipelineCreateCommand::Aabb(PipelineConfig { z_only }));
|
let pipeline = pipeline_ref(&PipelineCreateCommand::Aabb(PipelineConfig { z_only }));
|
||||||
let vert_range = push_verts(&[
|
let vert_range = push_verts(&[
|
||||||
CVector3f::new(aabb.max.x, aabb.max.y, aabb.min.z),
|
CVector3f::new(aabb.max.x, aabb.max.y, aabb.min.z),
|
||||||
CVector3f::new(aabb.max.x, aabb.min.y, aabb.min.z),
|
CVector3f::new(aabb.max.x, aabb.min.y, aabb.min.z),
|
|
@ -0,0 +1,16 @@
|
||||||
|
struct Uniform {
|
||||||
|
xf: mat4x4<f32>;
|
||||||
|
color: vec4<f32>;
|
||||||
|
};
|
||||||
|
@group(0) @binding(0)
|
||||||
|
var<uniform> ubuf: Uniform;
|
||||||
|
|
||||||
|
@stage(vertex)
|
||||||
|
fn vs_main(@location(0) in_pos: vec3<f32>) -> @builtin(position) vec4<f32> {
|
||||||
|
return ubuf.xf * vec4<f32>(in_pos, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@stage(fragment)
|
||||||
|
fn fs_main() -> @location(0) vec4<f32> {
|
||||||
|
return ubuf.color;
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, VecDeque},
|
collections::{HashMap, VecDeque},
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
num::NonZeroU8,
|
|
||||||
ops::Range,
|
ops::Range,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
@ -10,10 +9,12 @@ use aabb::queue_aabb;
|
||||||
use bytemuck::Pod;
|
use bytemuck::Pod;
|
||||||
use bytemuck_derive::{Pod, Zeroable};
|
use bytemuck_derive::{Pod, Zeroable};
|
||||||
use cxx::{type_id, ExternType};
|
use cxx::{type_id, ExternType};
|
||||||
|
use cxx::private::hash;
|
||||||
use fog_volume_filter::queue_fog_volume_filter;
|
use fog_volume_filter::queue_fog_volume_filter;
|
||||||
use fog_volume_plane::queue_fog_volume_plane;
|
use fog_volume_plane::queue_fog_volume_plane;
|
||||||
use model::{add_material_set, add_model};
|
use model::{add_material_set, add_model};
|
||||||
use texture::{create_render_texture, create_static_texture_2d, drop_texture};
|
use texture::{create_render_texture, create_static_texture_2d, drop_texture};
|
||||||
|
use textured_quad::queue_textured_quad;
|
||||||
use twox_hash::Xxh3Hash64;
|
use twox_hash::Xxh3Hash64;
|
||||||
use wgpu::RenderPipeline;
|
use wgpu::RenderPipeline;
|
||||||
|
|
||||||
|
@ -21,11 +22,14 @@ use crate::{
|
||||||
gpu::GraphicsConfig,
|
gpu::GraphicsConfig,
|
||||||
zeus::{CColor, CMatrix4f, CRectangle, CVector2f, CVector3f, IDENTITY_MATRIX4F},
|
zeus::{CColor, CMatrix4f, CRectangle, CVector2f, CVector3f, IDENTITY_MATRIX4F},
|
||||||
};
|
};
|
||||||
|
use crate::shaders::ffi::{TextureFormat, TextureRef};
|
||||||
|
use crate::shaders::texture::{RenderTexture, TextureWithView};
|
||||||
|
|
||||||
mod aabb;
|
mod aabb;
|
||||||
mod fog_volume_filter;
|
mod fog_volume_filter;
|
||||||
mod fog_volume_plane;
|
mod fog_volume_plane;
|
||||||
mod model;
|
mod model;
|
||||||
|
mod textured_quad;
|
||||||
mod texture;
|
mod texture;
|
||||||
|
|
||||||
#[cxx::bridge]
|
#[cxx::bridge]
|
||||||
|
@ -55,7 +59,7 @@ mod ffi {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[namespace = "aurora::shaders"]
|
#[namespace = "aurora::shaders"]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Hash)]
|
||||||
pub(crate) enum CameraFilterType {
|
pub(crate) enum CameraFilterType {
|
||||||
Passthru,
|
Passthru,
|
||||||
Multiply,
|
Multiply,
|
||||||
|
@ -69,7 +73,7 @@ mod ffi {
|
||||||
InvDstMultiply,
|
InvDstMultiply,
|
||||||
}
|
}
|
||||||
#[namespace = "aurora::shaders"]
|
#[namespace = "aurora::shaders"]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Hash)]
|
||||||
pub(crate) enum ZTest {
|
pub(crate) enum ZTest {
|
||||||
None,
|
None,
|
||||||
LEqual,
|
LEqual,
|
||||||
|
@ -96,9 +100,10 @@ mod ffi {
|
||||||
ClampToBlack,
|
ClampToBlack,
|
||||||
}
|
}
|
||||||
#[namespace = "aurora::shaders"]
|
#[namespace = "aurora::shaders"]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Hash)]
|
||||||
pub(crate) struct TextureRef {
|
pub(crate) struct TextureRef {
|
||||||
pub(crate) id: u32,
|
pub(crate) id: u32,
|
||||||
|
pub(crate) render: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[namespace = "aurora::shaders"]
|
#[namespace = "aurora::shaders"]
|
||||||
|
@ -180,6 +185,15 @@ mod ffi {
|
||||||
fn queue_aabb(aabb: CAABox, color: CColor, z_only: bool);
|
fn queue_aabb(aabb: CAABox, color: CColor, z_only: bool);
|
||||||
fn queue_fog_volume_plane(verts: &CxxVector<CVector4f>, pass: u8);
|
fn queue_fog_volume_plane(verts: &CxxVector<CVector4f>, pass: u8);
|
||||||
fn queue_fog_volume_filter(color: CColor, two_way: bool);
|
fn queue_fog_volume_filter(color: CColor, two_way: bool);
|
||||||
|
fn queue_textured_quad(
|
||||||
|
filter_type: CameraFilterType,
|
||||||
|
texture: TextureRef,
|
||||||
|
z_test: ZTest,
|
||||||
|
color: CColor,
|
||||||
|
uv_scale: f32,
|
||||||
|
rect: CRectangle,
|
||||||
|
z: f32,
|
||||||
|
);
|
||||||
|
|
||||||
fn create_static_texture_2d(
|
fn create_static_texture_2d(
|
||||||
width: u32,
|
width: u32,
|
||||||
|
@ -210,6 +224,21 @@ impl Default for ffi::FogState {
|
||||||
Self { color: Default::default(), a: 0.0, b: 0.5, c: 0.0, mode: ffi::FogMode::None }
|
Self { color: Default::default(), a: 0.0, b: 0.5, c: 0.0, mode: ffi::FogMode::None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Into<u32> for ffi::TextureFormat {
|
||||||
|
// noinspection RsUnreachablePatterns
|
||||||
|
fn into(self) -> u32 {
|
||||||
|
match self {
|
||||||
|
TextureFormat::RGBA8 => 1,
|
||||||
|
TextureFormat::R8 => 2,
|
||||||
|
TextureFormat::R32Float => 3,
|
||||||
|
TextureFormat::DXT1 => 4,
|
||||||
|
TextureFormat::DXT3 => 5,
|
||||||
|
TextureFormat::DXT5 => 6,
|
||||||
|
TextureFormat::BPTC => 7,
|
||||||
|
_ => panic!("Invalid texture format {:?}", self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
enum ColoredStripMode {
|
enum ColoredStripMode {
|
||||||
|
@ -280,12 +309,7 @@ enum ShaderDrawCommand {
|
||||||
RandomStaticFilter {/* TODO */},
|
RandomStaticFilter {/* TODO */},
|
||||||
ScanLinesFilter {/* TODO */},
|
ScanLinesFilter {/* TODO */},
|
||||||
TextSupport {/* TODO */},
|
TextSupport {/* TODO */},
|
||||||
TexturedQuad {
|
TexturedQuad(textured_quad::DrawData),
|
||||||
filter_type: ffi::CameraFilterType,
|
|
||||||
z_test: ffi::ZTest,
|
|
||||||
tex: u32, /* TODO */
|
|
||||||
/* draw, cropped, verts, filter? */
|
|
||||||
},
|
|
||||||
ThermalCold,
|
ThermalCold,
|
||||||
ThermalHot,
|
ThermalHot,
|
||||||
WorldShadow {
|
WorldShadow {
|
||||||
|
@ -309,8 +333,11 @@ struct RenderState {
|
||||||
storage_alignment: usize,
|
storage_alignment: usize,
|
||||||
buffers: BuiltBuffers,
|
buffers: BuiltBuffers,
|
||||||
commands: VecDeque<Command>,
|
commands: VecDeque<Command>,
|
||||||
|
textures: HashMap<u32, TextureWithView>,
|
||||||
|
render_textures: HashMap<u32, RenderTexture>,
|
||||||
// Shader states
|
// Shader states
|
||||||
aabb: aabb::State,
|
aabb: aabb::State,
|
||||||
|
textured_quad: textured_quad::State,
|
||||||
}
|
}
|
||||||
pub(crate) fn construct_state(
|
pub(crate) fn construct_state(
|
||||||
device: Arc<wgpu::Device>,
|
device: Arc<wgpu::Device>,
|
||||||
|
@ -318,7 +345,7 @@ pub(crate) fn construct_state(
|
||||||
graphics_config: &GraphicsConfig,
|
graphics_config: &GraphicsConfig,
|
||||||
) {
|
) {
|
||||||
let limits = device.limits();
|
let limits = device.limits();
|
||||||
let mut buffers = BuiltBuffers {
|
let buffers = BuiltBuffers {
|
||||||
uniform_buffer: device.create_buffer(&wgpu::BufferDescriptor {
|
uniform_buffer: device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
label: Some("Shared Uniform Buffer"),
|
label: Some("Shared Uniform Buffer"),
|
||||||
size: 134_217_728, // 128mb
|
size: 134_217_728, // 128mb
|
||||||
|
@ -333,6 +360,7 @@ pub(crate) fn construct_state(
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
let aabb = aabb::construct_state(&device, &queue, &buffers);
|
let aabb = aabb::construct_state(&device, &queue, &buffers);
|
||||||
|
let textured_quad = textured_quad::construct_state(&device, &queue, &buffers, graphics_config);
|
||||||
let mut state = RenderState {
|
let mut state = RenderState {
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
queue: queue.clone(),
|
queue: queue.clone(),
|
||||||
|
@ -343,12 +371,16 @@ pub(crate) fn construct_state(
|
||||||
storage_alignment: limits.min_storage_buffer_offset_alignment as usize,
|
storage_alignment: limits.min_storage_buffer_offset_alignment as usize,
|
||||||
buffers,
|
buffers,
|
||||||
commands: Default::default(),
|
commands: Default::default(),
|
||||||
|
textures: Default::default(),
|
||||||
|
render_textures: Default::default(),
|
||||||
aabb,
|
aabb,
|
||||||
|
textured_quad,
|
||||||
};
|
};
|
||||||
for config in aabb::INITIAL_PIPELINES {
|
for config in aabb::INITIAL_PIPELINES {
|
||||||
let hash = hash_with_seed(config, 0xAABB);
|
construct_pipeline(&mut state, config);
|
||||||
let pipeline = aabb::construct_pipeline(&device, graphics_config, &state.aabb, config);
|
}
|
||||||
state.pipelines.insert(hash, pipeline);
|
for config in textured_quad::INITIAL_PIPELINES {
|
||||||
|
construct_pipeline(&mut state, config);
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
STATE = Some(state);
|
STATE = Some(state);
|
||||||
|
@ -442,8 +474,9 @@ struct PipelineRef {
|
||||||
id: u64,
|
id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PipelineCreateCommand {
|
pub(crate) enum PipelineCreateCommand {
|
||||||
Aabb(aabb::PipelineConfig),
|
Aabb(aabb::PipelineConfig),
|
||||||
|
TexturedQuad(textured_quad::PipelineConfig),
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn hash_with_seed<T: Hash>(value: &T, seed: u64) -> u64 {
|
fn hash_with_seed<T: Hash>(value: &T, seed: u64) -> u64 {
|
||||||
|
@ -451,12 +484,11 @@ fn hash_with_seed<T: Hash>(value: &T, seed: u64) -> u64 {
|
||||||
value.hash(&mut state);
|
value.hash(&mut state);
|
||||||
state.finish()
|
state.finish()
|
||||||
}
|
}
|
||||||
fn pipeline_ref(cmd: PipelineCreateCommand) -> PipelineRef {
|
fn construct_pipeline(state: &mut RenderState, cmd: &PipelineCreateCommand) -> u64 {
|
||||||
let state = unsafe { STATE.as_mut().unwrap() };
|
|
||||||
let id = match cmd {
|
let id = match cmd {
|
||||||
PipelineCreateCommand::Aabb(ref config) => hash_with_seed(config, 0xAABB),
|
PipelineCreateCommand::Aabb(ref config) => hash_with_seed(config, 0xAABB),
|
||||||
|
PipelineCreateCommand::TexturedQuad(ref config) => hash_with_seed(config, 0xEEAD),
|
||||||
};
|
};
|
||||||
// TODO queue for creation if not found
|
|
||||||
if !state.pipelines.contains_key(&id) {
|
if !state.pipelines.contains_key(&id) {
|
||||||
let pipeline = match cmd {
|
let pipeline = match cmd {
|
||||||
PipelineCreateCommand::Aabb(ref config) => aabb::construct_pipeline(
|
PipelineCreateCommand::Aabb(ref config) => aabb::construct_pipeline(
|
||||||
|
@ -465,14 +497,26 @@ fn pipeline_ref(cmd: PipelineCreateCommand) -> PipelineRef {
|
||||||
&state.aabb,
|
&state.aabb,
|
||||||
config,
|
config,
|
||||||
),
|
),
|
||||||
|
PipelineCreateCommand::TexturedQuad(ref config) => textured_quad::construct_pipeline(
|
||||||
|
state.device.as_ref(),
|
||||||
|
&state.graphics_config,
|
||||||
|
&state.textured_quad,
|
||||||
|
config,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
state.pipelines.insert(id, pipeline);
|
state.pipelines.insert(id, pipeline);
|
||||||
}
|
}
|
||||||
|
id
|
||||||
|
}
|
||||||
|
fn pipeline_ref(cmd: &PipelineCreateCommand) -> PipelineRef {
|
||||||
|
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||||
|
// TODO queue for creation if not found
|
||||||
|
let id = construct_pipeline(state, cmd);
|
||||||
PipelineRef { id }
|
PipelineRef { id }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_pipeline(pipeline_ref: PipelineRef, pass: &mut wgpu::RenderPass) -> bool {
|
fn bind_pipeline(pipeline_ref: PipelineRef, pass: &mut wgpu::RenderPass) -> bool {
|
||||||
let state = unsafe { STATE.as_ref().unwrap() };
|
let state = unsafe { STATE.as_ref().unwrap_unchecked() };
|
||||||
if pipeline_ref.id == state.current_pipeline {
|
if pipeline_ref.id == state.current_pipeline {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -484,7 +528,7 @@ fn bind_pipeline(pipeline_ref: PipelineRef, pass: &mut wgpu::RenderPass) -> bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn render_into_pass(pass: &mut wgpu::RenderPass) {
|
pub(crate) fn render_into_pass(pass: &mut wgpu::RenderPass) {
|
||||||
let state = unsafe { STATE.as_mut().unwrap() };
|
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||||
{
|
{
|
||||||
let global_buffers = unsafe { &mut GLOBAL_BUFFERS };
|
let global_buffers = unsafe { &mut GLOBAL_BUFFERS };
|
||||||
state.queue.write_buffer(&state.buffers.vertex_buffer, 0, &global_buffers.verts);
|
state.queue.write_buffer(&state.buffers.vertex_buffer, 0, &global_buffers.verts);
|
||||||
|
@ -512,6 +556,9 @@ pub(crate) fn render_into_pass(pass: &mut wgpu::RenderPass) {
|
||||||
ShaderDrawCommand::Aabb(data) => {
|
ShaderDrawCommand::Aabb(data) => {
|
||||||
aabb::draw_aabb(data, &state.aabb, pass, &state.buffers);
|
aabb::draw_aabb(data, &state.aabb, pass, &state.buffers);
|
||||||
}
|
}
|
||||||
|
ShaderDrawCommand::TexturedQuad(data) => {
|
||||||
|
textured_quad::draw_textured_quad(data, &state.textured_quad, pass, &state.buffers);
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -554,15 +601,15 @@ fn finalize_global_uniform() -> Range<u64> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_draw_command(cmd: ShaderDrawCommand) {
|
fn push_draw_command(cmd: ShaderDrawCommand) {
|
||||||
let state = unsafe { STATE.as_mut().unwrap() };
|
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||||
state.commands.push_back(Command::Draw(cmd));
|
state.commands.push_back(Command::Draw(cmd));
|
||||||
}
|
}
|
||||||
fn set_viewport(rect: CRectangle, znear: f32, zfar: f32) {
|
fn set_viewport(rect: CRectangle, znear: f32, zfar: f32) {
|
||||||
let state = unsafe { STATE.as_mut().unwrap() };
|
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||||
state.commands.push_back(Command::SetViewport(rect, znear, zfar));
|
state.commands.push_back(Command::SetViewport(rect, znear, zfar));
|
||||||
}
|
}
|
||||||
fn set_scissor(x: u32, y: u32, w: u32, h: u32) {
|
fn set_scissor(x: u32, y: u32, w: u32, h: u32) {
|
||||||
let state = unsafe { STATE.as_mut().unwrap() };
|
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||||
state.commands.push_back(Command::SetScissor(x, y, w, h));
|
state.commands.push_back(Command::SetScissor(x, y, w, h));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,349 @@
|
||||||
|
struct PassTrait {
|
||||||
|
constant_color: vec4<f32>;
|
||||||
|
tex_idx: i32;
|
||||||
|
uv_source: i32;
|
||||||
|
tcg_mtx_idx: i32;
|
||||||
|
normalize: u32;
|
||||||
|
sample_alpha: u32;
|
||||||
|
has_constant_color: u32;
|
||||||
|
};
|
||||||
|
struct TCGUniform {
|
||||||
|
mode: i32;
|
||||||
|
f0: f32;
|
||||||
|
f1: f32;
|
||||||
|
f2: f32;
|
||||||
|
f3: f32;
|
||||||
|
f4: f32;
|
||||||
|
f5: f32;
|
||||||
|
f6: f32;
|
||||||
|
f7: f32;
|
||||||
|
f8: f32;
|
||||||
|
pad1: u32;
|
||||||
|
pad2: u32;
|
||||||
|
};
|
||||||
|
struct ConstShaderTraits {
|
||||||
|
shader_type: u32;
|
||||||
|
world_shadow: u32;
|
||||||
|
short_uvs: u32;
|
||||||
|
alpha_discard: u32;
|
||||||
|
samus_reflection: u32;
|
||||||
|
@align(16) tcgs: @stride(48) array<TCGUniform, 4>;
|
||||||
|
};
|
||||||
|
struct MutShaderTraits {
|
||||||
|
post_type: u32;
|
||||||
|
game_blend_mode: u32;
|
||||||
|
model_flags: u32;
|
||||||
|
};
|
||||||
|
struct ConstTraits {
|
||||||
|
shader: ConstShaderTraits;
|
||||||
|
lightmap: PassTrait;
|
||||||
|
diffuse: PassTrait;
|
||||||
|
diffuse_mod: PassTrait;
|
||||||
|
emissive: PassTrait;
|
||||||
|
specular: PassTrait;
|
||||||
|
extended_specular: PassTrait;
|
||||||
|
reflection: PassTrait;
|
||||||
|
alpha: PassTrait;
|
||||||
|
alpha_mod: PassTrait;
|
||||||
|
};
|
||||||
|
@group(2) @binding(10)
|
||||||
|
var<uniform> c_traits: ConstTraits;
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
pos: vec3<f32>;
|
||||||
|
dir: vec3<f32>;
|
||||||
|
color: vec4<f32>;
|
||||||
|
lin_att: vec3<f32>;
|
||||||
|
ang_att: vec3<f32>;
|
||||||
|
};
|
||||||
|
struct FogState {
|
||||||
|
color: vec4<f32>;
|
||||||
|
a: f32;
|
||||||
|
b: f32;
|
||||||
|
c: f32;
|
||||||
|
mode: u32;
|
||||||
|
};
|
||||||
|
struct ModelUniform {
|
||||||
|
position: vec3<f32>;
|
||||||
|
orientation: vec3<f32>;
|
||||||
|
scale: vec3<f32>;
|
||||||
|
ambient_color: vec4<f32>;
|
||||||
|
lights: array<Light, 8>;
|
||||||
|
};
|
||||||
|
struct GlobalUniform {
|
||||||
|
view: mat4x4<f32>;
|
||||||
|
proj: mat4x4<f32>;
|
||||||
|
ambient: vec4<f32>;
|
||||||
|
lightmap_mul: vec4<f32>;
|
||||||
|
fog: FogState;
|
||||||
|
seconds: f32;
|
||||||
|
};
|
||||||
|
@group(1) @binding(0)
|
||||||
|
var<uniform> u_model: ModelUniform;
|
||||||
|
@group(1) @binding(1)
|
||||||
|
var<uniform> u_global: GlobalUniform;
|
||||||
|
@group(1) @binding(2)
|
||||||
|
var<uniform> u_traits: MutShaderTraits;
|
||||||
|
|
||||||
|
@group(2) @binding(0)
|
||||||
|
var t_lightmap: texture_2d<f32>;
|
||||||
|
@group(2) @binding(1)
|
||||||
|
var t_diffuse: texture_2d<f32>;
|
||||||
|
@group(2) @binding(2)
|
||||||
|
var t_diffuse_mod: texture_2d<f32>;
|
||||||
|
@group(2) @binding(3)
|
||||||
|
var t_emissive: texture_2d<f32>;
|
||||||
|
@group(2) @binding(4)
|
||||||
|
var t_specular: texture_2d<f32>;
|
||||||
|
@group(2) @binding(5)
|
||||||
|
var t_extended_specular: texture_2d<f32>;
|
||||||
|
@group(2) @binding(6)
|
||||||
|
var t_reflection: texture_2d<f32>;
|
||||||
|
@group(2) @binding(7)
|
||||||
|
var t_alpha: texture_2d<f32>;
|
||||||
|
@group(2) @binding(8)
|
||||||
|
var t_alpha_mod: texture_2d<f32>;
|
||||||
|
@group(2) @binding(9)
|
||||||
|
var t_material: texture_2d<f32>;
|
||||||
|
|
||||||
|
@group(3) @binding(0)
|
||||||
|
var s_repeat: sampler;
|
||||||
|
@group(3) @binding(1)
|
||||||
|
var s_clamp: sampler;
|
||||||
|
@group(3) @binding(2)
|
||||||
|
var s_reflect: sampler;
|
||||||
|
@group(3) @binding(3)
|
||||||
|
var s_clamp_edge: sampler;
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
@builtin(position) position: vec4<f32>;
|
||||||
|
@location(0) lighting: vec3<f32>;
|
||||||
|
@location(1) uv_lightmap: vec2<f32>;
|
||||||
|
@location(2) uv_diffuse: vec2<f32>;
|
||||||
|
@location(3) uv_diffuse_mod: vec2<f32>;
|
||||||
|
@location(4) uv_emissive: vec2<f32>;
|
||||||
|
@location(5) uv_specular: vec2<f32>;
|
||||||
|
@location(6) uv_extended_specular: vec2<f32>;
|
||||||
|
@location(7) uv_reflection: vec2<f32>;
|
||||||
|
@location(8) uv_alpha: vec2<f32>;
|
||||||
|
@location(9) uv_alpha_mod: vec2<f32>;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn make_rotate_x(r: f32) -> mat4x4<f32> {
|
||||||
|
var s = sin(r);
|
||||||
|
var c = cos(r);
|
||||||
|
return mat4x4<f32>(
|
||||||
|
vec4<f32>(1.0, 0.0, 0.0, 0.0),
|
||||||
|
vec4<f32>(0.0, c, s, 0.0),
|
||||||
|
vec4<f32>(0.0, -s, c, 0.0),
|
||||||
|
vec4<f32>(0.0, 0.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_rotate_y(r: f32) -> mat4x4<f32> {
|
||||||
|
var s = sin(r);
|
||||||
|
var c = cos(r);
|
||||||
|
return mat4x4<f32>(
|
||||||
|
vec4<f32>(c, 0.0, -s, 0.0),
|
||||||
|
vec4<f32>(0.0, 1.0, 0.0, 0.0),
|
||||||
|
vec4<f32>(s, 0.0, c, 0.0),
|
||||||
|
vec4<f32>(0.0, 0.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_rotate_z(r: f32) -> mat4x4<f32> {
|
||||||
|
var s = sin(r);
|
||||||
|
var c = cos(r);
|
||||||
|
return mat4x4<f32>(
|
||||||
|
vec4<f32>(c, s, 0.0, 0.0),
|
||||||
|
vec4<f32>(-s, c, 0.0, 0.0),
|
||||||
|
vec4<f32>(0.0, 0.0, 1.0, 0.0),
|
||||||
|
vec4<f32>(0.0, 0.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_rotate(r: vec3<f32>) -> mat4x4<f32> {
|
||||||
|
return make_rotate_z(r.z)
|
||||||
|
* make_rotate_y(r.y)
|
||||||
|
* make_rotate_x(r.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_scale(s: vec3<f32>) -> mat4x4<f32> {
|
||||||
|
return mat4x4<f32>(
|
||||||
|
vec4<f32>(s.x, 0.0, 0.0, 0.0),
|
||||||
|
vec4<f32>(0.0, s.y, 0.0, 0.0),
|
||||||
|
vec4<f32>(0.0, 0.0, s.z, 0.0),
|
||||||
|
vec4<f32>(0.0, 0.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_translate(translate: vec3<f32>) -> mat4x4<f32> {
|
||||||
|
return mat4x4<f32>(
|
||||||
|
vec4<f32>(1.0, 0.0, 0.0, 0.0),
|
||||||
|
vec4<f32>(0.0, 1.0, 0.0, 0.0),
|
||||||
|
vec4<f32>(0.0, 0.0, 1.0, 0.0),
|
||||||
|
vec4<f32>(translate, 1.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TCGMatrix {
|
||||||
|
mtx: mat4x4<f32>;
|
||||||
|
post_mtx: mat4x4<f32>;
|
||||||
|
};
|
||||||
|
|
||||||
|
let identity_mtx: mat4x4<f32> = mat4x4<f32>(
|
||||||
|
vec4<f32>(1.0, 0.0, 0.0, 0.0),
|
||||||
|
vec4<f32>(0.0, 1.0, 0.0, 0.0),
|
||||||
|
vec4<f32>(0.0, 0.0, 1.0, 0.0),
|
||||||
|
vec4<f32>(0.0, 0.0, 0.0, 1.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
fn process_uv_anim(
|
||||||
|
model_matrix: ptr<function, mat4x4<f32>>,
|
||||||
|
mv_inv: ptr<function, mat4x4<f32>>,
|
||||||
|
traits: PassTrait,
|
||||||
|
) -> TCGMatrix {
|
||||||
|
var out = TCGMatrix(identity_mtx, identity_mtx);
|
||||||
|
var tu = c_traits.shader.tcgs[traits.tcg_mtx_idx];
|
||||||
|
switch (tu.mode) {
|
||||||
|
case 0: {
|
||||||
|
out.mtx = *mv_inv;
|
||||||
|
out.mtx[3][3] = 1.0;
|
||||||
|
out.post_mtx[0][0] = 0.5;
|
||||||
|
out.post_mtx[1][1] = 0.5;
|
||||||
|
out.post_mtx[3][0] = 0.5;
|
||||||
|
out.post_mtx[3][1] = 0.5;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
out.mtx = *mv_inv;
|
||||||
|
out.mtx[3] = u_global.view * vec4<f32>(u_model.position, 1.0);
|
||||||
|
out.mtx[3][3] = 1.0;
|
||||||
|
out.post_mtx[0][0] = 0.5;
|
||||||
|
out.post_mtx[1][1] = 0.5;
|
||||||
|
out.post_mtx[3][0] = 0.5;
|
||||||
|
out.post_mtx[3][1] = 0.5;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
out.mtx[3][0] = u_global.seconds * tu.f2 + tu.f0;
|
||||||
|
out.mtx[3][1] = u_global.seconds * tu.f3 + tu.f1;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
var angle = u_global.seconds * tu.f1 + tu.f0;
|
||||||
|
var acos = cos(angle);
|
||||||
|
var asin = sin(angle);
|
||||||
|
out.mtx[0][0] = acos;
|
||||||
|
out.mtx[0][1] = asin;
|
||||||
|
out.mtx[1][0] = -asin;
|
||||||
|
out.mtx[1][1] = acos;
|
||||||
|
out.mtx[3][0] = (1.0 - (acos - asin)) * 0.5;
|
||||||
|
out.mtx[3][1] = (1.0 - (asin + acos)) * 0.5;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
var n: f32 = tu.f2 * tu.f0 * (tu.f3 + u_global.seconds);
|
||||||
|
out.mtx[3][0] = trunc(tu.f1 * fract(n)) * tu.f2;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
var n: f32 = tu.f2 * tu.f0 * (tu.f3 + u_global.seconds);
|
||||||
|
out.mtx[3][1] = trunc(tu.f1 * fract(n)) * tu.f2;
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
let pos = u_model.position;
|
||||||
|
out.mtx = *model_matrix;
|
||||||
|
out.mtx[3] = vec4<f32>(0.0, 0.0, 0.0, 1.0);
|
||||||
|
out.post_mtx[0][0] = 0.5;
|
||||||
|
out.post_mtx[1][1] = 0.0;
|
||||||
|
out.post_mtx[2][1] = 0.5;
|
||||||
|
out.post_mtx[3][0] = pos.x * 0.05;
|
||||||
|
out.post_mtx[3][1] = pos.y * 0.05;
|
||||||
|
}
|
||||||
|
default: {}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn t_sample(
|
||||||
|
traits: PassTrait,
|
||||||
|
tex: texture_2d<f32>,
|
||||||
|
uv: vec2<f32>,
|
||||||
|
) -> vec3<f32> {
|
||||||
|
// For control flow uniformity, we always have to sample
|
||||||
|
var color: vec4<f32> = textureSample(tex, s_repeat, uv);
|
||||||
|
if (traits.has_constant_color == 1u) {
|
||||||
|
color = traits.constant_color;
|
||||||
|
}
|
||||||
|
if (traits.sample_alpha == 1u) {
|
||||||
|
return vec3<f32>(color.w);
|
||||||
|
}
|
||||||
|
return color.xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
let kRGBToYPrime: vec3<f32> = vec3<f32>(0.299, 0.587, 0.114);
|
||||||
|
|
||||||
|
fn t_sample_alpha(
|
||||||
|
traits: PassTrait,
|
||||||
|
tex: texture_2d<f32>,
|
||||||
|
uv: vec2<f32>,
|
||||||
|
) -> f32 {
|
||||||
|
// For control flow uniformity, we always have to sample
|
||||||
|
var color: vec4<f32> = textureSample(tex, s_repeat, uv);
|
||||||
|
if (traits.has_constant_color == 1u) {
|
||||||
|
color = traits.constant_color;
|
||||||
|
}
|
||||||
|
if (traits.sample_alpha == 1u) {
|
||||||
|
return color.w;
|
||||||
|
}
|
||||||
|
return dot(color.xyz, kRGBToYPrime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@stage(fragment)
|
||||||
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
|
var color: vec4<f32>;
|
||||||
|
|
||||||
|
let mat_sample = textureSample(t_material, s_repeat, in.uv_diffuse);
|
||||||
|
|
||||||
|
if (c_traits.shader.shader_type == 0u) {
|
||||||
|
// Invalid
|
||||||
|
color = vec4<f32>(
|
||||||
|
t_sample(c_traits.diffuse, t_diffuse, in.uv_diffuse),
|
||||||
|
t_sample_alpha(c_traits.alpha, t_alpha, in.uv_alpha)
|
||||||
|
);
|
||||||
|
} else if (c_traits.shader.shader_type == 1u) {
|
||||||
|
// RetroShader
|
||||||
|
var rgb = t_sample(c_traits.lightmap, t_lightmap, in.uv_lightmap)
|
||||||
|
* u_global.lightmap_mul.xyz + in.lighting;
|
||||||
|
rgb = rgb * t_sample(c_traits.diffuse, t_diffuse, in.uv_diffuse)
|
||||||
|
+ t_sample(c_traits.emissive, t_emissive, in.uv_emissive);
|
||||||
|
let specular = t_sample(c_traits.specular, t_specular, in.uv_specular)
|
||||||
|
+ t_sample(c_traits.extended_specular, t_extended_specular, in.uv_extended_specular)
|
||||||
|
* in.lighting;
|
||||||
|
rgb = rgb + specular * t_sample(c_traits.reflection, t_reflection, in.uv_reflection);
|
||||||
|
// TODO DynReflectionSample
|
||||||
|
color = vec4<f32>(rgb, t_sample_alpha(c_traits.alpha, t_alpha, in.uv_alpha)
|
||||||
|
* t_sample_alpha(c_traits.alpha_mod, t_alpha_mod, in.uv_alpha_mod));
|
||||||
|
} else if (c_traits.shader.shader_type == 2u) {
|
||||||
|
// RetroDynamicShader
|
||||||
|
var rgb = t_sample(c_traits.lightmap, t_lightmap, in.uv_lightmap)
|
||||||
|
* u_global.lightmap_mul.xyz + in.lighting;
|
||||||
|
rgb = rgb * t_sample(c_traits.diffuse, t_diffuse, in.uv_diffuse)
|
||||||
|
+ t_sample(c_traits.emissive, t_emissive, in.uv_emissive);
|
||||||
|
let specular = t_sample(c_traits.specular, t_specular, in.uv_specular)
|
||||||
|
+ t_sample(c_traits.extended_specular, t_extended_specular, in.uv_extended_specular)
|
||||||
|
* in.lighting;
|
||||||
|
rgb = rgb + specular * t_sample(c_traits.reflection, t_reflection, in.uv_reflection);
|
||||||
|
// TODO DynReflectionSample
|
||||||
|
color = vec4<f32>(rgb, t_sample_alpha(c_traits.alpha, t_alpha, in.uv_alpha)
|
||||||
|
* t_sample_alpha(c_traits.alpha_mod, t_alpha_mod, in.uv_alpha_mod));
|
||||||
|
} else {
|
||||||
|
// TODO RetroDynamicAlphaShader + RetroDynamicCharacterShader
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO fog shader
|
||||||
|
|
||||||
|
// TODO post type
|
||||||
|
|
||||||
|
if (c_traits.shader.alpha_discard == 1u && color.w < 0.25) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
struct Vec3Block {
|
||||||
|
data: @stride(16) array<vec3<f32>>;
|
||||||
|
};
|
||||||
|
struct Vec2Block {
|
||||||
|
data: @stride(8) array<vec2<f32>>;
|
||||||
|
};
|
||||||
|
struct TCGUniforms {
|
||||||
|
data: array<TCGUniform>;
|
||||||
|
};
|
||||||
|
|
||||||
|
@group(0) @binding(0)
|
||||||
|
var<storage, read> v_verts: Vec3Block;
|
||||||
|
@group(0) @binding(1)
|
||||||
|
var<storage, read> v_norms: Vec3Block;
|
||||||
|
@group(0) @binding(2)
|
||||||
|
var<storage, read> v_uvs: Vec2Block;
|
||||||
|
@group(0) @binding(3)
|
||||||
|
var<storage, read> v_short_uvs: Vec2Block;
|
||||||
|
//@group(0) @binding(4)
|
||||||
|
//var<uniform> v_tcg: TCGUniforms;
|
||||||
|
|
||||||
|
fn calculate_tcg(
|
||||||
|
traits: PassTrait,
|
||||||
|
obj_pos: ptr<function, vec4<f32>>,
|
||||||
|
obj_norm: ptr<function, vec4<f32>>,
|
||||||
|
model_matrix: ptr<function, mat4x4<f32>>,
|
||||||
|
mv_inv: ptr<function, mat4x4<f32>>,
|
||||||
|
uv_0_4_idx: vec4<i32>,
|
||||||
|
uv_4_7_idx: vec4<i32>,
|
||||||
|
) -> vec2<f32> {
|
||||||
|
if (traits.uv_source == -1) {
|
||||||
|
return vec2<f32>(0.0);
|
||||||
|
}
|
||||||
|
if (traits.tcg_mtx_idx >= 0) {
|
||||||
|
var src: vec4<f32>;
|
||||||
|
switch (traits.uv_source) {
|
||||||
|
case 0: { src = vec4<f32>((*obj_pos).xyz, 1.0); }
|
||||||
|
case 1: { src = vec4<f32>((*obj_norm).xyz, 1.0); }
|
||||||
|
case 2: {
|
||||||
|
if (c_traits.shader.short_uvs == 1u) {
|
||||||
|
src = vec4<f32>(v_short_uvs.data[uv_0_4_idx.x], 0.0, 1.0);
|
||||||
|
} else {
|
||||||
|
src = vec4<f32>(v_uvs.data[uv_0_4_idx.x], 0.0, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 3: { src = vec4<f32>(v_uvs.data[uv_0_4_idx.y], 0.0, 1.0); }
|
||||||
|
case 4: { src = vec4<f32>(v_uvs.data[uv_0_4_idx.z], 0.0, 1.0); }
|
||||||
|
case 5: { src = vec4<f32>(v_uvs.data[uv_0_4_idx.w], 0.0, 1.0); }
|
||||||
|
case 6: { src = vec4<f32>(v_uvs.data[uv_4_7_idx.x], 0.0, 1.0); }
|
||||||
|
case 7: { src = vec4<f32>(v_uvs.data[uv_4_7_idx.y], 0.0, 1.0); }
|
||||||
|
case 8: { src = vec4<f32>(v_uvs.data[uv_4_7_idx.z], 0.0, 1.0); }
|
||||||
|
default: {}
|
||||||
|
}
|
||||||
|
let tcgm = process_uv_anim(model_matrix, mv_inv, traits);
|
||||||
|
var tmp = (tcgm.mtx * src).xyz;
|
||||||
|
if (traits.normalize == 1u) {
|
||||||
|
tmp = normalize(tmp);
|
||||||
|
}
|
||||||
|
let tmp_proj = tcgm.post_mtx * vec4<f32>(tmp, 1.0);
|
||||||
|
return (tmp_proj / tmp_proj.w).xy;
|
||||||
|
} else {
|
||||||
|
switch (traits.uv_source) {
|
||||||
|
case 0: { return (*obj_pos).xy; }
|
||||||
|
case 1: { return (*obj_norm).xy; }
|
||||||
|
case 2: {
|
||||||
|
if (c_traits.shader.short_uvs == 1u) {
|
||||||
|
return v_short_uvs.data[uv_0_4_idx.x];
|
||||||
|
} else {
|
||||||
|
return v_uvs.data[uv_0_4_idx.x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 3: { return v_uvs.data[uv_0_4_idx.y]; }
|
||||||
|
case 4: { return v_uvs.data[uv_0_4_idx.z]; }
|
||||||
|
case 5: { return v_uvs.data[uv_0_4_idx.w]; }
|
||||||
|
case 6: { return v_uvs.data[uv_4_7_idx.x]; }
|
||||||
|
case 7: { return v_uvs.data[uv_4_7_idx.y]; }
|
||||||
|
case 8: { return v_uvs.data[uv_4_7_idx.z]; }
|
||||||
|
default: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vec2<f32>(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@stage(vertex)
|
||||||
|
fn vs_main(
|
||||||
|
@location(0) pos_norm_idx: vec2<i32>,
|
||||||
|
@location(1) uv_0_4_idx: vec4<i32>,
|
||||||
|
@location(2) uv_4_7_idx: vec4<i32>,
|
||||||
|
) -> VertexOutput {
|
||||||
|
var out: VertexOutput;
|
||||||
|
var obj_pos = vec4<f32>(v_verts.data[pos_norm_idx.x], 1.0);
|
||||||
|
var obj_norm = vec4<f32>(v_norms.data[pos_norm_idx.y], 0.0);
|
||||||
|
var model_matrix_no_trans = make_rotate(radians(u_model.orientation)) * make_scale(u_model.scale);
|
||||||
|
var model_matrix = make_translate(u_model.position) * model_matrix_no_trans;
|
||||||
|
var mv = u_global.view * model_matrix;
|
||||||
|
var mv_inv = transpose(u_global.view * model_matrix_no_trans);
|
||||||
|
var mv_pos = mv * obj_pos;
|
||||||
|
var mv_norm = mv_inv * obj_norm;
|
||||||
|
|
||||||
|
out.position = u_global.proj * mv_pos;
|
||||||
|
out.uv_lightmap = calculate_tcg(c_traits.lightmap, &obj_pos, &obj_norm, &model_matrix, &mv_inv, uv_0_4_idx, uv_4_7_idx);
|
||||||
|
out.uv_diffuse = calculate_tcg(c_traits.diffuse, &obj_pos, &obj_norm, &model_matrix, &mv_inv, uv_0_4_idx, uv_4_7_idx);
|
||||||
|
out.uv_diffuse_mod = calculate_tcg(c_traits.diffuse_mod, &obj_pos, &obj_norm, &model_matrix, &mv_inv, uv_0_4_idx, uv_4_7_idx);
|
||||||
|
out.uv_emissive = calculate_tcg(c_traits.emissive, &obj_pos, &obj_norm, &model_matrix, &mv_inv, uv_0_4_idx, uv_4_7_idx);
|
||||||
|
out.uv_specular = calculate_tcg(c_traits.specular, &obj_pos, &obj_norm, &model_matrix, &mv_inv, uv_0_4_idx, uv_4_7_idx);
|
||||||
|
out.uv_extended_specular = calculate_tcg(c_traits.extended_specular, &obj_pos, &obj_norm, &model_matrix, &mv_inv, uv_0_4_idx, uv_4_7_idx);
|
||||||
|
out.uv_reflection = calculate_tcg(c_traits.reflection, &obj_pos, &obj_norm, &model_matrix, &mv_inv, uv_0_4_idx, uv_4_7_idx);
|
||||||
|
out.uv_alpha = calculate_tcg(c_traits.alpha, &obj_pos, &obj_norm, &model_matrix, &mv_inv, uv_0_4_idx, uv_4_7_idx);
|
||||||
|
out.uv_alpha_mod = calculate_tcg(c_traits.alpha_mod, &obj_pos, &obj_norm, &model_matrix, &mv_inv, uv_0_4_idx, uv_4_7_idx);
|
||||||
|
|
||||||
|
if (c_traits.shader.samus_reflection == 1u) {
|
||||||
|
// TODO dyn reflection
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u_traits.post_type > 0u && u_traits.post_type < 5u) {
|
||||||
|
out.lighting = vec3<f32>(1.0);
|
||||||
|
} else {
|
||||||
|
var lighting = u_global.ambient.xyz + u_model.ambient_color.xyz;
|
||||||
|
for (var i = 0; i < 8; i = i + 1) {
|
||||||
|
var light = u_model.lights[i];
|
||||||
|
var delta = mv_pos.xyz - light.pos;
|
||||||
|
var dist = length(delta);
|
||||||
|
var delta_norm = delta / dist;
|
||||||
|
var ang_dot = max(dot(delta_norm, light.dir), 0.0);
|
||||||
|
var lin_att = light.lin_att;
|
||||||
|
var att = 1.0 / (lin_att.z * dist * dist * lin_att.y * dist + lin_att.x);
|
||||||
|
var ang_att = light.ang_att;
|
||||||
|
var ang_att_d = ang_att.z * ang_dot * ang_dot * ang_att.y * ang_dot + ang_att.x;
|
||||||
|
var this_color = light.color.xyz * ang_att_d * att * max(dot(-delta_norm, mv_norm.xyz), 0.0);
|
||||||
|
if (i == 0 && c_traits.shader.world_shadow == 1u) {
|
||||||
|
// TODO ExtTex0 sample
|
||||||
|
}
|
||||||
|
lighting = lighting + this_color;
|
||||||
|
}
|
||||||
|
out.lighting = clamp(lighting, vec3<f32>(0.0), vec3<f32>(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO dyn reflection sample
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
fn calculate_tcg(
|
||||||
|
traits: PassTrait,
|
||||||
|
uv_in: vec3<f32>,
|
||||||
|
obj_pos: ptr<function, vec4<f32>>,
|
||||||
|
obj_norm: ptr<function, vec4<f32>>,
|
||||||
|
model_matrix: ptr<function, mat4x4<f32>>,
|
||||||
|
mv_inv: ptr<function, mat4x4<f32>>,
|
||||||
|
) -> vec2<f32> {
|
||||||
|
var uv: vec4<f32> = vec4<f32>(uv_in, 1.0);
|
||||||
|
if (traits.tcg_mtx_idx >= 0) {
|
||||||
|
let tcgm = process_uv_anim(model_matrix, mv_inv, traits);
|
||||||
|
var tmp = (tcgm.mtx * uv).xyz;
|
||||||
|
if (traits.normalize == 1u) {
|
||||||
|
tmp = normalize(tmp);
|
||||||
|
}
|
||||||
|
let tmp_proj = tcgm.post_mtx * vec4<f32>(tmp, 1.0);
|
||||||
|
return (tmp_proj / tmp_proj.w).xy;
|
||||||
|
}
|
||||||
|
return uv.xy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@stage(vertex)
|
||||||
|
fn vs_main(
|
||||||
|
@location(0) pos: vec3<f32>,
|
||||||
|
@location(1) norm: vec3<f32>,
|
||||||
|
@location(2) in_uv_lightmap: vec3<f32>,
|
||||||
|
@location(3) in_uv_diffuse: vec2<f32>,
|
||||||
|
@location(4) in_uv_diffuse_mod: vec2<f32>,
|
||||||
|
@location(5) in_uv_emissive: vec2<f32>,
|
||||||
|
@location(6) in_uv_specular: vec2<f32>,
|
||||||
|
@location(7) in_uv_extended_specular: vec2<f32>,
|
||||||
|
@location(8) in_uv_reflection: vec2<f32>,
|
||||||
|
@location(9) in_uv_alpha: vec2<f32>,
|
||||||
|
@location(10) in_uv_alpha_mod: vec2<f32>,
|
||||||
|
) -> VertexOutput {
|
||||||
|
var out: VertexOutput;
|
||||||
|
var obj_pos = vec4<f32>(pos, 1.0);
|
||||||
|
var obj_norm = vec4<f32>(norm, 0.0);
|
||||||
|
var model_matrix_no_trans = make_rotate(radians(u_model.orientation)) * make_scale(u_model.scale);
|
||||||
|
var model_matrix = make_translate(u_model.position) * model_matrix_no_trans;
|
||||||
|
var mv = u_global.view * model_matrix;
|
||||||
|
var mv_inv = transpose(u_global.view * model_matrix_no_trans);
|
||||||
|
var mv_pos = mv * obj_pos;
|
||||||
|
var mv_norm = mv_inv * obj_norm;
|
||||||
|
|
||||||
|
out.position = u_global.proj * mv_pos;
|
||||||
|
out.uv_lightmap = calculate_tcg(c_traits.lightmap, in_uv_lightmap, &obj_pos, &obj_norm, &model_matrix, &mv_inv);
|
||||||
|
out.uv_diffuse = calculate_tcg(c_traits.diffuse, vec3<f32>(in_uv_diffuse, 0.0), &obj_pos, &obj_norm, &model_matrix, &mv_inv);
|
||||||
|
out.uv_diffuse_mod = calculate_tcg(c_traits.diffuse_mod, vec3<f32>(in_uv_diffuse_mod, 0.0), &obj_pos, &obj_norm, &model_matrix, &mv_inv);
|
||||||
|
out.uv_emissive = calculate_tcg(c_traits.emissive, vec3<f32>(in_uv_emissive, 0.0), &obj_pos, &obj_norm, &model_matrix, &mv_inv);
|
||||||
|
out.uv_specular = calculate_tcg(c_traits.specular, vec3<f32>(in_uv_specular, 0.0), &obj_pos, &obj_norm, &model_matrix, &mv_inv);
|
||||||
|
out.uv_extended_specular = calculate_tcg(c_traits.extended_specular, vec3<f32>(in_uv_extended_specular, 0.0), &obj_pos, &obj_norm, &model_matrix, &mv_inv);
|
||||||
|
out.uv_reflection = calculate_tcg(c_traits.reflection, vec3<f32>(in_uv_reflection, 0.0), &obj_pos, &obj_norm, &model_matrix, &mv_inv);
|
||||||
|
out.uv_alpha = calculate_tcg(c_traits.alpha, vec3<f32>(in_uv_alpha, 0.0), &obj_pos, &obj_norm, &model_matrix, &mv_inv);
|
||||||
|
out.uv_alpha_mod = calculate_tcg(c_traits.alpha_mod, vec3<f32>(in_uv_alpha_mod, 0.0), &obj_pos, &obj_norm, &model_matrix, &mv_inv);
|
||||||
|
|
||||||
|
if (c_traits.shader.samus_reflection == 1u) {
|
||||||
|
// TODO dyn reflection
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u_traits.post_type > 0u && u_traits.post_type < 5u) {
|
||||||
|
out.lighting = vec3<f32>(1.0);
|
||||||
|
} else {
|
||||||
|
var lighting = u_global.ambient.xyz + u_model.ambient_color.xyz;
|
||||||
|
for (var i = 0; i < 8; i = i + 1) {
|
||||||
|
var light = u_model.lights[i];
|
||||||
|
var delta = mv_pos.xyz - light.pos;
|
||||||
|
var dist = length(delta);
|
||||||
|
var delta_norm = delta / dist;
|
||||||
|
var ang_dot = max(dot(delta_norm, light.dir), 0.0);
|
||||||
|
var lin_att = light.lin_att;
|
||||||
|
var att = 1.0 / (lin_att.z * dist * dist * lin_att.y * dist + lin_att.x);
|
||||||
|
var ang_att = light.ang_att;
|
||||||
|
var ang_att_d = ang_att.z * ang_dot * ang_dot * ang_att.y * ang_dot + ang_att.x;
|
||||||
|
var this_color = light.color.xyz * ang_att_d * att * max(dot(-delta_norm, mv_norm.xyz), 0.0);
|
||||||
|
if (i == 0 && c_traits.shader.world_shadow == 1u) {
|
||||||
|
// TODO ExtTex0 sample
|
||||||
|
}
|
||||||
|
lighting = lighting + this_color;
|
||||||
|
}
|
||||||
|
out.lighting = clamp(lighting, vec3<f32>(0.0), vec3<f32>(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO dyn reflection sample
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
|
@ -1,17 +1,20 @@
|
||||||
use std::ptr::null;
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::num::NonZeroU8;
|
||||||
|
|
||||||
use cxx::SharedPtr;
|
use twox_hash::XxHash32;
|
||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
get_app,
|
get_app,
|
||||||
gpu::TextureWithSampler,
|
shaders::{
|
||||||
shaders::ffi::{TextureClampMode, TextureFormat, TextureRef},
|
ffi::{TextureFormat, TextureRef},
|
||||||
|
STATE,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) struct TextureWithView {
|
pub(crate) struct TextureWithView {
|
||||||
texture: wgpu::Texture,
|
pub(crate) texture: wgpu::Texture,
|
||||||
view: wgpu::TextureView,
|
pub(crate) view: wgpu::TextureView,
|
||||||
}
|
}
|
||||||
impl TextureWithView {
|
impl TextureWithView {
|
||||||
fn new(texture: wgpu::Texture) -> Self {
|
fn new(texture: wgpu::Texture) -> Self {
|
||||||
|
@ -21,12 +24,8 @@ impl TextureWithView {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct RenderTexture {
|
pub(crate) struct RenderTexture {
|
||||||
color_texture: Option<TextureWithView>,
|
pub(crate) color_texture: Option<TextureWithView>,
|
||||||
depth_texture: Option<TextureWithView>,
|
pub(crate) depth_texture: Option<TextureWithView>,
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct Texture {
|
|
||||||
texture: wgpu::Texture,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn create_static_texture_2d(
|
pub(crate) fn create_static_texture_2d(
|
||||||
|
@ -60,7 +59,20 @@ pub(crate) fn create_static_texture_2d(
|
||||||
},
|
},
|
||||||
data,
|
data,
|
||||||
);
|
);
|
||||||
TextureRef { id: u32::MAX }
|
|
||||||
|
// Generate texture hash as ID
|
||||||
|
let mut hasher = XxHash32::with_seed(format.into());
|
||||||
|
width.hash(&mut hasher);
|
||||||
|
height.hash(&mut hasher);
|
||||||
|
mips.hash(&mut hasher);
|
||||||
|
data.hash(&mut hasher);
|
||||||
|
label.hash(&mut hasher);
|
||||||
|
let id = hasher.finish() as u32;
|
||||||
|
|
||||||
|
// Store texture and return reference
|
||||||
|
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||||
|
state.textures.insert(id, TextureWithView::new(texture));
|
||||||
|
TextureRef { id, render: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn create_render_texture(
|
pub(crate) fn create_render_texture(
|
||||||
|
@ -122,8 +134,54 @@ pub(crate) fn create_render_texture(
|
||||||
// anisotropy_clamp: None,
|
// anisotropy_clamp: None,
|
||||||
// border_color,
|
// border_color,
|
||||||
// });
|
// });
|
||||||
RenderTexture { color_texture, depth_texture };
|
|
||||||
TextureRef { id: u32::MAX }
|
// Generate texture hash as ID
|
||||||
|
let mut hasher = XxHash32::default();
|
||||||
|
width.hash(&mut hasher);
|
||||||
|
height.hash(&mut hasher);
|
||||||
|
color_bind_count.hash(&mut hasher);
|
||||||
|
depth_bind_count.hash(&mut hasher);
|
||||||
|
label.hash(&mut hasher);
|
||||||
|
let id = hasher.finish() as u32;
|
||||||
|
|
||||||
|
// Store texture and return reference
|
||||||
|
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||||
|
state.render_textures.insert(id, RenderTexture { color_texture, depth_texture });
|
||||||
|
TextureRef { id, render: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn drop_texture(handle: TextureRef) {}
|
pub(crate) fn drop_texture(handle: TextureRef) {
|
||||||
|
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||||
|
if handle.render {
|
||||||
|
state.render_textures.remove(&handle.id).expect("Render texture already dropped");
|
||||||
|
} else {
|
||||||
|
state.textures.remove(&handle.id).expect("Texture already dropped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_sampler(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
mut address_mode: wgpu::AddressMode,
|
||||||
|
mut border_color: Option<wgpu::SamplerBorderColor>,
|
||||||
|
) -> wgpu::Sampler {
|
||||||
|
if address_mode == wgpu::AddressMode::ClampToBorder
|
||||||
|
&& !device.features().contains(wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER)
|
||||||
|
{
|
||||||
|
address_mode = wgpu::AddressMode::ClampToEdge;
|
||||||
|
border_color = None;
|
||||||
|
}
|
||||||
|
device.create_sampler(&wgpu::SamplerDescriptor {
|
||||||
|
label: None,
|
||||||
|
address_mode_u: address_mode,
|
||||||
|
address_mode_v: address_mode,
|
||||||
|
address_mode_w: address_mode,
|
||||||
|
mag_filter: wgpu::FilterMode::Linear,
|
||||||
|
min_filter: wgpu::FilterMode::Linear,
|
||||||
|
mipmap_filter: wgpu::FilterMode::Linear,
|
||||||
|
lod_min_clamp: 0.0,
|
||||||
|
lod_max_clamp: f32::MAX,
|
||||||
|
compare: None,
|
||||||
|
anisotropy_clamp: NonZeroU8::new(16),
|
||||||
|
border_color,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,317 @@
|
||||||
|
use std::{collections::HashMap, hash::Hash, ops::Range};
|
||||||
|
|
||||||
|
use bytemuck_derive::{Pod, Zeroable};
|
||||||
|
use wgpu::{include_wgsl, vertex_attr_array};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
get_app,
|
||||||
|
gpu::GraphicsConfig,
|
||||||
|
shaders::{
|
||||||
|
bind_pipeline,
|
||||||
|
BuiltBuffers,
|
||||||
|
ffi::{CameraFilterType, TextureRef, ZTest}, pipeline_ref, PipelineCreateCommand, PipelineHolder, PipelineRef,
|
||||||
|
push_draw_command, push_uniform, push_verts, ShaderDrawCommand, STATE,
|
||||||
|
},
|
||||||
|
zeus::{CColor, CMatrix4f, CRectangle, CVector2f, CVector3f, CVector4f},
|
||||||
|
};
|
||||||
|
use crate::shaders::texture::create_sampler;
|
||||||
|
use crate::util::{align, Vec2, Vec3};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) struct DrawData {
|
||||||
|
pipeline: PipelineRef,
|
||||||
|
vert_range: Range<u64>,
|
||||||
|
uniform_range: Range<u64>,
|
||||||
|
texture: TextureRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Hash)]
|
||||||
|
pub(crate) struct PipelineConfig {
|
||||||
|
filter_type: CameraFilterType,
|
||||||
|
z_test: ZTest,
|
||||||
|
}
|
||||||
|
pub(crate) const INITIAL_PIPELINES: &[PipelineCreateCommand] = &[
|
||||||
|
// PipelineCreateCommand::TexturedQuad(PipelineConfig { z_only: false }),
|
||||||
|
// PipelineCreateCommand::TexturedQuad(PipelineConfig { z_only: true }),
|
||||||
|
];
|
||||||
|
|
||||||
|
pub(crate) struct State {
|
||||||
|
shader: wgpu::ShaderModule,
|
||||||
|
uniform_layout: wgpu::BindGroupLayout,
|
||||||
|
uniform_bind_group: wgpu::BindGroup,
|
||||||
|
texture_layout: wgpu::BindGroupLayout,
|
||||||
|
sampler: wgpu::Sampler,
|
||||||
|
pipeline_layout: wgpu::PipelineLayout,
|
||||||
|
// Transient state
|
||||||
|
texture_bind_groups: HashMap<u32, wgpu::BindGroup>,
|
||||||
|
frame_used_textures: Vec<u32>, // TODO use to clear bind groups
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn construct_state(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
_queue: &wgpu::Queue,
|
||||||
|
buffers: &BuiltBuffers,
|
||||||
|
graphics_config: &GraphicsConfig,
|
||||||
|
) -> State {
|
||||||
|
let shader = device.create_shader_module(&include_wgsl!("shader.wgsl"));
|
||||||
|
let uniform_alignment = device.limits().min_uniform_buffer_offset_alignment;
|
||||||
|
let uniform_size = wgpu::BufferSize::new(align(std::mem::size_of::<Uniform>() as u64, uniform_alignment as u64));
|
||||||
|
let uniform_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: Some("Textured Quad Uniform Bind Group Layout"),
|
||||||
|
entries: &[wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Uniform,
|
||||||
|
has_dynamic_offset: true,
|
||||||
|
min_binding_size: uniform_size,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
}, wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 1,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||||
|
count: None,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let sampler = create_sampler(device, wgpu::AddressMode::Repeat, None);
|
||||||
|
let uniform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: Some("Textured Quad Uniform Bind Group"),
|
||||||
|
layout: &uniform_layout,
|
||||||
|
entries: &[wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding {
|
||||||
|
buffer: &buffers.uniform_buffer,
|
||||||
|
offset: 0, // dynamic
|
||||||
|
size: uniform_size,
|
||||||
|
}),
|
||||||
|
}, wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&sampler),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let texture_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: Some("Textured Quad Texture Bind Group Layout"),
|
||||||
|
entries: &[wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Texture {
|
||||||
|
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||||
|
view_dimension: wgpu::TextureViewDimension::D2,
|
||||||
|
multisampled: false,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("Textured Quad Pipeline Layout"),
|
||||||
|
bind_group_layouts: &[&uniform_layout, &texture_layout],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
});
|
||||||
|
State {
|
||||||
|
shader,
|
||||||
|
uniform_layout,
|
||||||
|
uniform_bind_group,
|
||||||
|
texture_layout,
|
||||||
|
sampler,
|
||||||
|
pipeline_layout,
|
||||||
|
texture_bind_groups: Default::default(),
|
||||||
|
frame_used_textures: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn construct_pipeline(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
graphics: &GraphicsConfig,
|
||||||
|
state: &State,
|
||||||
|
config: &PipelineConfig,
|
||||||
|
) -> PipelineHolder {
|
||||||
|
let (blend_component, alpha_write) = match config.filter_type {
|
||||||
|
CameraFilterType::Multiply => (
|
||||||
|
wgpu::BlendComponent {
|
||||||
|
src_factor: wgpu::BlendFactor::Zero,
|
||||||
|
dst_factor: wgpu::BlendFactor::Src,
|
||||||
|
operation: wgpu::BlendOperation::Add,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
CameraFilterType::Add => (
|
||||||
|
wgpu::BlendComponent {
|
||||||
|
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||||
|
dst_factor: wgpu::BlendFactor::One,
|
||||||
|
operation: wgpu::BlendOperation::Add,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
CameraFilterType::Subtract => (
|
||||||
|
wgpu::BlendComponent {
|
||||||
|
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||||
|
dst_factor: wgpu::BlendFactor::One,
|
||||||
|
operation: wgpu::BlendOperation::Subtract,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
CameraFilterType::Blend => (
|
||||||
|
wgpu::BlendComponent {
|
||||||
|
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||||
|
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||||
|
operation: wgpu::BlendOperation::Add,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
CameraFilterType::InvDstMultiply => (
|
||||||
|
wgpu::BlendComponent {
|
||||||
|
src_factor: wgpu::BlendFactor::Zero,
|
||||||
|
dst_factor: wgpu::BlendFactor::OneMinusSrc,
|
||||||
|
operation: wgpu::BlendOperation::Add,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
_ => todo!(),
|
||||||
|
};
|
||||||
|
log::warn!("VERT SIZE: {}", std::mem::size_of::<Vert>() as u64);
|
||||||
|
PipelineHolder {
|
||||||
|
pipeline: device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: Some("Textured Quad Pipeline"),
|
||||||
|
layout: Some(&state.pipeline_layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &state.shader,
|
||||||
|
entry_point: "vs_main",
|
||||||
|
buffers: &[wgpu::VertexBufferLayout {
|
||||||
|
array_stride: std::mem::size_of::<Vert>() as u64,
|
||||||
|
step_mode: wgpu::VertexStepMode::Vertex,
|
||||||
|
attributes: &vertex_attr_array![0 => Float32x3, 1 => Float32x2],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleStrip,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
|
format: graphics.depth_format,
|
||||||
|
depth_write_enabled: config.z_test == ZTest::GEqualZWrite,
|
||||||
|
depth_compare: match config.z_test {
|
||||||
|
ZTest::None => wgpu::CompareFunction::Always,
|
||||||
|
ZTest::LEqual => wgpu::CompareFunction::LessEqual,
|
||||||
|
ZTest::GEqual | ZTest::GEqualZWrite => wgpu::CompareFunction::GreaterEqual,
|
||||||
|
_ => todo!(),
|
||||||
|
},
|
||||||
|
stencil: Default::default(),
|
||||||
|
bias: Default::default(),
|
||||||
|
}),
|
||||||
|
multisample: wgpu::MultisampleState {
|
||||||
|
count: graphics.msaa_samples,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &state.shader,
|
||||||
|
entry_point: "fs_main",
|
||||||
|
targets: &[wgpu::ColorTargetState {
|
||||||
|
format: graphics.color_format,
|
||||||
|
blend: Some(wgpu::BlendState {
|
||||||
|
color: blend_component,
|
||||||
|
alpha: blend_component,
|
||||||
|
}),
|
||||||
|
write_mask: if alpha_write {
|
||||||
|
wgpu::ColorWrites::ALL
|
||||||
|
} else {
|
||||||
|
wgpu::ColorWrites::COLOR
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
multiview: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Pod, Zeroable, Copy, Clone, Default, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct Uniform {
|
||||||
|
xf: CMatrix4f,
|
||||||
|
color: CColor,
|
||||||
|
lod: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Pod, Zeroable, Copy, Clone, Default, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct Vert {
|
||||||
|
pos: Vec3<f32>,
|
||||||
|
uv: Vec2<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn queue_textured_quad(
|
||||||
|
filter_type: CameraFilterType,
|
||||||
|
texture: TextureRef,
|
||||||
|
z_test: ZTest,
|
||||||
|
color: CColor,
|
||||||
|
uv_scale: f32,
|
||||||
|
rect: CRectangle,
|
||||||
|
z: f32,
|
||||||
|
) {
|
||||||
|
let pipeline =
|
||||||
|
pipeline_ref(&PipelineCreateCommand::TexturedQuad(PipelineConfig { filter_type, z_test }));
|
||||||
|
let vert_range = push_verts(&[
|
||||||
|
Vert { pos: Vec3::new(0.0, 0.0, z), uv: Vec2::new(0.0, 0.0) },
|
||||||
|
Vert { pos: Vec3::new(0.0, 1.0, z), uv: Vec2::new(0.0, uv_scale) },
|
||||||
|
Vert { pos: Vec3::new(1.0, 0.0, z), uv: Vec2::new(uv_scale, 0.0) },
|
||||||
|
Vert { pos: Vec3::new(1.0, 1.0, z), uv: Vec2::new(uv_scale, uv_scale) },
|
||||||
|
]);
|
||||||
|
let uniform_range = push_uniform(&Uniform {
|
||||||
|
xf: CMatrix4f::new(
|
||||||
|
CVector4f::new(rect.size.x * 2.0, 0.0, 0.0, 0.0),
|
||||||
|
CVector4f::new(0.0, rect.size.y * 2.0, 0.0, 0.0),
|
||||||
|
CVector4f::new(0.0, 0.0, 1.0, 0.0),
|
||||||
|
CVector4f::new(rect.position.x * 2.0 - 1.0, rect.position.y * 2.0 - 1.0, 0.0, 1.0),
|
||||||
|
),
|
||||||
|
color,
|
||||||
|
lod: 0.0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO defer bind group creation to draw time or another thread?
|
||||||
|
let state = unsafe { STATE.as_mut().unwrap_unchecked() };
|
||||||
|
let groups = &mut state.textured_quad.texture_bind_groups;
|
||||||
|
if !groups.contains_key(&texture.id) {
|
||||||
|
let tex = state.textures.get(&texture.id).unwrap();
|
||||||
|
let bind_group = get_app().gpu.device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: &state.textured_quad.texture_layout,
|
||||||
|
entries: &[wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&tex.view),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
groups.insert(texture.id, bind_group);
|
||||||
|
}
|
||||||
|
|
||||||
|
push_draw_command(ShaderDrawCommand::TexturedQuad(DrawData {
|
||||||
|
pipeline,
|
||||||
|
vert_range,
|
||||||
|
uniform_range,
|
||||||
|
texture,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn draw_textured_quad<'a>(
|
||||||
|
data: &DrawData,
|
||||||
|
state: &'a State,
|
||||||
|
pass: &mut wgpu::RenderPass<'a>,
|
||||||
|
buffers: &'a BuiltBuffers,
|
||||||
|
) {
|
||||||
|
if !bind_pipeline(data.pipeline, pass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uniform bind group
|
||||||
|
pass.set_bind_group(0, &state.uniform_bind_group, &[
|
||||||
|
data.uniform_range.start as wgpu::DynamicOffset
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Texture bind group
|
||||||
|
let texture_bind_group =
|
||||||
|
state.texture_bind_groups.get(&data.texture.id).expect("Failed to find texture bind group");
|
||||||
|
pass.set_bind_group(1, texture_bind_group, &[]);
|
||||||
|
|
||||||
|
// Vertex buffer
|
||||||
|
pass.set_vertex_buffer(0, buffers.vertex_buffer.slice(data.vert_range.clone()));
|
||||||
|
pass.draw(0..4, 0..1);
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
struct Uniform {
|
||||||
|
xf: mat4x4<f32>;
|
||||||
|
color: vec4<f32>;
|
||||||
|
lod: f32;
|
||||||
|
};
|
||||||
|
@group(0) @binding(0)
|
||||||
|
var<uniform> ubuf: Uniform;
|
||||||
|
@group(0) @binding(1)
|
||||||
|
var texture_sampler: sampler;
|
||||||
|
@group(1) @binding(0)
|
||||||
|
var texture: texture_2d<f32>;
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
@builtin(position) pos: vec4<f32>;
|
||||||
|
@location(0) uv: vec2<f32>;
|
||||||
|
};
|
||||||
|
|
||||||
|
@stage(vertex)
|
||||||
|
fn vs_main(@location(0) in_pos: vec3<f32>, @location(1) in_uv: vec2<f32>) -> VertexOutput {
|
||||||
|
var out: VertexOutput;
|
||||||
|
out.pos = ubuf.xf * vec4<f32>(in_pos, 1.0);
|
||||||
|
out.uv = in_uv;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@stage(fragment)
|
||||||
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
|
return ubuf.color * textureSampleBias(texture, texture_sampler, in.uv, ubuf.lod);
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
//! This contains regular vector types for use in packed buffers (i.e. vertex).
|
||||||
|
//! zeus types are all aligned to f32x4
|
||||||
|
use binrw::BinRead;
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, BinRead, Default)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub(crate) struct Vec3<T: 'static + BinRead<Args = ()> + Pod> {
|
||||||
|
pub(crate) x: T,
|
||||||
|
pub(crate) y: T,
|
||||||
|
pub(crate) z: T,
|
||||||
|
}
|
||||||
|
impl<T: 'static + BinRead<Args = ()> + Pod> Vec3<T> {
|
||||||
|
// TODO const
|
||||||
|
pub fn new(x: T, y: T, z: T) -> Self { Self { x, y, z } }
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: BinRead<Args = ()> + Pod> Zeroable for Vec3<T> {}
|
||||||
|
|
||||||
|
unsafe impl<T: BinRead<Args = ()> + Pod> Pod for Vec3<T> {}
|
||||||
|
|
||||||
|
impl<T: BinRead<Args = ()> + Pod> From<T> for Vec3<T> {
|
||||||
|
fn from(v: T) -> Self { Vec3::<T> { x: v, y: v, z: v } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: BinRead<Args = ()> + Pod> From<cgmath::Vector3<T>> for Vec3<T> {
|
||||||
|
fn from(v: cgmath::Vector3<T>) -> Self { Self { x: v.x, y: v.y, z: v.z } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: BinRead<Args = ()> + Pod> From<Vec3<T>> for cgmath::Vector3<T> {
|
||||||
|
fn from(v: Vec3<T>) -> Self { Self { x: v.x, y: v.y, z: v.z } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: BinRead<Args = ()> + Pod> From<cgmath::Point3<T>> for Vec3<T> {
|
||||||
|
fn from(v: cgmath::Point3<T>) -> Self { Self { x: v.x, y: v.y, z: v.z } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: BinRead<Args = ()> + Pod> From<Vec3<T>> for cgmath::Point3<T> {
|
||||||
|
fn from(v: Vec3<T>) -> Self { Self { x: v.x, y: v.y, z: v.z } }
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub(crate) const fn vec3_splat<T: BinRead<Args = ()> + Pod>(v: T) -> Vec3<T> {
|
||||||
|
// Vec3::<T> { x: v, y: v, z: v }
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, BinRead, Default)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub(crate) struct Vec2<T: 'static + BinRead<Args = ()> + Pod> {
|
||||||
|
pub(crate) x: T,
|
||||||
|
pub(crate) y: T,
|
||||||
|
}
|
||||||
|
impl<T: 'static + BinRead<Args = ()> + Pod> Vec2<T> {
|
||||||
|
// TODO const
|
||||||
|
pub fn new(x: T, y: T) -> Self { Self { x, y } }
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: BinRead<Args = ()> + Pod> Zeroable for Vec2<T> {}
|
||||||
|
|
||||||
|
unsafe impl<T: BinRead<Args = ()> + Pod> Pod for Vec2<T> {}
|
||||||
|
|
||||||
|
impl<T: BinRead<Args = ()> + Pod> From<T> for Vec2<T> {
|
||||||
|
fn from(v: T) -> Self { Self { x: v, y: v } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: BinRead<Args = ()> + Pod> From<cgmath::Vector2<T>> for Vec2<T> {
|
||||||
|
fn from(v: cgmath::Vector2<T>) -> Self { Self { x: v.x, y: v.y } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: BinRead<Args = ()> + Pod> From<Vec2<T>> for cgmath::Vector2<T> {
|
||||||
|
fn from(v: Vec2<T>) -> Self { Self { x: v.x, y: v.y } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec2<i16>> for Vec2<f32> {
|
||||||
|
fn from(v: Vec2<i16>) -> Self { Self { x: v.x as f32 / 32768.0, y: v.y as f32 / 32768.0 } }
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub(crate) const fn vec2_splat<T: BinRead<Args = ()> + Pod>(v: T) -> Vec2<T> {
|
||||||
|
// Vec2::<T> { x: v, y: v }
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn align<
|
||||||
|
T: Copy
|
||||||
|
+ std::ops::Sub<Output = T>
|
||||||
|
+ std::ops::Add<Output = T>
|
||||||
|
+ std::ops::Not<Output = T>
|
||||||
|
+ std::ops::BitAnd<Output = T>
|
||||||
|
+ num_traits::One
|
||||||
|
+ num_traits::Zero
|
||||||
|
+ std::cmp::PartialEq,
|
||||||
|
>(
|
||||||
|
n: T,
|
||||||
|
a: T,
|
||||||
|
) -> T {
|
||||||
|
if a == num_traits::Zero::zero() {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
(n + (a - num_traits::One::one())) & !(a - num_traits::One::one())
|
||||||
|
}
|
|
@ -15,13 +15,13 @@ constexpr std::array SplashTextures{"TXTR_NintendoLogo"sv, "TXTR_RetroLogo"sv, "
|
||||||
CSplashScreen::CSplashScreen(ESplashScreen which)
|
CSplashScreen::CSplashScreen(ESplashScreen which)
|
||||||
: CIOWin("SplashScreen")
|
: CIOWin("SplashScreen")
|
||||||
, x14_which(which)
|
, x14_which(which)
|
||||||
, m_quad(EFilterType::Blend, g_SimplePool->GetObj(SplashTextures[size_t(which)])) {}
|
, m_texture(g_SimplePool->GetObj(SplashTextures[size_t(which)])) {}
|
||||||
|
|
||||||
CIOWin::EMessageReturn CSplashScreen::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) {
|
CIOWin::EMessageReturn CSplashScreen::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) {
|
||||||
switch (msg.GetType()) {
|
switch (msg.GetType()) {
|
||||||
case EArchMsgType::TimerTick: {
|
case EArchMsgType::TimerTick: {
|
||||||
if (!x25_textureLoaded) {
|
if (!x25_textureLoaded) {
|
||||||
if (!m_quad.GetTex().IsLoaded())
|
if (!m_texture.IsLoaded())
|
||||||
return EMessageReturn::Exit;
|
return EMessageReturn::Exit;
|
||||||
x25_textureLoaded = true;
|
x25_textureLoaded = true;
|
||||||
}
|
}
|
||||||
|
@ -68,12 +68,20 @@ void CSplashScreen::Draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CRectangle rect;
|
zeus::CRectangle rect;
|
||||||
rect.size.x() = m_quad.GetTex()->GetWidth() / (480.f * g_Viewport.aspect);
|
rect.size.x() = m_texture->GetWidth() / (480.f * g_Viewport.aspect);
|
||||||
rect.size.y() = m_quad.GetTex()->GetHeight() / 480.f;
|
rect.size.y() = m_texture->GetHeight() / 480.f;
|
||||||
rect.position.x() = 0.5f - rect.size.x() / 2.f;
|
rect.position.x() = 0.5f - rect.size.x() / 2.f;
|
||||||
rect.position.y() = 0.5f - rect.size.y() / 2.f;
|
rect.position.y() = 0.5f - rect.size.y() / 2.f;
|
||||||
|
|
||||||
m_quad.draw(color, 1.f, rect);
|
aurora::shaders::queue_textured_quad(
|
||||||
|
aurora::shaders::CameraFilterType::Blend,
|
||||||
|
m_texture->GetTexture()->ref,
|
||||||
|
aurora::shaders::ZTest::None,
|
||||||
|
color,
|
||||||
|
1.f,
|
||||||
|
rect,
|
||||||
|
0.f
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -19,7 +19,7 @@ private:
|
||||||
// EProgressivePhase x20_progressivePhase = EProgressivePhase::Before;
|
// EProgressivePhase x20_progressivePhase = EProgressivePhase::Before;
|
||||||
// bool x24_progressiveSelection = true;
|
// bool x24_progressiveSelection = true;
|
||||||
bool x25_textureLoaded = false;
|
bool x25_textureLoaded = false;
|
||||||
CTexturedQuadFilterAlpha m_quad;
|
TLockedToken<CTexture> m_texture;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CSplashScreen(ESplashScreen);
|
explicit CSplashScreen(ESplashScreen);
|
||||||
|
|
Loading…
Reference in New Issue