mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Started the report of wgpu
This commit is contained in:
parent
f8b642ce86
commit
0a5ef49d05
397
Cargo.lock
generated
397
Cargo.lock
generated
@ -203,6 +203,15 @@ dependencies = [
|
|||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ash"
|
||||||
|
version = "0.31.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c69a8137596e84c22d57f3da1b5de1d4230b1742a710091c85f4d7ce50f00f38"
|
||||||
|
dependencies = [
|
||||||
|
"libloading 0.6.7",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "assets_manager"
|
name = "assets_manager"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
@ -358,6 +367,21 @@ dependencies = [
|
|||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit-set"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
|
||||||
|
dependencies = [
|
||||||
|
"bit-vec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit-vec"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@ -764,6 +788,12 @@ dependencies = [
|
|||||||
"walkdir 0.1.8",
|
"walkdir 0.1.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "copyless"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "copypasta"
|
name = "copypasta"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@ -1219,6 +1249,17 @@ dependencies = [
|
|||||||
"sct",
|
"sct",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "d3d12"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d0a60cceb22c7c53035f8980524fdc7f17cf49681a3c154e6757d30afbec6ec4"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"libloading 0.6.7",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "daggy"
|
name = "daggy"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -1875,6 +1916,152 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gfx-auxil"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07cd956b592970f08545b9325b87580eb95a51843b6f39da27b8667fec1a1216"
|
||||||
|
dependencies = [
|
||||||
|
"fxhash",
|
||||||
|
"gfx-hal",
|
||||||
|
"spirv_cross",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gfx-backend-dx11"
|
||||||
|
version = "0.6.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54b43f06089866bdffe59b5a6801022c86b74d2c1dd28940a9cf301d3d014fbc"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags",
|
||||||
|
"gfx-auxil",
|
||||||
|
"gfx-hal",
|
||||||
|
"libloading 0.6.7",
|
||||||
|
"log",
|
||||||
|
"parking_lot 0.11.1",
|
||||||
|
"range-alloc",
|
||||||
|
"raw-window-handle",
|
||||||
|
"smallvec",
|
||||||
|
"spirv_cross",
|
||||||
|
"thunderdome",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
"wio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gfx-backend-dx12"
|
||||||
|
version = "0.6.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "375014deed24d76b03604736dd899f0925158a1a96db90cbefb9cce070f71af7"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bit-set",
|
||||||
|
"bitflags",
|
||||||
|
"d3d12",
|
||||||
|
"gfx-auxil",
|
||||||
|
"gfx-hal",
|
||||||
|
"log",
|
||||||
|
"range-alloc",
|
||||||
|
"raw-window-handle",
|
||||||
|
"smallvec",
|
||||||
|
"spirv_cross",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gfx-backend-empty"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2085227c12b78f6657a900c829f2d0deb46a9be3eaf86844fde263cdc218f77c"
|
||||||
|
dependencies = [
|
||||||
|
"gfx-hal",
|
||||||
|
"log",
|
||||||
|
"raw-window-handle",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gfx-backend-metal"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "273d60d5207f96d99e0d11d0718995f67e56533a9df1444d83baf787f4c3cb32"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags",
|
||||||
|
"block",
|
||||||
|
"cocoa-foundation",
|
||||||
|
"copyless",
|
||||||
|
"foreign-types",
|
||||||
|
"gfx-auxil",
|
||||||
|
"gfx-hal",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"metal",
|
||||||
|
"objc",
|
||||||
|
"parking_lot 0.11.1",
|
||||||
|
"range-alloc",
|
||||||
|
"raw-window-handle",
|
||||||
|
"smallvec",
|
||||||
|
"spirv_cross",
|
||||||
|
"storage-map",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gfx-backend-vulkan"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a3a63cf61067a09b7d1ac480af3cb2ae0c5ede5bed294607bbd814cb1666c45"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"ash",
|
||||||
|
"byteorder",
|
||||||
|
"core-graphics-types",
|
||||||
|
"gfx-hal",
|
||||||
|
"inplace_it",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"objc",
|
||||||
|
"raw-window-handle",
|
||||||
|
"smallvec",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
"x11",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gfx-descriptor"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd8c7afcd000f279d541a490e27117e61037537279b9342279abf4938fe60c6b"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"fxhash",
|
||||||
|
"gfx-hal",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gfx-hal"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18d0754f5b7a43915fd7466883b2d1bb0800d7cc4609178d0b27bf143b9e5123"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"raw-window-handle",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gfx-memory"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dccdda5d2b39412f4ca2cb15c70b5a82783a86b0606f5e985342754c8ed88f05"
|
||||||
|
dependencies = [
|
||||||
|
"bit-set",
|
||||||
|
"fxhash",
|
||||||
|
"gfx-hal",
|
||||||
|
"log",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx_core"
|
name = "gfx_core"
|
||||||
version = "0.9.2"
|
version = "0.9.2"
|
||||||
@ -2446,6 +2633,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inplace_it"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90953f308a79fe6d62a4643e51f848fbfddcd05975a38e69fdf4ab86a7baf7ca"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@ -2846,6 +3039,20 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "metal"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c4e8a431536529327e28c9ba6992f2cb0c15d4222f0602a16e6d7695ff3bccf"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"block",
|
||||||
|
"cocoa-foundation",
|
||||||
|
"foreign-types",
|
||||||
|
"log",
|
||||||
|
"objc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minifb"
|
name = "minifb"
|
||||||
version = "0.19.1"
|
version = "0.19.1"
|
||||||
@ -2961,6 +3168,20 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238"
|
checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "naga"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0873deb76cf44b7454fba7b2ba6a89d3de70c08aceffd2c489379b3d9d08e661"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"fxhash",
|
||||||
|
"log",
|
||||||
|
"num-traits",
|
||||||
|
"spirv_headers",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "native-dialog"
|
name = "native-dialog"
|
||||||
version = "0.5.5"
|
version = "0.5.5"
|
||||||
@ -3401,6 +3622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"malloc_buf",
|
"malloc_buf",
|
||||||
|
"objc_exception",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3414,6 +3636,15 @@ dependencies = [
|
|||||||
"objc_id",
|
"objc_id",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc_exception"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc_id"
|
name = "objc_id"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -4032,6 +4263,12 @@ dependencies = [
|
|||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "range-alloc"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "raw-window-handle"
|
name = "raw-window-handle"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@ -4807,6 +5044,27 @@ dependencies = [
|
|||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spirv_cross"
|
||||||
|
version = "0.22.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ebd49af36be83ecd6290b57147e2a0e26145b832634b17146d934b197ca3713"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spirv_headers"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f5b132530b1ac069df335577e3581765995cba5a13995cdbbdbc8fb057c532c"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -4885,6 +5143,15 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
|
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "storage-map"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "418bb14643aa55a7841d5303f72cf512cfb323b8cc221d51580500a1ca75206c"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api 0.4.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "str-buf"
|
name = "str-buf"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
@ -4985,6 +5252,18 @@ dependencies = [
|
|||||||
"unicode-xid 0.2.1",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "synstructure"
|
||||||
|
version = "0.12.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.26",
|
||||||
|
"quote 1.0.9",
|
||||||
|
"syn 1.0.69",
|
||||||
|
"unicode-xid 0.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tap"
|
name = "tap"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@ -5069,6 +5348,12 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thunderdome"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7572415bd688d401c52f6e36f4c8e805b9ae1622619303b9fa835d531db0acae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.43"
|
version = "0.1.43"
|
||||||
@ -5353,6 +5638,12 @@ dependencies = [
|
|||||||
"nom 5.1.2",
|
"nom 5.1.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typed-arena"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
@ -5821,6 +6112,7 @@ dependencies = [
|
|||||||
"dot_vox",
|
"dot_vox",
|
||||||
"enum-iterator",
|
"enum-iterator",
|
||||||
"euc",
|
"euc",
|
||||||
|
"futures",
|
||||||
"gfx",
|
"gfx",
|
||||||
"gfx_device_gl",
|
"gfx_device_gl",
|
||||||
"gfx_gl",
|
"gfx_gl",
|
||||||
@ -5866,9 +6158,11 @@ dependencies = [
|
|||||||
"veloren-server",
|
"veloren-server",
|
||||||
"veloren-voxygen-anim",
|
"veloren-voxygen-anim",
|
||||||
"veloren-world",
|
"veloren-world",
|
||||||
|
"wgpu",
|
||||||
"window_clipboard 0.2.0",
|
"window_clipboard 0.2.0",
|
||||||
"winit",
|
"winit",
|
||||||
"winres",
|
"winres",
|
||||||
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6419,9 +6713,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.50"
|
version = "0.3.48"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be"
|
checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@ -6447,6 +6741,65 @@ dependencies = [
|
|||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wgpu"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "991903e4c9f5b7319732b30a3d0339e27a51ea992cea22769b5f6c7f7076af6d"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"futures",
|
||||||
|
"gfx-backend-vulkan",
|
||||||
|
"js-sys",
|
||||||
|
"objc",
|
||||||
|
"parking_lot 0.11.1",
|
||||||
|
"raw-window-handle",
|
||||||
|
"smallvec",
|
||||||
|
"tracing",
|
||||||
|
"typed-arena",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
"wgpu-core",
|
||||||
|
"wgpu-types",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wgpu-core"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea487deeae90e06d77eb8e6cef945247774e7c0a0a226d238b31e90633594365"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags",
|
||||||
|
"copyless",
|
||||||
|
"fxhash",
|
||||||
|
"gfx-backend-dx11",
|
||||||
|
"gfx-backend-dx12",
|
||||||
|
"gfx-backend-empty",
|
||||||
|
"gfx-backend-metal",
|
||||||
|
"gfx-backend-vulkan",
|
||||||
|
"gfx-descriptor",
|
||||||
|
"gfx-hal",
|
||||||
|
"gfx-memory",
|
||||||
|
"naga",
|
||||||
|
"parking_lot 0.11.1",
|
||||||
|
"raw-window-handle",
|
||||||
|
"smallvec",
|
||||||
|
"thiserror",
|
||||||
|
"tracing",
|
||||||
|
"wgpu-types",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wgpu-types"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e3529528e608b54838ee618c3923b0f46e6db0334cfc6c42a16cf4ceb3bdb57"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "which"
|
name = "which"
|
||||||
version = "4.1.0"
|
version = "4.1.0"
|
||||||
@ -6575,6 +6928,15 @@ dependencies = [
|
|||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wio"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ws2_32-sys"
|
name = "ws2_32-sys"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -6594,6 +6956,16 @@ dependencies = [
|
|||||||
"tap",
|
"tap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x11"
|
||||||
|
version = "2.18.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ecd092546cb16f25783a5451538e73afc8d32e242648d54f4ae5459ba1e773"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x11-clipboard"
|
name = "x11-clipboard"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@ -6711,3 +7083,24 @@ checksum = "0de7bff972b4f2a06c85f6d8454b09df153af7e3a4ec2aac81db1b105b684ddb"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6580539ad917b7c026220c4b3f2c08d52ce54d6ce0dc491e66002e35388fab46"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d498dbd1fd7beb83c86709ae1c33ca50942889473473d287d56ce4770a18edfb"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.26",
|
||||||
|
"syn 1.0.69",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
@ -22,14 +22,13 @@ runtimeLibs = ["libGL", "xorg.libX11", "xorg.libXcursor", "xorg.libXrandr", "xor
|
|||||||
buildInputs = ["xorg.libxcb"]
|
buildInputs = ["xorg.libxcb"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
gl = ["gfx_device_gl", "gfx_gl"]
|
|
||||||
hot-anim = ["anim/use-dyn-lib"]
|
hot-anim = ["anim/use-dyn-lib"]
|
||||||
singleplayer = ["server"]
|
singleplayer = ["server"]
|
||||||
simd = ["vek/platform_intrinsics"]
|
simd = ["vek/platform_intrinsics"]
|
||||||
tracy = ["common/tracy", "common-ecs/tracy", "common-frontend/tracy", "common-net/tracy", "common-systems/tracy", "common-state/tracy", "client/tracy"]
|
tracy = ["common/tracy", "common-ecs/tracy", "common-frontend/tracy", "common-net/tracy", "common-systems/tracy", "common-state/tracy", "client/tracy"]
|
||||||
plugins = ["client/plugins"]
|
plugins = ["client/plugins"]
|
||||||
|
|
||||||
default = ["gl", "singleplayer", "native-dialog", "plugins", "simd"]
|
default = ["singleplayer", "native-dialog", "plugins", "simd"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
client = {package = "veloren-client", path = "../client"}
|
client = {package = "veloren-client", path = "../client"}
|
||||||
@ -51,6 +50,8 @@ gfx_gl = {version = "0.6.1", optional = true}
|
|||||||
glutin = "0.26.0"
|
glutin = "0.26.0"
|
||||||
old_school_gfx_glutin_ext = "0.26"
|
old_school_gfx_glutin_ext = "0.26"
|
||||||
winit = {version = "0.24.0", features = ["serde"]}
|
winit = {version = "0.24.0", features = ["serde"]}
|
||||||
|
wgpu = "0.6.0"
|
||||||
|
zerocopy = "0.3.0"
|
||||||
|
|
||||||
# Ui
|
# Ui
|
||||||
conrod_core = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"}
|
conrod_core = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"}
|
||||||
@ -86,8 +87,7 @@ crossbeam = "0.8.0"
|
|||||||
directories-next = "2.0"
|
directories-next = "2.0"
|
||||||
dot_vox = "4.0"
|
dot_vox = "4.0"
|
||||||
enum-iterator = "0.6"
|
enum-iterator = "0.6"
|
||||||
strum = "0.20"
|
futures = "0.3"
|
||||||
strum_macros = "0.20"
|
|
||||||
glsl-include = "0.3.1"
|
glsl-include = "0.3.1"
|
||||||
guillotiere = "0.6"
|
guillotiere = "0.6"
|
||||||
hashbrown = {version = "0.9", features = ["rayon", "serde", "nightly"]}
|
hashbrown = {version = "0.9", features = ["rayon", "serde", "nightly"]}
|
||||||
@ -100,6 +100,8 @@ rand = "0.8"
|
|||||||
rodio = {version = "0.13", default-features = false, features = ["vorbis"]}
|
rodio = {version = "0.13", default-features = false, features = ["vorbis"]}
|
||||||
ron = {version = "0.6", default-features = false}
|
ron = {version = "0.6", default-features = false}
|
||||||
serde = {version = "1.0", features = [ "rc", "derive" ]}
|
serde = {version = "1.0", features = [ "rc", "derive" ]}
|
||||||
|
strum = "0.20"
|
||||||
|
strum_macros = "0.20"
|
||||||
treeculler = "0.2"
|
treeculler = "0.2"
|
||||||
tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] }
|
tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] }
|
||||||
num_cpus = "1.0"
|
num_cpus = "1.0"
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
const_generics,
|
const_generics,
|
||||||
drain_filter,
|
drain_filter,
|
||||||
once_cell,
|
once_cell,
|
||||||
or_patterns
|
trait_alias
|
||||||
)]
|
)]
|
||||||
#![recursion_limit = "2048"]
|
#![recursion_limit = "2048"]
|
||||||
|
|
||||||
|
52
voxygen/src/render/buffer.rs
Normal file
52
voxygen/src/render/buffer.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
use super::RenderError;
|
||||||
|
use wgpu::util::DeviceExt;
|
||||||
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Buffer<T: Copy + AsBytes> {
|
||||||
|
pub buf: wgpu::Buffer,
|
||||||
|
// bytes
|
||||||
|
count: usize,
|
||||||
|
phantom_data: std::marker::PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy + AsBytes> Buffer<T> {
|
||||||
|
pub fn new(device: &mut wgpu::Device, cap: usize, usage: wgpu::BufferUsage) -> Self {
|
||||||
|
Self {
|
||||||
|
buf: device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
|
label: None,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
size: cap,
|
||||||
|
usage: usage | wgpu::BufferUsage::MAP_WRITE,
|
||||||
|
}),
|
||||||
|
count: 0,
|
||||||
|
phantom_data: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_data(device: &mut wgpu::Device, usage: wgpu::BufferUsage, data: &[T]) -> Self {
|
||||||
|
let contents = data.as_bytes();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
buf: device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: None,
|
||||||
|
contents,
|
||||||
|
usage: usage | wgpu::BufferUsage::MAP_WRITE,
|
||||||
|
}),
|
||||||
|
count: data.len(),
|
||||||
|
phantom_data: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(
|
||||||
|
&mut self,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
queue: &wgpu::Queue,
|
||||||
|
vals: &[T],
|
||||||
|
offset: usize,
|
||||||
|
) {
|
||||||
|
queue.write_buffer(&self.buf, offset, vals.as_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn count(&self) -> usize { self.count }
|
||||||
|
}
|
@ -1,36 +1,32 @@
|
|||||||
use super::{gfx_backend, RenderError};
|
use super::{buffer::Buffer, RenderError};
|
||||||
use gfx::{self, traits::FactoryExt};
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
/// A handle to a series of constants sitting on the GPU. This is used to hold
|
/// A handle to a series of constants sitting on the GPU. This is used to hold
|
||||||
/// information used in the rendering process that does not change throughout a
|
/// information used in the rendering process that does not change throughout a
|
||||||
/// single render pass.
|
/// single render pass.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Consts<T: Copy + gfx::traits::Pod> {
|
pub struct Consts<T: Copy + AsBytes> {
|
||||||
pub buf: gfx::handle::Buffer<gfx_backend::Resources, T>,
|
buf: Buffer<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy + gfx::traits::Pod> Consts<T> {
|
impl<T: Copy + AsBytes> Consts<T> {
|
||||||
/// Create a new `Const<T>`.
|
/// Create a new `Const<T>`.
|
||||||
pub fn new(factory: &mut gfx_backend::Factory, len: usize) -> Self {
|
pub fn new(device: &mut wgpu::Device, len: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
buf: factory.create_constant_buffer(len),
|
buf: Buffer::new(device, len, wgpu::BufferUsage::UNIFORM),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the GPU-side value represented by this constant handle.
|
/// Update the GPU-side value represented by this constant handle.
|
||||||
|
|
||||||
pub fn update(
|
pub fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
encoder: &mut gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
device: &wgpu::Device,
|
||||||
|
queue: &wgpu::Queue,
|
||||||
vals: &[T],
|
vals: &[T],
|
||||||
offset: usize,
|
offset: usize,
|
||||||
) -> Result<(), RenderError> {
|
) -> Result<(), RenderError> {
|
||||||
if vals.is_empty() {
|
self.buf.update(device, queue, vals, offset)
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
encoder
|
|
||||||
.update_buffer(&self.buf, vals, offset)
|
|
||||||
.map_err(RenderError::UpdateError)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn buf(&self) -> &wgpu::Buffer { self.buf.buf }
|
||||||
}
|
}
|
||||||
|
@ -2,73 +2,20 @@
|
|||||||
/// rendering subsystem.
|
/// rendering subsystem.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum RenderError {
|
pub enum RenderError {
|
||||||
PipelineError(gfx::PipelineStateError<String>),
|
RequestDeviceError(wgpu::RequestDeviceError),
|
||||||
UpdateError(gfx::UpdateError<usize>),
|
MappingError(wgpu::BufferAsyncError),
|
||||||
TexUpdateError(gfx::UpdateError<[u16; 3]>),
|
SwapChainError(wgpu::SwapChainError),
|
||||||
CombinedError(gfx::CombinedError),
|
|
||||||
BufferCreationError(gfx::buffer::CreationError),
|
|
||||||
IncludeError(glsl_include::Error),
|
|
||||||
MappingError(gfx::mapping::Error),
|
|
||||||
CopyError(gfx::CopyError<[u16; 3], usize>),
|
|
||||||
CustomError(String),
|
CustomError(String),
|
||||||
|
CouldNotFindAdapter,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<gfx::PipelineStateError<String>> for RenderError {
|
impl From<wgpu::RequestDeviceError> for RenderError {
|
||||||
fn from(err: gfx::PipelineStateError<String>) -> Self { Self::PipelineError(err) }
|
fn from(err: wgpu::RequestDeviceError) -> Self { Self::RequestDeviceError(err) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<gfx::PipelineStateError<&str>> for RenderError {
|
impl From<wgpu::BufferAsyncError> for RenderError {
|
||||||
fn from(err: gfx::PipelineStateError<&str>) -> Self {
|
fn from(err: wgpu::BufferAsyncError) -> Self { Self::MappingError(err) }
|
||||||
match err {
|
|
||||||
gfx::PipelineStateError::DescriptorInit(err) => {
|
|
||||||
gfx::PipelineStateError::DescriptorInit(err)
|
|
||||||
},
|
|
||||||
err => err,
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl From<gfx::shade::ProgramError> for RenderError {
|
impl From<wgpu::SwapChainError> for RenderError {
|
||||||
fn from(err: gfx::shade::ProgramError) -> Self {
|
fn from(err: wgpu::SwapChainError) -> Self { Self::SwapChainError(err) }
|
||||||
gfx::PipelineStateError::<String>::Program(err).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<gfx::UpdateError<usize>> for RenderError {
|
|
||||||
fn from(err: gfx::UpdateError<usize>) -> Self { Self::UpdateError(err) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<gfx::UpdateError<[u16; 3]>> for RenderError {
|
|
||||||
fn from(err: gfx::UpdateError<[u16; 3]>) -> Self { Self::TexUpdateError(err) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<gfx::CombinedError> for RenderError {
|
|
||||||
fn from(err: gfx::CombinedError) -> Self { Self::CombinedError(err) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<gfx::TargetViewError> for RenderError {
|
|
||||||
fn from(err: gfx::TargetViewError) -> Self { Self::CombinedError(err.into()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<gfx::ResourceViewError> for RenderError {
|
|
||||||
fn from(err: gfx::ResourceViewError) -> Self { Self::CombinedError(err.into()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<gfx::texture::CreationError> for RenderError {
|
|
||||||
fn from(err: gfx::texture::CreationError) -> Self { Self::CombinedError(err.into()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<gfx::buffer::CreationError> for RenderError {
|
|
||||||
fn from(err: gfx::buffer::CreationError) -> Self { Self::BufferCreationError(err) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<glsl_include::Error> for RenderError {
|
|
||||||
fn from(err: glsl_include::Error) -> Self { Self::IncludeError(err) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<gfx::mapping::Error> for RenderError {
|
|
||||||
fn from(err: gfx::mapping::Error) -> Self { Self::MappingError(err) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<gfx::CopyError<[u16; 3], usize>> for RenderError {
|
|
||||||
fn from(err: gfx::CopyError<[u16; 3], usize>) -> Self { Self::CopyError(err) }
|
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,30 @@
|
|||||||
use super::{gfx_backend, RenderError};
|
use super::{buffer::Buffer, RenderError};
|
||||||
use gfx::{
|
use zerocopy::AsBytes;
|
||||||
self,
|
|
||||||
buffer::Role,
|
|
||||||
memory::{Bind, Usage},
|
|
||||||
Factory,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Represents a mesh that has been sent to the GPU.
|
/// Represents a mesh that has been sent to the GPU.
|
||||||
pub struct Instances<T: Copy + gfx::traits::Pod> {
|
#[derive(Clone)]
|
||||||
pub ibuf: gfx::handle::Buffer<gfx_backend::Resources, T>,
|
pub struct Instances<T: Copy + AsBytes> {
|
||||||
|
buf: Buffer<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy + gfx::traits::Pod> Instances<T> {
|
impl<T: Copy + AsBytes> Instances<T> {
|
||||||
pub fn new(factory: &mut gfx_backend::Factory, len: usize) -> Result<Self, RenderError> {
|
pub fn new(device: &mut wgpu::Device, len: usize) -> Self {
|
||||||
Ok(Self {
|
Self {
|
||||||
ibuf: factory
|
buf: Buffer::new(device, len, wgpu::BufferUsage::VERTEX),
|
||||||
.create_buffer(len, Role::Vertex, Usage::Dynamic, Bind::empty())
|
}
|
||||||
.map_err(RenderError::BufferCreationError)?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn count(&self) -> usize { self.ibuf.len() }
|
pub fn count(&self) -> usize { self.buf.count() }
|
||||||
|
|
||||||
pub fn update(
|
pub fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
encoder: &mut gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
device: &wgpu::Device,
|
||||||
instances: &[T],
|
queue: &wgpu::Queue,
|
||||||
|
vals: &[T],
|
||||||
|
offset: usize,
|
||||||
) -> Result<(), RenderError> {
|
) -> Result<(), RenderError> {
|
||||||
encoder
|
self.buf.update(device, queue, vals, offset)
|
||||||
.update_buffer(&self.ibuf, instances, 0)
|
|
||||||
.map_err(RenderError::UpdateError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn buf(&self) -> &wgpu::Buffer { self.buf.buf }
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
use super::Pipeline;
|
use super::Vertex;
|
||||||
use core::{iter::FromIterator, ops::Range};
|
use core::{iter::FromIterator, ops::Range};
|
||||||
|
|
||||||
/// A `Vec`-based mesh structure used to store mesh data on the CPU.
|
/// A `Vec`-based mesh structure used to store mesh data on the CPU.
|
||||||
pub struct Mesh<P: Pipeline> {
|
pub struct Mesh<V: Vertex> {
|
||||||
verts: Vec<P::Vertex>,
|
verts: Vec<V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> Clone for Mesh<P>
|
impl<V: Vertex> Clone for Mesh<V> {
|
||||||
where
|
|
||||||
P::Vertex: Clone,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
verts: self.verts.clone(),
|
verts: self.verts.clone(),
|
||||||
@ -17,7 +14,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> Mesh<P> {
|
impl<V: Vertex> Mesh<V> {
|
||||||
/// Create a new `Mesh`.
|
/// Create a new `Mesh`.
|
||||||
#[allow(clippy::new_without_default)] // TODO: Pending review in #587
|
#[allow(clippy::new_without_default)] // TODO: Pending review in #587
|
||||||
pub fn new() -> Self { Self { verts: Vec::new() } }
|
pub fn new() -> Self { Self { verts: Vec::new() } }
|
||||||
@ -26,23 +23,23 @@ impl<P: Pipeline> Mesh<P> {
|
|||||||
pub fn clear(&mut self) { self.verts.clear(); }
|
pub fn clear(&mut self) { self.verts.clear(); }
|
||||||
|
|
||||||
/// Get a slice referencing the vertices of this mesh.
|
/// Get a slice referencing the vertices of this mesh.
|
||||||
pub fn vertices(&self) -> &[P::Vertex] { &self.verts }
|
pub fn vertices(&self) -> &[V] { &self.verts }
|
||||||
|
|
||||||
/// Get a mutable slice referencing the vertices of this mesh.
|
/// Get a mutable slice referencing the vertices of this mesh.
|
||||||
pub fn vertices_mut(&mut self) -> &mut [P::Vertex] { &mut self.verts }
|
pub fn vertices_mut(&mut self) -> &mut [P::Vertex] { &mut self.verts }
|
||||||
|
|
||||||
/// Push a new vertex onto the end of this mesh.
|
/// Push a new vertex onto the end of this mesh.
|
||||||
pub fn push(&mut self, vert: P::Vertex) { self.verts.push(vert); }
|
pub fn push(&mut self, vert: V) { self.verts.push(vert); }
|
||||||
|
|
||||||
/// Push a new polygon onto the end of this mesh.
|
/// Push a new polygon onto the end of this mesh.
|
||||||
pub fn push_tri(&mut self, tri: Tri<P>) {
|
pub fn push_tri(&mut self, tri: Tri<V>) {
|
||||||
self.verts.push(tri.a);
|
self.verts.push(tri.a);
|
||||||
self.verts.push(tri.b);
|
self.verts.push(tri.b);
|
||||||
self.verts.push(tri.c);
|
self.verts.push(tri.c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push a new quad onto the end of this mesh.
|
/// Push a new quad onto the end of this mesh.
|
||||||
pub fn push_quad(&mut self, quad: Quad<P>) {
|
pub fn push_quad(&mut self, quad: Quad<V>) {
|
||||||
// A quad is composed of two triangles. The code below converts the former to
|
// A quad is composed of two triangles. The code below converts the former to
|
||||||
// the latter.
|
// the latter.
|
||||||
|
|
||||||
@ -73,10 +70,10 @@ impl<P: Pipeline> Mesh<P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Push the vertices of another mesh onto the end of this mesh.
|
/// Push the vertices of another mesh onto the end of this mesh.
|
||||||
pub fn push_mesh(&mut self, other: &Mesh<P>) { self.verts.extend_from_slice(other.vertices()); }
|
pub fn push_mesh(&mut self, other: &Mesh<V>) { self.verts.extend_from_slice(other.vertices()); }
|
||||||
|
|
||||||
/// Map and push the vertices of another mesh onto the end of this mesh.
|
/// Map and push the vertices of another mesh onto the end of this mesh.
|
||||||
pub fn push_mesh_map<F: FnMut(P::Vertex) -> P::Vertex>(&mut self, other: &Mesh<P>, mut f: F) {
|
pub fn push_mesh_map<F: FnMut(V) -> V>(&mut self, other: &Mesh<V>, mut f: F) {
|
||||||
// Reserve enough space in our Vec. This isn't necessary, but it tends to reduce
|
// Reserve enough space in our Vec. This isn't necessary, but it tends to reduce
|
||||||
// the number of required (re)allocations.
|
// the number of required (re)allocations.
|
||||||
self.verts.reserve(other.vertices().len());
|
self.verts.reserve(other.vertices().len());
|
||||||
@ -86,23 +83,23 @@ impl<P: Pipeline> Mesh<P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> std::slice::Iter<P::Vertex> { self.verts.iter() }
|
pub fn iter(&self) -> std::slice::Iter<V> { self.verts.iter() }
|
||||||
|
|
||||||
/// NOTE: Panics if vertex_range is out of bounds of vertices.
|
/// NOTE: Panics if vertex_range is out of bounds of vertices.
|
||||||
pub fn iter_mut(&mut self, vertex_range: Range<usize>) -> std::slice::IterMut<P::Vertex> {
|
pub fn iter_mut(&mut self, vertex_range: Range<usize>) -> std::slice::IterMut<V> {
|
||||||
self.verts[vertex_range].iter_mut()
|
self.verts[vertex_range].iter_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> IntoIterator for Mesh<P> {
|
impl<V: Vertex> IntoIterator for Mesh<V> {
|
||||||
type IntoIter = std::vec::IntoIter<P::Vertex>;
|
type IntoIter = std::vec::IntoIter<V>;
|
||||||
type Item = P::Vertex;
|
type Item = V;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter { self.verts.into_iter() }
|
fn into_iter(self) -> Self::IntoIter { self.verts.into_iter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> FromIterator<Tri<P>> for Mesh<P> {
|
impl<V: Vertex> FromIterator<Tri<V>> for Mesh<V> {
|
||||||
fn from_iter<I: IntoIterator<Item = Tri<P>>>(tris: I) -> Self {
|
fn from_iter<I: IntoIterator<Item = Tri<V>>>(tris: I) -> Self {
|
||||||
tris.into_iter().fold(Self::new(), |mut this, tri| {
|
tris.into_iter().fold(Self::new(), |mut this, tri| {
|
||||||
this.push_tri(tri);
|
this.push_tri(tri);
|
||||||
this
|
this
|
||||||
@ -110,8 +107,8 @@ impl<P: Pipeline> FromIterator<Tri<P>> for Mesh<P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> FromIterator<Quad<P>> for Mesh<P> {
|
impl<V: Vertex> FromIterator<Quad<V>> for Mesh<V> {
|
||||||
fn from_iter<I: IntoIterator<Item = Quad<P>>>(quads: I) -> Self {
|
fn from_iter<I: IntoIterator<Item = Quad<V>>>(quads: I) -> Self {
|
||||||
quads.into_iter().fold(Self::new(), |mut this, quad| {
|
quads.into_iter().fold(Self::new(), |mut this, quad| {
|
||||||
this.push_quad(quad);
|
this.push_quad(quad);
|
||||||
this
|
this
|
||||||
@ -120,33 +117,28 @@ impl<P: Pipeline> FromIterator<Quad<P>> for Mesh<P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a triangle stored on the CPU.
|
/// Represents a triangle stored on the CPU.
|
||||||
pub struct Tri<P: Pipeline> {
|
pub struct Tri<V: Vertex> {
|
||||||
a: P::Vertex,
|
a: V,
|
||||||
b: P::Vertex,
|
b: V,
|
||||||
c: P::Vertex,
|
c: V,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> Tri<P> {
|
impl<V: Vertex> Tri<V> {
|
||||||
pub fn new(a: P::Vertex, b: P::Vertex, c: P::Vertex) -> Self { Self { a, b, c } }
|
pub fn new(a: V, b: V, c: V) -> Self { Self { a, b, c } }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a quad stored on the CPU.
|
/// Represents a quad stored on the CPU.
|
||||||
pub struct Quad<P: Pipeline> {
|
pub struct Quad<V: Vertex> {
|
||||||
a: P::Vertex,
|
a: V,
|
||||||
b: P::Vertex,
|
b: V,
|
||||||
c: P::Vertex,
|
c: V,
|
||||||
d: P::Vertex,
|
d: V,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> Quad<P> {
|
impl<V: Vertex> Quad<V> {
|
||||||
pub fn new(a: P::Vertex, b: P::Vertex, c: P::Vertex, d: P::Vertex) -> Self {
|
pub fn new(a: V, b: V, c: V, d: V) -> Self { Self { a, b, c, d } }
|
||||||
Self { a, b, c, d }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rotated_by(self, n: usize) -> Self
|
pub fn rotated_by(self, n: usize) -> Self {
|
||||||
where
|
|
||||||
P::Vertex: Clone,
|
|
||||||
{
|
|
||||||
let verts = [self.a, self.b, self.c, self.d];
|
let verts = [self.a, self.b, self.c, self.d];
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mod buffer;
|
||||||
#[allow(clippy::single_component_path_imports)] // TODO: Pending review in #587
|
#[allow(clippy::single_component_path_imports)] // TODO: Pending review in #587
|
||||||
pub mod consts;
|
pub mod consts;
|
||||||
mod error;
|
mod error;
|
||||||
@ -44,25 +45,9 @@ pub use self::{
|
|||||||
},
|
},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
};
|
};
|
||||||
pub use gfx::texture::{FilterMethod, WrapMode};
|
pub use wgpu::{AddressMode, FilterMode};
|
||||||
|
|
||||||
#[cfg(feature = "gl")]
|
trait Vertex = Clone + zerocopy::AsBytes;
|
||||||
use gfx_device_gl as gfx_backend;
|
|
||||||
|
|
||||||
/// Used to represent a specific rendering configuration.
|
|
||||||
///
|
|
||||||
/// Note that pipelines are tied to the
|
|
||||||
/// rendering backend, and as such it is necessary to modify the rendering
|
|
||||||
/// subsystem when adding new pipelines - custom pipelines are not currently an
|
|
||||||
/// objective of the rendering subsystem.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// - `SkyboxPipeline`
|
|
||||||
/// - `FigurePipeline`
|
|
||||||
pub trait Pipeline {
|
|
||||||
type Vertex: Clone + gfx::traits::Pod + gfx::pso::buffer::Structure<gfx::format::Format>;
|
|
||||||
}
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
/// Anti-aliasing modes
|
/// Anti-aliasing modes
|
||||||
|
@ -1,69 +1,48 @@
|
|||||||
use super::{gfx_backend, mesh::Mesh, Pipeline, RenderError};
|
use super::{buffer::Buffer, mesh::Mesh, RenderError, Vertex};
|
||||||
use gfx::{
|
|
||||||
buffer::Role,
|
|
||||||
memory::{Bind, Usage},
|
|
||||||
traits::FactoryExt,
|
|
||||||
Factory,
|
|
||||||
};
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
/// Represents a mesh that has been sent to the GPU.
|
/// Represents a mesh that has been sent to the GPU.
|
||||||
pub struct Model<P: Pipeline> {
|
pub struct SubModel<'a, V: Vertex> {
|
||||||
pub vbuf: gfx::handle::Buffer<gfx_backend::Resources, P::Vertex>,
|
|
||||||
pub vertex_range: Range<u32>,
|
pub vertex_range: Range<u32>,
|
||||||
|
buf: &'a wgpu::Buffer,
|
||||||
|
phantom_data: std::marker::PhantomData<V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> Model<P> {
|
impl<'a, V: Vertex> SubModel<'a, V> {
|
||||||
pub fn new(factory: &mut gfx_backend::Factory, mesh: &Mesh<P>) -> Self {
|
pub fn buf(&self) -> &wgpu::Buffer { self.buf }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a mesh that has been sent to the GPU.
|
||||||
|
pub struct Model<V: Vertex> {
|
||||||
|
vbuf: Buffer<V>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: Vertex> Model<V> {
|
||||||
|
pub fn new(device: &wgpu::Device, mesh: &Mesh<V>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
vbuf: factory.create_vertex_buffer(mesh.vertices()),
|
vbuf: Buffer::new_with_data(device, wgpu::BufferUsage::VERTEX, mesh.vertices()),
|
||||||
vertex_range: 0..mesh.vertices().len() as u32,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vertex_range(&self) -> Range<u32> { self.vertex_range.clone() }
|
|
||||||
|
|
||||||
/// Create a model with a slice of a portion of this model to send to the
|
|
||||||
/// renderer.
|
|
||||||
pub fn submodel(&self, vertex_range: Range<u32>) -> Model<P> {
|
|
||||||
Model {
|
|
||||||
vbuf: self.vbuf.clone(),
|
|
||||||
vertex_range,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a mesh on the GPU which can be updated dynamically.
|
|
||||||
pub struct DynamicModel<P: Pipeline> {
|
|
||||||
pub vbuf: gfx::handle::Buffer<gfx_backend::Resources, P::Vertex>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P: Pipeline> DynamicModel<P> {
|
|
||||||
pub fn new(factory: &mut gfx_backend::Factory, size: usize) -> Result<Self, RenderError> {
|
|
||||||
Ok(Self {
|
|
||||||
vbuf: factory
|
|
||||||
.create_buffer(size, Role::Vertex, Usage::Dynamic, Bind::empty())
|
|
||||||
.map_err(RenderError::BufferCreationError)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a model with a slice of a portion of this model to send to the
|
/// Create a model with a slice of a portion of this model to send to the
|
||||||
/// renderer.
|
/// renderer.
|
||||||
pub fn submodel(&self, vertex_range: Range<u32>) -> Model<P> {
|
pub fn submodel(&self, vertex_range: Range<u32>) -> SubModel<V> {
|
||||||
Model {
|
SubModel {
|
||||||
vbuf: self.vbuf.clone(),
|
|
||||||
vertex_range,
|
vertex_range,
|
||||||
|
buf: self.buf(),
|
||||||
|
phantom_data: std::marker::PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(
|
pub fn update(
|
||||||
&self,
|
&mut self,
|
||||||
encoder: &mut gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
device: &wgpu::Device,
|
||||||
mesh: &Mesh<P>,
|
queue: &wgpu::Queue,
|
||||||
|
mesh: &Mesh<V>,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
) -> Result<(), RenderError> {
|
) -> Result<(), RenderError> {
|
||||||
encoder
|
self.buf.update(device, queue, mesh.vertices(), offset)
|
||||||
.update_buffer(&self.vbuf, mesh.vertices(), offset)
|
|
||||||
.map_err(RenderError::UpdateError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn buf(&self) -> &wgpu::Buffer { self.vbuf.buf }
|
||||||
}
|
}
|
||||||
|
@ -1,56 +1,28 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{Mesh, Model, Pipeline, TerrainPipeline, TgtColorFmt, TgtDepthStencilFmt},
|
super::{Mesh, Model, TerrainPipeline, TgtColorFmt, TgtDepthStencilFmt},
|
||||||
shadow, Globals, Light, Shadow,
|
shadow, Globals, Light, Shadow,
|
||||||
};
|
};
|
||||||
use crate::mesh::greedy::GreedyMesh;
|
use crate::mesh::greedy::GreedyMesh;
|
||||||
use gfx::{
|
|
||||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
|
||||||
gfx_pipeline_inner, state::ColorMask,
|
|
||||||
};
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
gfx_defines! {
|
#[repr(C)]
|
||||||
constant Locals {
|
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||||
model_mat: [[f32; 4]; 4] = "model_mat",
|
pub struct Locals {
|
||||||
highlight_col: [f32; 4] = "highlight_col",
|
model_mat: [[f32; 4]; 4],
|
||||||
model_light: [f32; 4] = "model_light",
|
highlight_col: [f32; 4],
|
||||||
model_glow: [f32; 4] = "model_glow",
|
model_light: [f32; 4],
|
||||||
atlas_offs: [i32; 4] = "atlas_offs",
|
model_glow: [f32; 4],
|
||||||
model_pos: [f32; 3] = "model_pos",
|
atlas_offs: [i32; 4],
|
||||||
flags: u32 = "flags",
|
model_pos: [f32; 3],
|
||||||
}
|
flags: u32,
|
||||||
|
}
|
||||||
|
|
||||||
constant BoneData {
|
#[repr(C)]
|
||||||
bone_mat: [[f32; 4]; 4] = "bone_mat",
|
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||||
normals_mat: [[f32; 4]; 4] = "normals_mat",
|
pub struct BoneData {
|
||||||
}
|
bone_mat: [[f32; 4]; 4],
|
||||||
|
normals_mat: [[f32; 4]; 4],
|
||||||
pipeline pipe {
|
|
||||||
vbuf: gfx::VertexBuffer<<TerrainPipeline as Pipeline>::Vertex> = (),
|
|
||||||
// abuf: gfx::VertexBuffer<<TerrainPipeline as Pipeline>::Vertex> = (),
|
|
||||||
col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
|
||||||
|
|
||||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
|
||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
|
||||||
bones: gfx::ConstantBuffer<BoneData> = "u_bones",
|
|
||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
|
||||||
|
|
||||||
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
|
||||||
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_shadow_maps",
|
|
||||||
|
|
||||||
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
|
||||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
|
||||||
|
|
||||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
|
||||||
|
|
||||||
// Shadow stuff
|
|
||||||
light_shadows: gfx::ConstantBuffer<shadow::Locals> = "u_light_shadows",
|
|
||||||
|
|
||||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
|
||||||
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
|
||||||
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Replace))),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Locals {
|
impl Locals {
|
||||||
@ -76,6 +48,21 @@ impl Locals {
|
|||||||
flags,
|
flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: None,
|
||||||
|
entries: &[wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::UniformBuffer {
|
||||||
|
dynamic: false,
|
||||||
|
min_binding_size: None,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Locals {
|
impl Default for Locals {
|
||||||
@ -99,16 +86,39 @@ impl BoneData {
|
|||||||
normals_mat: normals_mat.into_col_arrays(),
|
normals_mat: normals_mat.into_col_arrays(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: None,
|
||||||
|
entries: &[wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::UniformBuffer {
|
||||||
|
dynamic: false,
|
||||||
|
min_binding_size: None,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BoneData {
|
impl Default for BoneData {
|
||||||
fn default() -> Self { Self::new(anim::vek::Mat4::identity(), anim::vek::Mat4::identity()) }
|
fn default() -> Self { Self::new(anim::vek::Mat4::identity(), anim::vek::Mat4::identity()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FigurePipeline;
|
pub struct FigureLayout {
|
||||||
|
pub locals: wgpu::BindGroupLayout,
|
||||||
|
pub bone_data: wgpu::BindGroupLayout,
|
||||||
|
}
|
||||||
|
|
||||||
impl Pipeline for FigurePipeline {
|
impl FigureLayout {
|
||||||
type Vertex = <TerrainPipeline as Pipeline>::Vertex;
|
pub fn new(device: &wgpu::Device) -> Self {
|
||||||
|
Self {
|
||||||
|
locals: Locals::locals_layout(device),
|
||||||
|
bone_data: BoneData::bone_data_layout(device),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FigureModel {
|
pub struct FigureModel {
|
||||||
@ -130,3 +140,49 @@ impl FigureModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type BoneMeshes = (Mesh<TerrainPipeline>, anim::vek::Aabb<f32>);
|
pub type BoneMeshes = (Mesh<TerrainPipeline>, anim::vek::Aabb<f32>);
|
||||||
|
|
||||||
|
//gfx_defines! {
|
||||||
|
// constant Locals {
|
||||||
|
// model_mat: [[f32; 4]; 4] = "model_mat",
|
||||||
|
// highlight_col: [f32; 4] = "highlight_col",
|
||||||
|
// model_light: [f32; 4] = "model_light",
|
||||||
|
// atlas_offs: [i32; 4] = "atlas_offs",
|
||||||
|
// model_pos: [f32; 3] = "model_pos",
|
||||||
|
// flags: u32 = "flags",
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// constant BoneData {
|
||||||
|
// bone_mat: [[f32; 4]; 4] = "bone_mat",
|
||||||
|
// normals_mat: [[f32; 4]; 4] = "normals_mat",
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pipeline pipe {
|
||||||
|
// vbuf: gfx::VertexBuffer<<TerrainPipeline as Pipeline>::Vertex> = (),
|
||||||
|
// // abuf: gfx::VertexBuffer<<TerrainPipeline as Pipeline>::Vertex> =
|
||||||
|
// (), col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
||||||
|
//
|
||||||
|
// locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
|
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
|
// bones: gfx::ConstantBuffer<BoneData> = "u_bones",
|
||||||
|
// lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
|
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
//
|
||||||
|
// point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||||
|
// directed_shadow_maps: gfx::TextureSampler<f32> =
|
||||||
|
// "t_directed_shadow_maps",
|
||||||
|
//
|
||||||
|
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||||
|
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||||
|
//
|
||||||
|
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
//
|
||||||
|
// // Shadow stuff
|
||||||
|
// light_shadows: gfx::ConstantBuffer<shadow::Locals> =
|
||||||
|
// "u_light_shadows",
|
||||||
|
//
|
||||||
|
// tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color",
|
||||||
|
// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil:
|
||||||
|
// gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
|
// // tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> =
|
||||||
|
// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,
|
||||||
|
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Replace))), }
|
||||||
|
@ -1,28 +1,21 @@
|
|||||||
use super::{
|
use super::{
|
||||||
consts::Consts,
|
consts::Consts,
|
||||||
gfx_backend,
|
|
||||||
instances::Instances,
|
instances::Instances,
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
model::{DynamicModel, Model},
|
model::{Model},
|
||||||
pipelines::{
|
pipelines::{
|
||||||
clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain,
|
clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain,
|
||||||
ui, GlobalModel, Globals,
|
ui, GlobalModel, Globals,
|
||||||
},
|
},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
AaMode, CloudMode, FilterMethod, FluidMode, LightingMode, Pipeline, RenderError, RenderMode,
|
AaMode, CloudMode, FilterMode, FluidMode, LightingMode, RenderError, RenderMode,
|
||||||
ShadowMapMode, ShadowMode, WrapMode,
|
ShadowMapMode, ShadowMode, AddressMode,
|
||||||
};
|
};
|
||||||
use common::assets::{self, AssetExt, AssetHandle};
|
use common::assets::{self, AssetExt, AssetHandle};
|
||||||
use common_base::span;
|
use common_base::span;
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use gfx::{
|
|
||||||
self,
|
|
||||||
handle::Sampler,
|
|
||||||
state::Comparison,
|
|
||||||
traits::{Device, Factory, FactoryExt},
|
|
||||||
};
|
|
||||||
use glsl_include::Context as IncludeContext;
|
use glsl_include::Context as IncludeContext;
|
||||||
use tracing::{error, warn};
|
use tracing::{error, info, warn};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
/// Represents the format of the pre-processed color target.
|
/// Represents the format of the pre-processed color target.
|
||||||
@ -225,13 +218,11 @@ impl assets::Compound for Shaders {
|
|||||||
pub struct ShadowMapRenderer {
|
pub struct ShadowMapRenderer {
|
||||||
// directed_encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
// directed_encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
||||||
// point_encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
// point_encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
||||||
directed_depth_stencil_view: ShadowDepthStencilView,
|
directed_depth_stencil_view: wgpu::TextureView,
|
||||||
directed_res: ShadowResourceView,
|
directed_sampler: wgpu::Sampler,
|
||||||
directed_sampler: Sampler<gfx_backend::Resources>,
|
|
||||||
|
|
||||||
point_depth_stencil_view: ShadowDepthStencilView,
|
point_depth_stencil_view: wgpu::TextureView,
|
||||||
point_res: ShadowResourceView,
|
point_sampler: wgpu::Sampler,
|
||||||
point_sampler: Sampler<gfx_backend::Resources>,
|
|
||||||
|
|
||||||
point_pipeline: GfxPipeline<shadow::pipe::Init<'static>>,
|
point_pipeline: GfxPipeline<shadow::pipe::Init<'static>>,
|
||||||
terrain_directed_pipeline: GfxPipeline<shadow::pipe::Init<'static>>,
|
terrain_directed_pipeline: GfxPipeline<shadow::pipe::Init<'static>>,
|
||||||
@ -243,22 +234,18 @@ pub struct ShadowMapRenderer {
|
|||||||
/// GPU, along with pipeline state objects (PSOs) needed to renderer different
|
/// GPU, along with pipeline state objects (PSOs) needed to renderer different
|
||||||
/// kinds of models to the screen.
|
/// kinds of models to the screen.
|
||||||
pub struct Renderer {
|
pub struct Renderer {
|
||||||
device: gfx_backend::Device,
|
device: wgpu::Device,
|
||||||
encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
queue: wgpu::Queue,
|
||||||
factory: gfx_backend::Factory,
|
swap_chain: wgpu::SwapChain,
|
||||||
|
|
||||||
win_color_view: WinColorView,
|
win_depth_view: wgpu::TextureView,
|
||||||
win_depth_view: WinDepthView,
|
|
||||||
|
|
||||||
tgt_color_view: TgtColorView,
|
tgt_color_view: wgpu::TextureView,
|
||||||
tgt_depth_stencil_view: TgtDepthStencilView,
|
tgt_depth_stencil_view: wgpu::TextureView,
|
||||||
tgt_color_view_pp: TgtColorView,
|
// TODO: rename
|
||||||
|
tgt_color_pp_view: wgpu::TextureView,
|
||||||
|
|
||||||
tgt_color_res: TgtColorRes,
|
sampler: wgpu::Sampler,
|
||||||
tgt_depth_res: TgtDepthRes,
|
|
||||||
tgt_color_res_pp: TgtColorRes,
|
|
||||||
|
|
||||||
sampler: Sampler<gfx_backend::Resources>,
|
|
||||||
|
|
||||||
shadow_map: Option<ShadowMapRenderer>,
|
shadow_map: Option<ShadowMapRenderer>,
|
||||||
|
|
||||||
@ -285,11 +272,8 @@ pub struct Renderer {
|
|||||||
impl Renderer {
|
impl Renderer {
|
||||||
/// Create a new `Renderer` from a variety of backend-specific components
|
/// Create a new `Renderer` from a variety of backend-specific components
|
||||||
/// and the window targets.
|
/// and the window targets.
|
||||||
pub fn new(
|
pub async fn new(
|
||||||
mut device: gfx_backend::Device,
|
window: &winit::window::Window,
|
||||||
mut factory: gfx_backend::Factory,
|
|
||||||
win_color_view: WinColorView,
|
|
||||||
win_depth_view: WinDepthView,
|
|
||||||
mode: RenderMode,
|
mode: RenderMode,
|
||||||
) -> Result<Self, RenderError> {
|
) -> Result<Self, RenderError> {
|
||||||
// Enable seamless cubemaps globally, where available--they are essentially a
|
// Enable seamless cubemaps globally, where available--they are essentially a
|
||||||
@ -297,12 +281,59 @@ impl Renderer {
|
|||||||
//
|
//
|
||||||
// Note that since we only have to enable this once globally, there is no point
|
// Note that since we only have to enable this once globally, there is no point
|
||||||
// in doing this on rerender.
|
// in doing this on rerender.
|
||||||
Self::enable_seamless_cube_maps(&mut device);
|
// Self::enable_seamless_cube_maps(&mut device);
|
||||||
|
|
||||||
let dims = win_color_view.get_dimensions();
|
let dims = window.inner_size();
|
||||||
|
|
||||||
|
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY | wgpu::BackendBit::SECONDARY);
|
||||||
|
|
||||||
|
// This is unsafe because the window handle must be valid, if you find a way to
|
||||||
|
// have an invalid winit::Window then you have bigger issues
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
let surface = unsafe { instance.create_surface(window) };
|
||||||
|
|
||||||
|
let adapter = instance
|
||||||
|
.request_adapter(wgpu::RequestAdapterOptionsBase {
|
||||||
|
power_preference: wgpu::PowerPreference::HighPerformance,
|
||||||
|
compatible_surface: Some(surface),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.ok_or(RenderError::CouldNotFindAdapter)?;
|
||||||
|
|
||||||
|
use wgpu::{Features, Limits};
|
||||||
|
|
||||||
|
let (device, queue) = adapter
|
||||||
|
.request_device(
|
||||||
|
wgpu::DeviceDescriptor {
|
||||||
|
// TODO
|
||||||
|
features: Features::DEPTH_CLAMPING,
|
||||||
|
limits: Limits::default(),
|
||||||
|
shader_validation: true,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let info = device.get_info();
|
||||||
|
info!(
|
||||||
|
?info.name,
|
||||||
|
?info.vendor,
|
||||||
|
?info.backend,
|
||||||
|
?info.device,
|
||||||
|
?info.device_type,
|
||||||
|
"selected graphics device"
|
||||||
|
);
|
||||||
|
|
||||||
|
let swap_chain = device.create_swap_chain(&surface, &wgpu::SwapChainDescriptor {
|
||||||
|
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||||
|
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||||
|
width: dims.0,
|
||||||
|
height: dims.1,
|
||||||
|
present_mode: wgpu::PresentMode::Immediate,
|
||||||
|
});
|
||||||
|
|
||||||
let shadow_views = Self::create_shadow_views(
|
let shadow_views = Self::create_shadow_views(
|
||||||
&mut factory,
|
&device,
|
||||||
(dims.0, dims.1),
|
(dims.0, dims.1),
|
||||||
&ShadowMapMode::try_from(mode.shadow).unwrap_or_default(),
|
&ShadowMapMode::try_from(mode.shadow).unwrap_or_default(),
|
||||||
)
|
)
|
||||||
@ -328,16 +359,18 @@ impl Renderer {
|
|||||||
point_shadow_pipeline,
|
point_shadow_pipeline,
|
||||||
terrain_directed_shadow_pipeline,
|
terrain_directed_shadow_pipeline,
|
||||||
figure_directed_shadow_pipeline,
|
figure_directed_shadow_pipeline,
|
||||||
) = create_pipelines(&mut factory, &shaders.read(), &mode, shadow_views.is_some())?;
|
) = create_pipelines(
|
||||||
|
&device,
|
||||||
|
&mode,
|
||||||
|
shadow_views.is_some(),
|
||||||
|
)?;
|
||||||
|
|
||||||
let (
|
let (
|
||||||
tgt_color_view,
|
tgt_color_view,
|
||||||
tgt_depth_stencil_view,
|
tgt_depth_stencil_view,
|
||||||
tgt_color_view_pp,
|
tgt_color_pp_view,
|
||||||
tgt_color_res,
|
win_depth_view,
|
||||||
tgt_depth_res,
|
) = Self::create_rt_views(&device, (dims.0, dims.1), &mode)?;
|
||||||
tgt_color_res_pp,
|
|
||||||
) = Self::create_rt_views(&mut factory, (dims.0, dims.1), &mode)?;
|
|
||||||
|
|
||||||
let shadow_map = if let (
|
let shadow_map = if let (
|
||||||
Some(point_pipeline),
|
Some(point_pipeline),
|
||||||
@ -360,13 +393,11 @@ impl Renderer {
|
|||||||
) = shadow_views;
|
) = shadow_views;
|
||||||
Some(ShadowMapRenderer {
|
Some(ShadowMapRenderer {
|
||||||
directed_depth_stencil_view,
|
directed_depth_stencil_view,
|
||||||
directed_res,
|
|
||||||
directed_sampler,
|
directed_sampler,
|
||||||
|
|
||||||
// point_encoder: factory.create_command_buffer().into(),
|
// point_encoder: factory.create_command_buffer().into(),
|
||||||
// directed_encoder: factory.create_command_buffer().into(),
|
// directed_encoder: factory.create_command_buffer().into(),
|
||||||
point_depth_stencil_view,
|
point_depth_stencil_view,
|
||||||
point_res,
|
|
||||||
point_sampler,
|
point_sampler,
|
||||||
|
|
||||||
point_pipeline,
|
point_pipeline,
|
||||||
@ -377,34 +408,36 @@ impl Renderer {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let sampler = factory.create_sampler(gfx::texture::SamplerInfo::new(
|
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
||||||
gfx::texture::FilterMethod::Bilinear,
|
label: None,
|
||||||
gfx::texture::WrapMode::Clamp,
|
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||||
));
|
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||||
|
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||||
|
mag_filter: wgpu::FilterMode::Linear,
|
||||||
|
min_filter: wgpu::FilterMode::Linear,
|
||||||
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
|
compare: None,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
let noise_tex = Texture::new(
|
let noise_tex = Texture::new(
|
||||||
&mut factory,
|
&device,
|
||||||
|
&queue,
|
||||||
&assets::Image::load_expect("voxygen.texture.noise").read().0,
|
&assets::Image::load_expect("voxygen.texture.noise").read().0,
|
||||||
Some(gfx::texture::FilterMethod::Trilinear),
|
Some(wgpu::FilterMode::Linear),
|
||||||
Some(gfx::texture::WrapMode::Tile),
|
Some(wgpu::AddressMode::Repeat),
|
||||||
None,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
device,
|
device,
|
||||||
encoder: factory.create_command_buffer().into(),
|
queue,
|
||||||
factory,
|
swap_chain,
|
||||||
|
|
||||||
win_color_view,
|
|
||||||
win_depth_view,
|
win_depth_view,
|
||||||
|
|
||||||
tgt_color_view,
|
tgt_color_view,
|
||||||
tgt_depth_stencil_view,
|
tgt_depth_stencil_view,
|
||||||
tgt_color_view_pp,
|
tgt_color_pp_view,
|
||||||
|
|
||||||
tgt_color_res,
|
|
||||||
tgt_depth_res,
|
|
||||||
tgt_color_res_pp,
|
|
||||||
|
|
||||||
sampler,
|
sampler,
|
||||||
|
|
||||||
@ -483,7 +516,7 @@ impl Renderer {
|
|||||||
let (
|
let (
|
||||||
tgt_color_view,
|
tgt_color_view,
|
||||||
tgt_depth_stencil_view,
|
tgt_depth_stencil_view,
|
||||||
tgt_color_view_pp,
|
tgt_color_pp_view,
|
||||||
tgt_color_res,
|
tgt_color_res,
|
||||||
tgt_depth_res,
|
tgt_depth_res,
|
||||||
tgt_color_res_pp,
|
tgt_color_res_pp,
|
||||||
@ -493,7 +526,7 @@ impl Renderer {
|
|||||||
self.tgt_color_res_pp = tgt_color_res_pp;
|
self.tgt_color_res_pp = tgt_color_res_pp;
|
||||||
self.tgt_color_view = tgt_color_view;
|
self.tgt_color_view = tgt_color_view;
|
||||||
self.tgt_depth_stencil_view = tgt_depth_stencil_view;
|
self.tgt_depth_stencil_view = tgt_depth_stencil_view;
|
||||||
self.tgt_color_view_pp = tgt_color_view_pp;
|
self.tgt_color_pp_view = tgt_color_pp_view;
|
||||||
if let (Some(shadow_map), ShadowMode::Map(mode)) =
|
if let (Some(shadow_map), ShadowMode::Map(mode)) =
|
||||||
(self.shadow_map.as_mut(), self.mode.shadow)
|
(self.shadow_map.as_mut(), self.mode.shadow)
|
||||||
{
|
{
|
||||||
@ -525,90 +558,103 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_rt_views(
|
fn create_rt_views(
|
||||||
factory: &mut gfx_device_gl::Factory,
|
device: &wgpu::Device,
|
||||||
size: (u16, u16),
|
size: (u16, u16),
|
||||||
mode: &RenderMode,
|
mode: &RenderMode,
|
||||||
) -> Result<
|
) -> Result<(wgpu::TextureView, wgpu::TextureView, wgpu::TextureView, wgpu::TextureView), RenderError> {
|
||||||
(
|
|
||||||
TgtColorView,
|
|
||||||
TgtDepthStencilView,
|
|
||||||
TgtColorView,
|
|
||||||
TgtColorRes,
|
|
||||||
TgtDepthRes,
|
|
||||||
TgtColorRes,
|
|
||||||
),
|
|
||||||
RenderError,
|
|
||||||
> {
|
|
||||||
let upscaled = Vec2::from(size)
|
let upscaled = Vec2::from(size)
|
||||||
.map(|e: u16| (e as f32 * mode.upscale_mode.factor) as u16)
|
.map(|e: u16| (e as f32 * mode.upscale_mode.factor) as u16)
|
||||||
.into_tuple();
|
.into_tuple();
|
||||||
let kind = match mode.aa {
|
let (width, height, sample_count) = match mode.aa {
|
||||||
AaMode::None | AaMode::Fxaa => {
|
AaMode::None | AaMode::Fxaa => (upscaled.0, upscaled.1, 1),
|
||||||
gfx::texture::Kind::D2(upscaled.0, upscaled.1, gfx::texture::AaMode::Single)
|
|
||||||
},
|
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::MsaaX4 => {
|
// TODO: Figure out how to do upscaling correctly with SSAA
|
||||||
gfx::texture::Kind::D2(upscaled.0, upscaled.1, gfx::texture::AaMode::Multi(4))
|
AaMode::MsaaX4 => (upscaled.0, upscaled.1, 4),
|
||||||
},
|
AaMode::MsaaX8 => (upscaled.0, upscaled.1, 8),
|
||||||
AaMode::MsaaX8 => {
|
AaMode::MsaaX16 => (upscaled.0, upscaled.1, 16),
|
||||||
gfx::texture::Kind::D2(upscaled.0, upscaled.1, gfx::texture::AaMode::Multi(8))
|
|
||||||
},
|
|
||||||
AaMode::MsaaX16 => {
|
|
||||||
gfx::texture::Kind::D2(upscaled.0, upscaled.1, gfx::texture::AaMode::Multi(16))
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
let levels = 1;
|
let levels = 1;
|
||||||
|
|
||||||
let color_cty = <<TgtColorFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped
|
let mut color_view = || {
|
||||||
>::get_channel_type();
|
let tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
let mut color_tex = || {
|
label: None,
|
||||||
factory.create_texture(
|
size: wgpu::Extent3d {
|
||||||
kind,
|
width,
|
||||||
levels,
|
height,
|
||||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::RENDER_TARGET,
|
depth: 1,
|
||||||
gfx::memory::Usage::Data,
|
},
|
||||||
Some(color_cty),
|
mip_level_count: levels,
|
||||||
)
|
sample_count,
|
||||||
};
|
dimension: wgpu::TextureDimension::D2,
|
||||||
let tgt_color_tex = color_tex()?;
|
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||||
let tgt_color_tex_pp = color_tex()?;
|
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||||
let mut color_res = |tex| {
|
});
|
||||||
factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
|
||||||
tex,
|
|
||||||
(0, levels - 1),
|
|
||||||
gfx::format::Swizzle::new(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let tgt_color_res = color_res(&tgt_color_tex)?;
|
|
||||||
let tgt_color_res_pp = color_res(&tgt_color_tex_pp)?;
|
|
||||||
let tgt_color_view = factory.view_texture_as_render_target(&tgt_color_tex, 0, None)?;
|
|
||||||
let tgt_color_view_pp =
|
|
||||||
factory.view_texture_as_render_target(&tgt_color_tex_pp, 0, None)?;
|
|
||||||
|
|
||||||
let depth_stencil_cty = <<TgtDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
let tgt_depth_stencil_tex = factory.create_texture(
|
label: None,
|
||||||
kind,
|
format: Some(wgpu::TextureFormat::Rgba8UnormSrgb),
|
||||||
levels,
|
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
aspect: wgpu::TextureAspect::Color,
|
||||||
gfx::memory::Usage::Data,
|
base_mip_level: 0,
|
||||||
Some(depth_stencil_cty),
|
level_count: Some(levels),
|
||||||
)?;
|
base_array_layer: 0,
|
||||||
let tgt_depth_res = factory.view_texture_as_shader_resource::<TgtDepthStencilFmt>(
|
array_layer_count: None,
|
||||||
&tgt_depth_stencil_tex,
|
})
|
||||||
(0, levels - 1),
|
};
|
||||||
gfx::format::Swizzle::new(),
|
|
||||||
)?;
|
let tgt_color_view = color_view();
|
||||||
|
let tgt_color_pp_view = color_view();
|
||||||
|
|
||||||
|
let tgt_depth_stencil_tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
|
label: None,
|
||||||
|
size: wgpu::Extent3d {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
depth: 1,
|
||||||
|
},
|
||||||
|
mip_level_count: levels,
|
||||||
|
sample_count,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Depth24Plus,
|
||||||
|
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||||
|
});
|
||||||
let tgt_depth_stencil_view =
|
let tgt_depth_stencil_view =
|
||||||
factory.view_texture_as_depth_stencil_trivial(&tgt_depth_stencil_tex)?;
|
tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
|
label: None,
|
||||||
|
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||||
|
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||||
|
aspect: wgpu::TextureAspect::DepthOnly,
|
||||||
|
base_mip_level: 0,
|
||||||
|
level_count: Some(levels),
|
||||||
|
base_array_layer: 0,
|
||||||
|
array_layer_count: None,
|
||||||
|
});
|
||||||
|
|
||||||
Ok((
|
let win_depth_tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
tgt_color_view,
|
label: None,
|
||||||
tgt_depth_stencil_view,
|
size: wgpu::Extent3d {
|
||||||
tgt_color_view_pp,
|
width: size.0,
|
||||||
tgt_color_res,
|
height: size.1,
|
||||||
tgt_depth_res,
|
depth: 1,
|
||||||
tgt_color_res_pp,
|
},
|
||||||
))
|
mip_level_count: levels,
|
||||||
|
sample_count,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Depth24Plus,
|
||||||
|
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||||
|
});
|
||||||
|
let win_depth_view = tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
|
label: None,
|
||||||
|
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||||
|
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||||
|
aspect: wgpu::TextureAspect::DepthOnly,
|
||||||
|
base_mip_level: 0,
|
||||||
|
level_count: Some(levels),
|
||||||
|
base_array_layer: 0,
|
||||||
|
array_layer_count: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok((tgt_color_view, tgt_depth_stencil_view, tgt_color_pp_view, win_depth_view))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create textures and views for shadow maps.
|
/// Create textures and views for shadow maps.
|
||||||
@ -616,24 +662,24 @@ impl Renderer {
|
|||||||
// disable the type complexity lint.
|
// disable the type complexity lint.
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
fn create_shadow_views(
|
fn create_shadow_views(
|
||||||
factory: &mut gfx_device_gl::Factory,
|
device: &wgpu::Device,
|
||||||
size: (u16, u16),
|
size: (u16, u16),
|
||||||
mode: &ShadowMapMode,
|
mode: &ShadowMapMode,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
ShadowDepthStencilView,
|
wgpu::TextureView,
|
||||||
ShadowResourceView,
|
wgpu::Sampler,
|
||||||
Sampler<gfx_backend::Resources>,
|
wgpu::TextureView,
|
||||||
ShadowDepthStencilView,
|
wgpu::Sampler,
|
||||||
ShadowResourceView,
|
|
||||||
Sampler<gfx_backend::Resources>,
|
|
||||||
),
|
),
|
||||||
RenderError,
|
RenderError,
|
||||||
> {
|
> {
|
||||||
// (Attempt to) apply resolution factor to shadow map resolution.
|
// (Attempt to) apply resolution factor to shadow map resolution.
|
||||||
let resolution_factor = mode.resolution.clamped(0.25, 4.0);
|
let resolution_factor = mode.resolution.clamped(0.25, 4.0);
|
||||||
|
|
||||||
let max_texture_size = Self::max_texture_size_raw(factory);
|
// This value is temporary as there are plans to include a way to get this in
|
||||||
|
// wgpu this is just a sane standard for now
|
||||||
|
let max_texture_size = 8000;
|
||||||
// Limit to max texture size, rather than erroring.
|
// Limit to max texture size, rather than erroring.
|
||||||
let size = Vec2::new(size.0, size.1).map(|e| {
|
let size = Vec2::new(size.0, size.1).map(|e| {
|
||||||
let size = f32::from(e) * resolution_factor;
|
let size = f32::from(e) * resolution_factor;
|
||||||
@ -677,72 +723,76 @@ impl Renderer {
|
|||||||
.filter(|&e| e <= max_texture_size)
|
.filter(|&e| e <= max_texture_size)
|
||||||
// Limit to max texture resolution rather than error.
|
// Limit to max texture resolution rather than error.
|
||||||
.unwrap_or(max_texture_size);
|
.unwrap_or(max_texture_size);
|
||||||
let depth_stencil_cty = <<ShadowDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
|
||||||
|
|
||||||
let point_shadow_tex = factory
|
let point_shadow_tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
.create_texture(
|
label: None,
|
||||||
gfx::texture::Kind::Cube(diag_two_size / 4),
|
size: wgpu::Extent3d {
|
||||||
levels as gfx::texture::Level,
|
width: diag_two_size / 4,
|
||||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
height: diag_two_size / 4,
|
||||||
gfx::memory::Usage::Data,
|
depth: 6,
|
||||||
Some(depth_stencil_cty),
|
},
|
||||||
)
|
mip_level_count: levels,
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Depth24Plus,
|
||||||
|
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||||
|
});
|
||||||
|
|
||||||
let point_tgt_shadow_view = factory
|
let point_tgt_shadow_view = point_shadow_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
label: None,
|
||||||
&point_shadow_tex,
|
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||||
0,
|
dimension: Some(wgpu::TextureViewDimension::Cube),
|
||||||
None,
|
aspect: wgpu::TextureAspect::DepthOnly,
|
||||||
gfx::texture::DepthStencilFlags::empty(),
|
base_mip_level: 0,
|
||||||
)?;
|
level_count: Some(levels),
|
||||||
|
base_array_layer: 0,
|
||||||
|
array_layer_count: None,
|
||||||
|
});
|
||||||
|
|
||||||
let point_tgt_shadow_res = factory
|
let directed_shadow_tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
.view_texture_as_shader_resource::<ShadowDepthStencilFmt>(
|
label: None,
|
||||||
&point_shadow_tex,
|
size: wgpu::Extent3d {
|
||||||
(0, levels - 1),
|
width: diag_two_size,
|
||||||
gfx::format::Swizzle::new(),
|
height: diag_two_size,
|
||||||
)?;
|
depth: 1,
|
||||||
|
},
|
||||||
|
mip_level_count: levels,
|
||||||
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Depth24Plus,
|
||||||
|
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||||
|
});
|
||||||
|
|
||||||
let directed_shadow_tex = factory
|
let directed_tgt_shadow_view = point_shadow_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
.create_texture(
|
label: None,
|
||||||
gfx::texture::Kind::D2(diag_two_size, diag_two_size, gfx::texture::AaMode::Single),
|
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||||
levels as gfx::texture::Level,
|
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
aspect: wgpu::TextureAspect::DepthOnly,
|
||||||
gfx::memory::Usage::Data,
|
base_mip_level: 0,
|
||||||
Some(depth_stencil_cty),
|
level_count: Some(levels),
|
||||||
)
|
base_array_layer: 0,
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
array_layer_count: None,
|
||||||
let directed_tgt_shadow_view = factory
|
});
|
||||||
.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
|
||||||
&directed_shadow_tex,
|
|
||||||
0,
|
|
||||||
None,
|
|
||||||
gfx::texture::DepthStencilFlags::empty(),
|
|
||||||
)?;
|
|
||||||
let directed_tgt_shadow_res = factory
|
|
||||||
.view_texture_as_shader_resource::<ShadowDepthStencilFmt>(
|
|
||||||
&directed_shadow_tex,
|
|
||||||
(0, levels - 1),
|
|
||||||
gfx::format::Swizzle::new(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let mut sampler_info = gfx::texture::SamplerInfo::new(
|
let sampler_info = wgpu::SamplerDescriptor {
|
||||||
gfx::texture::FilterMethod::Bilinear,
|
label: None,
|
||||||
// Lights should always be assumed to flood areas we can't see.
|
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||||
gfx::texture::WrapMode::Border,
|
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||||
);
|
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||||
sampler_info.comparison = Some(Comparison::LessEqual);
|
mag_filter: wgpu::FilterMode::Linear,
|
||||||
sampler_info.border = [1.0; 4].into();
|
min_filter: wgpu::FilterMode::Linear,
|
||||||
let point_shadow_tex_sampler = factory.create_sampler(sampler_info);
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
let directed_shadow_tex_sampler = factory.create_sampler(sampler_info);
|
compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let point_shadow_tex_sampler = device.create_sampler(&sampler_info);
|
||||||
|
let directed_shadow_tex_sampler = device.create_sampler(&sampler_info);
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
point_tgt_shadow_view,
|
point_tgt_shadow_view,
|
||||||
point_tgt_shadow_res,
|
|
||||||
point_shadow_tex_sampler,
|
point_shadow_tex_sampler,
|
||||||
directed_tgt_shadow_view,
|
directed_tgt_shadow_view,
|
||||||
directed_tgt_shadow_res,
|
|
||||||
directed_shadow_tex_sampler,
|
directed_shadow_tex_sampler,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -797,51 +847,22 @@ impl Renderer {
|
|||||||
/// available.
|
/// available.
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn enable_seamless_cube_maps(device: &mut gfx_backend::Device) {
|
fn enable_seamless_cube_maps(device: &mut gfx_backend::Device) {
|
||||||
unsafe {
|
todo!()
|
||||||
// NOTE: Currently just fail silently rather than complain if the computer is on
|
// unsafe {
|
||||||
// a version lower than 3.2, where seamless cubemaps were introduced.
|
// // NOTE: Currently just fail silently rather than complain if the
|
||||||
if !device.get_info().is_version_supported(3, 2) {
|
// computer is on // a version lower than 3.2, where
|
||||||
return;
|
// seamless cubemaps were introduced. if !device.get_info().
|
||||||
}
|
// is_version_supported(3, 2) { return;
|
||||||
|
// }
|
||||||
|
|
||||||
// NOTE: Safe because GL_TEXTURE_CUBE_MAP_SEAMLESS is supported by OpenGL 3.2+
|
// // NOTE: Safe because GL_TEXTURE_CUBE_MAP_SEAMLESS is supported
|
||||||
// (see https://www.khronos.org/opengl/wiki/Cubemap_Texture#Seamless_cubemap);
|
// by OpenGL 3.2+ // (see https://www.khronos.org/opengl/wiki/Cubemap_Texture#Seamless_cubemap);
|
||||||
// enabling seamless cube maps should always be safe regardless of the state of
|
// // enabling seamless cube maps should always be safe regardless
|
||||||
// the OpenGL context, so no further checks are needed.
|
// of the state of // the OpenGL context, so no further
|
||||||
device.with_gl(|gl| {
|
// checks are needed. device.with_gl(|gl| {
|
||||||
gl.Enable(gfx_gl::TEXTURE_CUBE_MAP_SEAMLESS);
|
// gl.Enable(gfx_gl::TEXTURE_CUBE_MAP_SEAMLESS);
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
/// NOTE: Supported by all but a handful of mobile GPUs
|
|
||||||
/// (see https://github.com/gpuweb/gpuweb/issues/480)
|
|
||||||
/// so wgpu should support it too.
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
fn set_depth_clamp(device: &mut gfx_backend::Device, depth_clamp: bool) {
|
|
||||||
unsafe {
|
|
||||||
// NOTE: Currently just fail silently rather than complain if the computer is on
|
|
||||||
// a version lower than 3.3, though we probably will complain
|
|
||||||
// elsewhere regardless, since shadow mapping is an optional feature
|
|
||||||
// and having depth clamping disabled won't cause undefined
|
|
||||||
// behavior, just incorrect shadowing from objects behind the viewer.
|
|
||||||
if !device.get_info().is_version_supported(3, 3) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Safe because glDepthClamp is (I believe) supported by
|
|
||||||
// OpenGL 3.3, so we shouldn't have to check for other OpenGL versions which
|
|
||||||
// may use different extensions. Also, enabling depth clamping should
|
|
||||||
// essentially always be safe regardless of the state of the OpenGL
|
|
||||||
// context, so no further checks are needed.
|
|
||||||
device.with_gl(|gl| {
|
|
||||||
if depth_clamp {
|
|
||||||
gl.Enable(gfx_gl::DEPTH_CLAMP);
|
|
||||||
} else {
|
|
||||||
gl.Disable(gfx_gl::DEPTH_CLAMP);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Queue the clearing of the depth target ready for a new frame to be
|
/// Queue the clearing of the depth target ready for a new frame to be
|
||||||
@ -1109,47 +1130,58 @@ impl Renderer {
|
|||||||
/// a image::DynamicImage.
|
/// a image::DynamicImage.
|
||||||
#[allow(clippy::map_clone)] // TODO: Pending review in #587
|
#[allow(clippy::map_clone)] // TODO: Pending review in #587
|
||||||
pub fn create_screenshot(&mut self) -> Result<image::DynamicImage, RenderError> {
|
pub fn create_screenshot(&mut self) -> Result<image::DynamicImage, RenderError> {
|
||||||
let (width, height) = self.get_resolution().into_tuple();
|
todo!()
|
||||||
use gfx::{
|
// let (width, height) = self.get_resolution().into_tuple();
|
||||||
format::{Formatted, SurfaceTyped},
|
|
||||||
memory::Typed,
|
|
||||||
};
|
|
||||||
type WinSurfaceData = <<WinColorFmt as Formatted>::Surface as SurfaceTyped>::DataType;
|
|
||||||
let download = self
|
|
||||||
.factory
|
|
||||||
.create_download_buffer::<WinSurfaceData>(width as usize * height as usize)?;
|
|
||||||
self.encoder.copy_texture_to_buffer_raw(
|
|
||||||
self.win_color_view.raw().get_texture(),
|
|
||||||
None,
|
|
||||||
gfx::texture::RawImageInfo {
|
|
||||||
xoffset: 0,
|
|
||||||
yoffset: 0,
|
|
||||||
zoffset: 0,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
depth: 0,
|
|
||||||
format: WinColorFmt::get_format(),
|
|
||||||
mipmap: 0,
|
|
||||||
},
|
|
||||||
download.raw(),
|
|
||||||
0,
|
|
||||||
)?;
|
|
||||||
self.flush();
|
|
||||||
|
|
||||||
// Assumes that the format is Rgba8.
|
// let download_buf = self
|
||||||
let raw_data = self
|
// .device
|
||||||
.factory
|
// .create_buffer(&wgpu::BufferDescriptor {
|
||||||
.read_mapping(&download)?
|
// label: None,
|
||||||
.chunks_exact(width as usize)
|
// size: width * height * 4,
|
||||||
.rev()
|
// usage : wgpu::BufferUsage::COPY_DST,
|
||||||
.flatten()
|
// mapped_at_creation: true
|
||||||
.flatten()
|
// });
|
||||||
.map(|&e| e)
|
|
||||||
.collect::<Vec<_>>();
|
// let encoder =
|
||||||
Ok(image::DynamicImage::ImageRgba8(
|
// self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor
|
||||||
// Should not fail if the dimensions are correct.
|
// {label: None});
|
||||||
image::ImageBuffer::from_raw(width as u32, height as u32, raw_data).unwrap(),
|
|
||||||
))
|
// encoder.copy_texture_to_buffer(&wgpu::TextureCopyViewBase {
|
||||||
|
// origin: &self.wi
|
||||||
|
// }, destination, copy_size)
|
||||||
|
|
||||||
|
// self.encoder.copy_texture_to_buffer_raw(
|
||||||
|
// self.win_color_view.raw().get_texture(),
|
||||||
|
// None,
|
||||||
|
// gfx::texture::RawImageInfo {
|
||||||
|
// xoffset: 0,
|
||||||
|
// yoffset: 0,
|
||||||
|
// zoffset: 0,
|
||||||
|
// width,
|
||||||
|
// height,
|
||||||
|
// depth: 0,
|
||||||
|
// format: WinColorFmt::get_format(),
|
||||||
|
// mipmap: 0,
|
||||||
|
// },
|
||||||
|
// download.raw(),
|
||||||
|
// 0,
|
||||||
|
// )?;
|
||||||
|
// self.flush();
|
||||||
|
|
||||||
|
// // Assumes that the format is Rgba8.
|
||||||
|
// let raw_data = self
|
||||||
|
// .factory
|
||||||
|
// .read_mapping(&download)?
|
||||||
|
// .chunks_exact(width as usize)
|
||||||
|
// .rev()
|
||||||
|
// .flatten()
|
||||||
|
// .flatten()
|
||||||
|
// .map(|&e| e)
|
||||||
|
// .collect::<Vec<_>>();
|
||||||
|
// Ok(image::DynamicImage::ImageRgba8(
|
||||||
|
// // Should not fail if the dimensions are correct.
|
||||||
|
// image::ImageBuffer::from_raw(width as u32, height as u32,
|
||||||
|
// raw_data).unwrap(), ))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Queue the rendering of the provided skybox model in the upcoming frame.
|
/// Queue the rendering of the provided skybox model in the upcoming frame.
|
||||||
@ -1825,7 +1857,7 @@ impl Renderer {
|
|||||||
color_sampler: (self.tgt_color_res.clone(), self.sampler.clone()),
|
color_sampler: (self.tgt_color_res.clone(), self.sampler.clone()),
|
||||||
depth_sampler: (self.tgt_depth_res.clone(), self.sampler.clone()),
|
depth_sampler: (self.tgt_depth_res.clone(), self.sampler.clone()),
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view_pp.clone(),
|
tgt_color: self.tgt_color_pp_view.clone(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,38 +1,22 @@
|
|||||||
use super::{gfx_backend, RenderError};
|
use super::RenderError;
|
||||||
use gfx::{self, traits::Factory};
|
|
||||||
use image::{DynamicImage, GenericImageView};
|
use image::{DynamicImage, GenericImageView};
|
||||||
use vek::Vec2;
|
use vek::Vec2;
|
||||||
|
use wgpu::{util::DeviceExt, Extent3d};
|
||||||
type DefaultShaderFormat = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
|
|
||||||
|
|
||||||
/// Represents an image that has been uploaded to the GPU.
|
/// Represents an image that has been uploaded to the GPU.
|
||||||
#[derive(Clone)]
|
pub struct Texture {
|
||||||
pub struct Texture<F: gfx::format::Formatted = DefaultShaderFormat>
|
pub tex: wgpu::TextureView,
|
||||||
where
|
pub sampler: wgpu::Sampler,
|
||||||
F::Surface: gfx::format::TextureSurface,
|
size: Extent3d,
|
||||||
F::Channel: gfx::format::TextureChannel,
|
|
||||||
<F::Surface as gfx::format::SurfaceTyped>::DataType: Copy,
|
|
||||||
{
|
|
||||||
pub tex: gfx::handle::Texture<gfx_backend::Resources, <F as gfx::format::Formatted>::Surface>,
|
|
||||||
pub srv: gfx::handle::ShaderResourceView<
|
|
||||||
gfx_backend::Resources,
|
|
||||||
<F as gfx::format::Formatted>::View,
|
|
||||||
>,
|
|
||||||
pub sampler: gfx::handle::Sampler<gfx_backend::Resources>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: gfx::format::Formatted> Texture<F>
|
impl Texture {
|
||||||
where
|
|
||||||
F::Surface: gfx::format::TextureSurface,
|
|
||||||
F::Channel: gfx::format::TextureChannel,
|
|
||||||
<F::Surface as gfx::format::SurfaceTyped>::DataType: Copy,
|
|
||||||
{
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
factory: &mut gfx_backend::Factory,
|
device: &wgpu::Device,
|
||||||
|
queue: &wgpu::Queue,
|
||||||
image: &DynamicImage,
|
image: &DynamicImage,
|
||||||
filter_method: Option<gfx::texture::FilterMethod>,
|
filter_method: Option<wgpu::FilterMode>,
|
||||||
wrap_mode: Option<gfx::texture::WrapMode>,
|
addresse_mode: Option<wgpu::AddressMode>,
|
||||||
border: Option<gfx::texture::PackedColor>,
|
|
||||||
) -> Result<Self, RenderError> {
|
) -> Result<Self, RenderError> {
|
||||||
// TODO: Actualy handle images that aren't in rgba format properly.
|
// TODO: Actualy handle images that aren't in rgba format properly.
|
||||||
let buffer = image.as_flat_samples_u8().ok_or_else(|| {
|
let buffer = image.as_flat_samples_u8().ok_or_else(|| {
|
||||||
@ -40,147 +24,143 @@ where
|
|||||||
"We currently do not support color formats using more than 4 bytes / pixel.".into(),
|
"We currently do not support color formats using more than 4 bytes / pixel.".into(),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let (tex, srv) = factory
|
|
||||||
.create_texture_immutable_u8::<F>(
|
|
||||||
gfx::texture::Kind::D2(
|
|
||||||
image.width() as u16,
|
|
||||||
image.height() as u16,
|
|
||||||
gfx::texture::AaMode::Single,
|
|
||||||
),
|
|
||||||
gfx::texture::Mipmap::Provided,
|
|
||||||
// Guarenteed to be correct, since all the conversions from DynamicImage to
|
|
||||||
// FlatSamples<u8> go through the underlying ImageBuffer's implementation of
|
|
||||||
// as_flat_samples(), which guarantees that the resulting FlatSamples is
|
|
||||||
// well-formed.
|
|
||||||
&[buffer.as_slice()],
|
|
||||||
)
|
|
||||||
.map_err(RenderError::CombinedError)?;
|
|
||||||
|
|
||||||
let mut sampler_info = gfx::texture::SamplerInfo::new(
|
let size = Extent3d {
|
||||||
filter_method.unwrap_or(gfx::texture::FilterMethod::Scale),
|
width: image.width(),
|
||||||
wrap_mode.unwrap_or(gfx::texture::WrapMode::Clamp),
|
height: image.height(),
|
||||||
|
depth: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
|
label: None,
|
||||||
|
size,
|
||||||
|
mip_level_count: 1,
|
||||||
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||||
|
usage: wgpu::TextureUsage::COPY_DST | wgpu::TextureUsage::SAMPLED,
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut command_encoder =
|
||||||
|
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||||
|
|
||||||
|
queue.write_texture(
|
||||||
|
wgpu::TextureCopyViewBase {
|
||||||
|
texture: &tex,
|
||||||
|
mip_level: 0,
|
||||||
|
origin: wgpu::Origin3d::ZERO,
|
||||||
|
},
|
||||||
|
&[buffer.as_slice()],
|
||||||
|
wgpu::TextureDataLayout {
|
||||||
|
offset: 0,
|
||||||
|
bytes_per_row: image.width() * 4,
|
||||||
|
rows_per_image: image.height(),
|
||||||
|
},
|
||||||
|
wgpu::Extent3d {
|
||||||
|
width: image.width(),
|
||||||
|
height: image.height(),
|
||||||
|
depth: 1,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
let transparent = [0.0, 0.0, 0.0, 1.0].into();
|
|
||||||
sampler_info.border = border.unwrap_or(transparent);
|
let sampler_info = wgpu::SamplerDescriptor {
|
||||||
|
label: None,
|
||||||
|
address_mode_u: addresse_mode.unwrap_or(wgpu::AddressMode::ClampToEdge),
|
||||||
|
address_mode_v: addresse_mode.unwrap_or(wgpu::AddressMode::ClampToEdge),
|
||||||
|
address_mode_w: addresse_mode.unwrap_or(wgpu::AddressMode::ClampToEdge),
|
||||||
|
mag_filter: filter_method.unwrap_or(wgpu::FilterMode::Nearest),
|
||||||
|
min_filter: filter_method.unwrap_or(wgpu::FilterMode::Nearest),
|
||||||
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
tex,
|
tex,
|
||||||
srv,
|
sampler: device.create_sampler(&sampler_info),
|
||||||
sampler: factory.create_sampler(sampler_info),
|
size,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_dynamic(
|
pub fn new_dynamic(device: &wgpu::Device, width: u16, height: u16) -> Self {
|
||||||
factory: &mut gfx_backend::Factory,
|
let size = wgpu::Extent3d {
|
||||||
width: u16,
|
|
||||||
height: u16,
|
|
||||||
) -> Result<Self, RenderError> {
|
|
||||||
let tex = factory.create_texture(
|
|
||||||
gfx::texture::Kind::D2(
|
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
gfx::texture::AaMode::Single,
|
depth: 1,
|
||||||
),
|
};
|
||||||
1_u8,
|
|
||||||
gfx::memory::Bind::SHADER_RESOURCE,
|
|
||||||
gfx::memory::Usage::Dynamic,
|
|
||||||
Some(<<F as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type()),
|
|
||||||
)
|
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
|
||||||
|
|
||||||
let srv = factory
|
let tex_info = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
.view_texture_as_shader_resource::<F>(&tex, (0, 0), gfx::format::Swizzle::new())
|
label: None,
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Resource(err)))?;
|
size,
|
||||||
|
mip_level_count: 1,
|
||||||
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||||
|
usage: wgpu::TextureUsage::COPY_DST | wgpu::TextureUsage::SAMPLED,
|
||||||
|
});
|
||||||
|
|
||||||
Ok(Self {
|
let sampler_info = wgpu::SamplerDescriptor {
|
||||||
tex,
|
label: None,
|
||||||
srv,
|
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||||
sampler: factory.create_sampler(gfx::texture::SamplerInfo::new(
|
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||||
gfx::texture::FilterMethod::Scale,
|
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||||
gfx::texture::WrapMode::Clamp,
|
mag_filter: wgpu::FilterMode::Nearest,
|
||||||
)),
|
min_filter: wgpu::FilterMode::Nearest,
|
||||||
})
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
}
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
pub fn new_immutable_raw(
|
Self::new_raw(device, tex_info, sampler_info)
|
||||||
factory: &mut gfx_backend::Factory,
|
|
||||||
kind: gfx::texture::Kind,
|
|
||||||
mipmap: gfx::texture::Mipmap,
|
|
||||||
data: &[&[<F::Surface as gfx::format::SurfaceTyped>::DataType]],
|
|
||||||
sampler_info: gfx::texture::SamplerInfo,
|
|
||||||
) -> Result<Self, RenderError> {
|
|
||||||
let (tex, srv) = factory
|
|
||||||
.create_texture_immutable::<F>(kind, mipmap, data)
|
|
||||||
.map_err(RenderError::CombinedError)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
tex,
|
|
||||||
srv,
|
|
||||||
sampler: factory.create_sampler(sampler_info),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_raw(
|
pub fn new_raw(
|
||||||
_device: &mut gfx_backend::Device,
|
device: &wgpu::Device,
|
||||||
factory: &mut gfx_backend::Factory,
|
texture_info: wgpu::TextureDescriptor,
|
||||||
kind: gfx::texture::Kind,
|
sampler_info: wgpu::SamplerDescriptor,
|
||||||
max_levels: u8,
|
) -> Self {
|
||||||
bind: gfx::memory::Bind,
|
|
||||||
usage: gfx::memory::Usage,
|
|
||||||
levels: (u8, u8),
|
|
||||||
swizzle: gfx::format::Swizzle,
|
|
||||||
sampler_info: gfx::texture::SamplerInfo,
|
|
||||||
) -> Result<Self, RenderError> {
|
|
||||||
let tex = factory
|
|
||||||
.create_texture(
|
|
||||||
kind,
|
|
||||||
max_levels as gfx::texture::Level,
|
|
||||||
bind | gfx::memory::Bind::SHADER_RESOURCE,
|
|
||||||
usage,
|
|
||||||
Some(<<F as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type())
|
|
||||||
)
|
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
|
||||||
|
|
||||||
let srv = factory
|
|
||||||
.view_texture_as_shader_resource::<F>(&tex, levels, swizzle)
|
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Resource(err)))?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
tex,
|
tex: device.create_texture(&texture_info),
|
||||||
srv,
|
sampler: device.create_sampler(&sampler_info),
|
||||||
sampler: factory.create_sampler(sampler_info),
|
size: texture_info.size,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a texture with the given data (used for updating the glyph cache
|
/// Update a texture with the given data (used for updating the glyph cache
|
||||||
/// texture).
|
/// texture).
|
||||||
|
|
||||||
pub fn update(
|
pub fn update(
|
||||||
&self,
|
&self,
|
||||||
encoder: &mut gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
device: &wgpu::Device,
|
||||||
|
queue: &wgpu::Queue,
|
||||||
offset: [u16; 2],
|
offset: [u16; 2],
|
||||||
size: [u16; 2],
|
size: [u16; 2],
|
||||||
data: &[<F::Surface as gfx::format::SurfaceTyped>::DataType],
|
data: &[u8],
|
||||||
) -> Result<(), RenderError> {
|
) -> Result<(), RenderError> {
|
||||||
let info = gfx::texture::ImageInfoCommon {
|
// TODO: Only works for 2D images
|
||||||
xoffset: offset[0],
|
queue.write_texture(
|
||||||
yoffset: offset[1],
|
wgpu::TextureCopyViewBase {
|
||||||
zoffset: 0,
|
texture: &self.tex,
|
||||||
|
mip_level: 0,
|
||||||
|
origin: wgpu::Origin3d {
|
||||||
|
x: offset[0],
|
||||||
|
y: offset[1],
|
||||||
|
z: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data,
|
||||||
|
// TODO: I heard some rumors that there are other
|
||||||
|
// formats that are not Rgba8
|
||||||
|
wgpu::TextureDataLayout {
|
||||||
|
offset: 0,
|
||||||
|
bytes_per_row: self.size.x * 4,
|
||||||
|
rows_per_image: self.size.y,
|
||||||
|
},
|
||||||
|
wgpu::Extent3d {
|
||||||
width: size[0],
|
width: size[0],
|
||||||
height: size[1],
|
height: size[1],
|
||||||
depth: 0,
|
depth: 1,
|
||||||
format: (),
|
},
|
||||||
mipmap: 0,
|
);
|
||||||
};
|
|
||||||
encoder
|
|
||||||
.update_texture::<<F as gfx::format::Formatted>::Surface, F>(
|
|
||||||
&self.tex, None, info, data,
|
|
||||||
)
|
|
||||||
.map_err(RenderError::TexUpdateError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get dimensions of the represented image.
|
/// Get dimensions of the represented image.
|
||||||
pub fn get_dimensions(&self) -> Vec2<u16> {
|
pub fn get_dimensions(&self) -> Extent3d { self.size }
|
||||||
let (w, h, ..) = self.tex.get_info().kind.get_dimensions();
|
|
||||||
Vec2::new(w, h)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
controller::*,
|
controller::*,
|
||||||
render::{Renderer, WinColorFmt, WinDepthFmt},
|
render::Renderer,
|
||||||
settings::{ControlSettings, Settings},
|
settings::{ControlSettings, Settings},
|
||||||
ui, Error,
|
ui, Error,
|
||||||
};
|
};
|
||||||
@ -12,7 +12,7 @@ use itertools::Itertools;
|
|||||||
use keyboard_keynames::key_layout::KeyLayout;
|
use keyboard_keynames::key_layout::KeyLayout;
|
||||||
use old_school_gfx_glutin_ext::{ContextBuilderExt, WindowInitExt, WindowUpdateExt};
|
use old_school_gfx_glutin_ext::{ContextBuilderExt, WindowInitExt, WindowUpdateExt};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, warn};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use winit::monitor::VideoMode;
|
use winit::monitor::VideoMode;
|
||||||
|
|
||||||
@ -519,7 +519,7 @@ impl KeyMouse {
|
|||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
window: glutin::ContextWrapper<glutin::PossiblyCurrent, winit::window::Window>,
|
window: winit::window::Window,
|
||||||
cursor_grabbed: bool,
|
cursor_grabbed: bool,
|
||||||
pub pan_sensitivity: u32,
|
pub pan_sensitivity: u32,
|
||||||
pub zoom_sensitivity: u32,
|
pub zoom_sensitivity: u32,
|
||||||
@ -565,26 +565,18 @@ impl Window {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (window, device, factory, win_color_view, win_depth_view) =
|
// let (window, device, factory, win_color_view, win_depth_view) =
|
||||||
glutin::ContextBuilder::new()
|
// glutin::ContextBuilder::new()
|
||||||
.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 3)))
|
// .with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 3)))
|
||||||
.with_vsync(false)
|
// .with_vsync(false)
|
||||||
.with_gfx_color_depth::<WinColorFmt, WinDepthFmt>()
|
// .with_gfx_color_depth::<WinColorFmt, WinDepthFmt>()
|
||||||
.build_windowed(win_builder, &event_loop)
|
// .build_windowed(win_builder, &event_loop)
|
||||||
.map_err(|err| Error::BackendError(Box::new(err)))?
|
// .map_err(|err| Error::BackendError(Box::new(err)))?
|
||||||
.init_gfx::<WinColorFmt, WinDepthFmt>();
|
// .init_gfx::<WinColorFmt, WinDepthFmt>();
|
||||||
|
|
||||||
let vendor = device.get_info().platform_name.vendor;
|
let window = win_builder.build(&event_loop)?;
|
||||||
let renderer = device.get_info().platform_name.renderer;
|
|
||||||
let opengl_version = device.get_info().version;
|
let renderer = Renderer::new(&window, settings.graphics.render_mode.clone())?;
|
||||||
let glsl_version = device.get_info().shading_language;
|
|
||||||
info!(
|
|
||||||
?vendor,
|
|
||||||
?renderer,
|
|
||||||
?opengl_version,
|
|
||||||
?glsl_version,
|
|
||||||
"selected graphics device"
|
|
||||||
);
|
|
||||||
|
|
||||||
let keypress_map = HashMap::new();
|
let keypress_map = HashMap::new();
|
||||||
|
|
||||||
@ -632,13 +624,7 @@ impl Window {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
renderer: Renderer::new(
|
renderer,
|
||||||
device,
|
|
||||||
factory,
|
|
||||||
win_color_view,
|
|
||||||
win_depth_view,
|
|
||||||
settings.graphics.render_mode.clone(),
|
|
||||||
)?,
|
|
||||||
window,
|
window,
|
||||||
cursor_grabbed: false,
|
cursor_grabbed: false,
|
||||||
pan_sensitivity: settings.gameplay.pan_sensitivity,
|
pan_sensitivity: settings.gameplay.pan_sensitivity,
|
||||||
@ -1366,7 +1352,7 @@ impl Window {
|
|||||||
pub fn set_size(&mut self, new_size: Vec2<u16>) {
|
pub fn set_size(&mut self, new_size: Vec2<u16>) {
|
||||||
self.window
|
self.window
|
||||||
.window()
|
.window()
|
||||||
.set_inner_size(glutin::dpi::LogicalSize::new(
|
.set_inner_size(winit::dpi::LogicalSize::new(
|
||||||
new_size.x as f64,
|
new_size.x as f64,
|
||||||
new_size.y as f64,
|
new_size.y as f64,
|
||||||
));
|
));
|
||||||
|
Loading…
Reference in New Issue
Block a user