formatting
This commit is contained in:
parent
75a855bb9f
commit
e106242d41
15 changed files with 540 additions and 626 deletions
223
Cargo.lock
generated
223
Cargo.lock
generated
|
@ -43,7 +43,7 @@ dependencies = [
|
|||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
"zerocopy 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -112,6 +112,15 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.9"
|
||||
|
@ -315,7 +324,7 @@ version = "0.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"approx 0.4.0",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
|
@ -443,6 +452,34 @@ dependencies = [
|
|||
"urlencoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
|
@ -523,6 +560,12 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "endian-type"
|
||||
version = "0.1.2"
|
||||
|
@ -752,6 +795,44 @@ dependencies = [
|
|||
"gl_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glyph_brush"
|
||||
version = "0.7.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0060f4ed4ef64a5876d9836d7d6c9ed43a463f3ca431682bec1c326064c8c93e"
|
||||
dependencies = [
|
||||
"glyph_brush_draw_cache",
|
||||
"glyph_brush_layout",
|
||||
"ordered-float 5.0.0",
|
||||
"rustc-hash 2.1.1",
|
||||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glyph_brush_draw_cache"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bb6c910def52365fef3f439a6b50a4d5c11b28eec4cf6c191f6dfea18e88d7f"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"linked-hash-map",
|
||||
"rayon",
|
||||
"rustc-hash 2.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glyph_brush_layout"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b1e288bfd2f6c0313f78bf5aa538356ad481a3bb97e9b7f93220ab0066c5992"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"approx 0.5.1",
|
||||
"xi-unicode",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gpu-alloc"
|
||||
version = "0.6.0"
|
||||
|
@ -1111,6 +1192,12 @@ dependencies = [
|
|||
"redox_syscall 0.5.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
|
@ -1213,7 +1300,7 @@ dependencies = [
|
|||
"hexf-parse",
|
||||
"indexmap",
|
||||
"log",
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.1.0",
|
||||
"spirv",
|
||||
"strum",
|
||||
"termcolor",
|
||||
|
@ -1566,6 +1653,15 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2c1f9f56e534ac6a9b8a4600bdf0f530fb393b5f393e7b4d03489c3cf0c3f01"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
|
@ -1669,6 +1765,15 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy 0.8.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "presser"
|
||||
version = "0.3.1"
|
||||
|
@ -1727,6 +1832,36 @@ dependencies = [
|
|||
"nibble_vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "range-alloc"
|
||||
version = "0.1.4"
|
||||
|
@ -1739,6 +1874,26 @@ version = "0.6.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
|
@ -1815,6 +1970,12 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
|
@ -2302,6 +2463,15 @@ version = "0.25.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
|
||||
|
||||
[[package]]
|
||||
name = "twox-hash"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7b17f197b3050ba473acf9181f7b1d3b66d1cf7356c6cc57886662276e65908"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.18.0"
|
||||
|
@ -2645,7 +2815,7 @@ dependencies = [
|
|||
"parking_lot",
|
||||
"profiling",
|
||||
"raw-window-handle",
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.1.0",
|
||||
"smallvec",
|
||||
"thiserror 2.0.12",
|
||||
"wgpu-hal",
|
||||
|
@ -2682,13 +2852,13 @@ dependencies = [
|
|||
"ndk-sys 0.5.0+25.2.9519653",
|
||||
"objc",
|
||||
"once_cell",
|
||||
"ordered-float",
|
||||
"ordered-float 4.6.0",
|
||||
"parking_lot",
|
||||
"profiling",
|
||||
"range-alloc",
|
||||
"raw-window-handle",
|
||||
"renderdoc-sys",
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.1.0",
|
||||
"smallvec",
|
||||
"thiserror 2.0.12",
|
||||
"wasm-bindgen",
|
||||
|
@ -2710,6 +2880,18 @@ dependencies = [
|
|||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wgpu_text"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccd192487eb81eb51f8f0eb82fea0865e71ab4f002f7942bee0bba04fc2a0b8c"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"glyph_brush",
|
||||
"log",
|
||||
"wgpu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -3136,6 +3318,12 @@ version = "0.3.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61"
|
||||
|
||||
[[package]]
|
||||
name = "xi-unicode"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a"
|
||||
|
||||
[[package]]
|
||||
name = "xkbcommon-dl"
|
||||
version = "0.4.2"
|
||||
|
@ -3220,6 +3408,7 @@ dependencies = [
|
|||
"tracing-subscriber",
|
||||
"typenum",
|
||||
"wgpu",
|
||||
"wgpu_text",
|
||||
"winit",
|
||||
]
|
||||
|
||||
|
@ -3229,7 +3418,16 @@ version = "0.7.35"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
"zerocopy-derive 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
|
||||
dependencies = [
|
||||
"zerocopy-derive 0.8.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3243,6 +3441,17 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.6"
|
||||
|
|
31
Cargo.toml
31
Cargo.toml
|
@ -2,39 +2,16 @@
|
|||
resolver = "2"
|
||||
members = ["engine","subcrates/zen_core"]
|
||||
|
||||
[profile.dev]
|
||||
|
||||
rpath = false
|
||||
panic = "abort"
|
||||
lto = "off"
|
||||
opt-level = 0
|
||||
debug = false
|
||||
overflow-checks = false
|
||||
incremental = true
|
||||
codegen-units = 512
|
||||
|
||||
|
||||
strip = "symbols"
|
||||
debug-assertions = true
|
||||
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 0
|
||||
debug = false
|
||||
overflow-checks = false
|
||||
incremental = true
|
||||
codegen-units = 512
|
||||
|
||||
|
||||
strip = "symbols"
|
||||
debug-assertions = true
|
||||
|
||||
|
||||
[workspace.dependencies]
|
||||
lazy_static = "1.5.0"
|
||||
parking_lot = "0.12.3"
|
||||
|
||||
[profile.release]
|
||||
debug-assertions = false
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
||||
split-debuginfo = "off"
|
||||
|
||||
[profile.dev]
|
||||
debug = 0
|
||||
|
|
22
Pumpkin.mtl
Normal file
22
Pumpkin.mtl
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Blender 4.2.3 LTS MTL File: 'None'
|
||||
# www.blender.org
|
||||
|
||||
newmtl Material.001
|
||||
Ns 0.000000
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.800000 0.800000 0.800000
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.500000
|
||||
d 1.000000
|
||||
illum 1
|
||||
|
||||
newmtl Material.003
|
||||
Ns 0.000000
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.800000 0.800000 0.800000
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.500000
|
||||
d 1.000000
|
||||
illum 1
|
BIN
Pumpkin.obj
(Stored with Git LFS)
Normal file
BIN
Pumpkin.obj
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -40,7 +40,6 @@ in
|
|||
doCheck = false;
|
||||
LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath buildInputs}";
|
||||
|
||||
|
||||
fixupPhase = ''
|
||||
wrapProgram $out/bin/${pname} --set PATH ${bash}/bin:\$PATH --set LD_LIBRARY_PATH ${pkgs.lib.makeLibraryPath buildInputs}
|
||||
'';
|
||||
|
|
|
@ -3,35 +3,42 @@ name = "zenyx"
|
|||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
repository = "https://github.com/Zenyx-Engine/Zenyx"
|
||||
|
||||
[dependencies]
|
||||
# TBR
|
||||
anyhow = "1.0.94"
|
||||
# TBR (if possible)
|
||||
backtrace = "0.3.74"
|
||||
# TBR (if possible)
|
||||
chrono = "0.4.39"
|
||||
colored = "3.0.0"
|
||||
# TBR (if possible)
|
||||
crashreport = "1.0.1"
|
||||
# TBR
|
||||
dirs-next = "2.0.0"
|
||||
|
||||
# TBR == (To be removed)
|
||||
# TBR
|
||||
lazy_static.workspace = true
|
||||
# TBR
|
||||
once_cell = "1.21.1"
|
||||
parking_lot.workspace = true
|
||||
# TBR (if possible)
|
||||
regex = "1.11.1"
|
||||
# TBR (if possible)
|
||||
rustyline = { version = "15.0.0", features = ["derive", "rustyline-derive"] }
|
||||
thiserror = "2.0.11"
|
||||
# Tokio is heavy but so far its the best option, we should make better use of it or switch to another runtime.
|
||||
tokio = { version = "1.44.1", features = ["fs", "macros", "parking_lot", "rt-multi-thread"] }
|
||||
wgpu = "24.0.3"
|
||||
winit = "0.30.9"
|
||||
bytemuck = "1.21.0"
|
||||
# TBR (if possible)
|
||||
futures = "0.3.31"
|
||||
cgmath = "0.18.0"
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = "0.3.19"
|
||||
# TBR
|
||||
typenum = { version = "1.18.0", features = ["const-generics"] }
|
||||
tobj = { version = "4.0.3", features = ["tokio"] }
|
||||
ahash = "0.8.11"
|
||||
|
||||
|
||||
[profile.dev]
|
||||
debug-assertions = true
|
||||
|
||||
[profile.release]
|
||||
debug-assertions = false
|
||||
wgpu_text = "0.9.2"
|
||||
|
|
|
@ -1,334 +0,0 @@
|
|||
use std::{
|
||||
cmp::Ordering,
|
||||
convert::From,
|
||||
fmt,
|
||||
hash::{Hash, Hasher},
|
||||
ops::{
|
||||
Add, AddAssign, BitAnd, BitOr, BitXor, Deref, DerefMut, Div, DivAssign, Mul, MulAssign,
|
||||
Rem, RemAssign, Shl, Shr, Sub, SubAssign,
|
||||
},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct BigInt<const N: usize> {
|
||||
bytes: [u8; N],
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl<const N: usize> BigInt<N> {
|
||||
pub fn from_bytes(bytes: &[u8]) -> Self {
|
||||
debug_assert!(bytes.len() != 0);
|
||||
let mut len = bytes.len();
|
||||
while len > 1 && bytes[len - 1] == 0 {
|
||||
len -= 1;
|
||||
}
|
||||
let mut arr = [0u8; N];
|
||||
arr[..len].copy_from_slice(&bytes[..len]);
|
||||
BigInt { bytes: arr, len }
|
||||
}
|
||||
|
||||
pub fn from_u64(value: u64) -> Self {
|
||||
Self::from_bytes(&value.to_le_bytes())
|
||||
}
|
||||
|
||||
fn trim_zeros(mut self) -> Self {
|
||||
while self.len > 1 && self.bytes[self.len - 1] == 0 {
|
||||
self.len -= 1;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn max_value() -> Self {
|
||||
let mut arr = [0u8; N];
|
||||
arr.fill(255);
|
||||
BigInt { bytes: arr, len: N }
|
||||
}
|
||||
pub fn div_rem(&self, other: &Self) -> (Self, Self) {
|
||||
let mut quotient = BigInt::from(0);
|
||||
let mut remainder = self.clone();
|
||||
let divisor = other.clone();
|
||||
|
||||
while remainder >= divisor {
|
||||
let mut multiple = divisor.clone();
|
||||
let mut temp_quotient = BigInt::from(1);
|
||||
while multiple + multiple <= remainder {
|
||||
multiple = multiple + multiple;
|
||||
temp_quotient = temp_quotient + temp_quotient;
|
||||
}
|
||||
remainder = remainder - multiple;
|
||||
quotient = quotient + temp_quotient;
|
||||
}
|
||||
(quotient.trim_zeros(), remainder.trim_zeros())
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Add for BigInt<N> {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
let mut result = [0u8; N];
|
||||
let mut carry = 0u16;
|
||||
let max_len = self.len.max(rhs.len);
|
||||
let mut res_len = 0;
|
||||
|
||||
for i in 0..max_len {
|
||||
let a = self.bytes.get(i).copied().unwrap_or(0) as u16;
|
||||
let b = rhs.bytes.get(i).copied().unwrap_or(0) as u16;
|
||||
let sum = a + b + carry;
|
||||
result[i] = (sum % 256) as u8;
|
||||
carry = sum / 256;
|
||||
res_len = i + 1;
|
||||
}
|
||||
|
||||
if carry > 0 {
|
||||
result[res_len] = carry as u8;
|
||||
res_len += 1;
|
||||
}
|
||||
|
||||
BigInt {
|
||||
bytes: result,
|
||||
len: res_len,
|
||||
}
|
||||
.trim_zeros()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> AddAssign for BigInt<N> {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = *self + rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Sub for BigInt<N> {
|
||||
type Output = Self;
|
||||
fn sub(self, rhs: Self) -> Self {
|
||||
let mut result = [0u8; N];
|
||||
let mut borrow = 0i16;
|
||||
let mut res_len = 0;
|
||||
|
||||
for i in 0..self.len {
|
||||
let a = self.bytes[i] as i16;
|
||||
let b = rhs.bytes.get(i).copied().unwrap_or(0) as i16;
|
||||
let mut diff = a - b - borrow;
|
||||
borrow = 0;
|
||||
|
||||
if diff < 0 {
|
||||
diff += 256;
|
||||
borrow = 1;
|
||||
}
|
||||
|
||||
result[i] = diff as u8;
|
||||
res_len = i + 1;
|
||||
}
|
||||
|
||||
BigInt {
|
||||
bytes: result,
|
||||
len: res_len,
|
||||
}
|
||||
.trim_zeros()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> SubAssign for BigInt<N> {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = *self - rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Mul for BigInt<N> {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: Self) -> Self {
|
||||
let mut result = BigInt {
|
||||
bytes: [0; N],
|
||||
len: 0,
|
||||
};
|
||||
|
||||
for i in 0..self.len {
|
||||
let mut carry = 0u16;
|
||||
for j in 0..rhs.len {
|
||||
let idx = i + j;
|
||||
if idx >= N {
|
||||
panic!("Multiplication overflow");
|
||||
}
|
||||
let product =
|
||||
self.bytes[i] as u16 * rhs.bytes[j] as u16 + carry + result.bytes[idx] as u16;
|
||||
result.bytes[idx] = (product % 256) as u8;
|
||||
carry = product / 256;
|
||||
}
|
||||
let mut k = i + rhs.len;
|
||||
while carry > 0 && k < N {
|
||||
let sum = result.bytes[k] as u16 + carry;
|
||||
result.bytes[k] = (sum % 256) as u8;
|
||||
carry = sum / 256;
|
||||
k += 1;
|
||||
}
|
||||
result.len = result.len.max(k);
|
||||
}
|
||||
|
||||
result.trim_zeros()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> MulAssign for BigInt<N> {
|
||||
fn mul_assign(&mut self, rhs: Self) {
|
||||
*self = *self * rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Div for BigInt<N> {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: Self) -> Self {
|
||||
self.div_rem(&rhs).0
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> DivAssign for BigInt<N> {
|
||||
fn div_assign(&mut self, rhs: Self) {
|
||||
*self = *self / rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Rem for BigInt<N> {
|
||||
type Output = Self;
|
||||
fn rem(self, rhs: Self) -> Self {
|
||||
self.div_rem(&rhs).1
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> RemAssign for BigInt<N> {
|
||||
fn rem_assign(&mut self, rhs: Self) {
|
||||
*self = *self % rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> PartialEq for BigInt<N> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.bytes[..self.len] == other.bytes[..other.len]
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Eq for BigInt<N> {}
|
||||
|
||||
impl<const N: usize> Hash for BigInt<N> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.bytes[..self.len].hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> PartialOrd for BigInt<N> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Ord for BigInt<N> {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
if self.len != other.len {
|
||||
return self.len.cmp(&other.len);
|
||||
}
|
||||
for i in (0..self.len).rev() {
|
||||
match self.bytes[i].cmp(&other.bytes[i]) {
|
||||
Ordering::Equal => continue,
|
||||
ord => return ord,
|
||||
}
|
||||
}
|
||||
Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Deref for BigInt<N> {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
&self.bytes[..self.len]
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> DerefMut for BigInt<N> {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.bytes[..self.len]
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_int {
|
||||
($($t:ty),*) => {$(
|
||||
impl<const N: usize> From<$t> for BigInt<N> {
|
||||
fn from(value: $t) -> Self {
|
||||
let bytes = value.to_le_bytes();
|
||||
Self::from_bytes(&bytes)
|
||||
}
|
||||
}
|
||||
)*};
|
||||
}
|
||||
|
||||
impl_from_int!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128);
|
||||
|
||||
impl<const N: usize> FromStr for BigInt<N> {
|
||||
type Err = &'static str;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut result = BigInt::from(0u8);
|
||||
for c in s.chars() {
|
||||
if !c.is_digit(10) {
|
||||
return Err("Invalid digit");
|
||||
}
|
||||
let digit = c.to_digit(10).unwrap() as u8;
|
||||
result = result * BigInt::from(10u8) + BigInt::from(digit);
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> fmt::Display for BigInt<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.len == 0 {
|
||||
return write!(f, "0");
|
||||
}
|
||||
let mut digits = Vec::new();
|
||||
let mut bytes = self.bytes[..self.len].to_vec();
|
||||
|
||||
while !bytes.is_empty() {
|
||||
let mut remainder = 0u16;
|
||||
for byte in bytes.iter_mut().rev() {
|
||||
let value = *byte as u16 + remainder * 256;
|
||||
*byte = (value / 10) as u8;
|
||||
remainder = value % 10;
|
||||
}
|
||||
digits.push(remainder as u8);
|
||||
while !bytes.is_empty() && bytes[bytes.len() - 1] == 0 {
|
||||
bytes.pop();
|
||||
}
|
||||
}
|
||||
|
||||
digits.reverse();
|
||||
let s = digits
|
||||
.iter()
|
||||
.map(|d| char::from_digit(*d as u32, 10).unwrap())
|
||||
.collect::<String>();
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||
struct Dint {
|
||||
bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Deref for Dint {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
&self.bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Dint {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.bytes
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
type TheInt = BigInt<2>;
|
||||
let mut test: TheInt = TheInt::max_value();
|
||||
let thing = BigInt::<9>::max_value();
|
||||
test /= 2.into();
|
||||
println!("{test}")
|
||||
}
|
BIN
engine/src/core/render/DejaVuSans.ttf
Normal file
BIN
engine/src/core/render/DejaVuSans.ttf
Normal file
Binary file not shown.
|
@ -6,9 +6,12 @@ use std::time::Instant;
|
|||
use cgmath::{Deg, Matrix4, Point3, Rad, SquareMatrix, Vector3, perspective};
|
||||
use futures::executor::block_on;
|
||||
use thiserror::Error;
|
||||
use tracing::{error, trace};
|
||||
use tracing::{error, info, trace};
|
||||
use wgpu::TextureUsages;
|
||||
use wgpu::{Backends, InstanceDescriptor, util::DeviceExt};
|
||||
use wgpu_text::glyph_brush::ab_glyph::FontRef;
|
||||
use wgpu_text::glyph_brush::{HorizontalAlign, Layout, OwnedSection, OwnedText, VerticalAlign};
|
||||
use wgpu_text::{BrushBuilder, TextBrush};
|
||||
use winit::window::Window;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
@ -129,50 +132,7 @@ impl From<wgpu::RequestDeviceError> for RenderContextError {
|
|||
}
|
||||
}
|
||||
|
||||
const SHADER_SRC: &str = r#"
|
||||
struct CameraUniform {
|
||||
view: mat4x4<f32>,
|
||||
proj: mat4x4<f32>,
|
||||
};
|
||||
|
||||
struct ModelUniform {
|
||||
model: mat4x4<f32>,
|
||||
};
|
||||
|
||||
@group(0) @binding(0)
|
||||
var<uniform> camera: CameraUniform;
|
||||
|
||||
@group(1) @binding(0)
|
||||
var<uniform> model: ModelUniform;
|
||||
|
||||
struct VertexInput {
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) normal: vec3<f32>,
|
||||
};
|
||||
|
||||
@vertex
|
||||
fn vs_main(input: VertexInput) -> VertexOutput {
|
||||
var output: VertexOutput;
|
||||
let model_pos = model.model * vec4<f32>(input.position, 1.0);
|
||||
output.clip_position = camera.proj * camera.view * model_pos;
|
||||
output.normal = input.normal;
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let ambient: f32 = 0.2;
|
||||
let light_dir = normalize(vec3<f32>(0.5, 1.0, 0.5));
|
||||
let diffuse = clamp(dot(normalize(input.normal), light_dir), 0.0, 1.0);
|
||||
let brightness = ambient + (1.0 - ambient) * diffuse;
|
||||
return vec4<f32>(0.7 * brightness, 0.7 * brightness, 0.9 * brightness, 1.0);
|
||||
}
|
||||
"#;
|
||||
const SHADER_SRC: &str = include_str!("shader.wgsl");
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
|
@ -284,7 +244,7 @@ struct Model {
|
|||
index_buffer: wgpu::Buffer,
|
||||
uniform_buffer: wgpu::Buffer,
|
||||
bind_group: wgpu::BindGroup,
|
||||
index_count: u32, // Changed from vertex_count to index_count
|
||||
index_count: u32,
|
||||
transform: Matrix4<f32>,
|
||||
}
|
||||
|
||||
|
@ -359,6 +319,15 @@ pub struct Renderer<'window> {
|
|||
start_time: Instant,
|
||||
last_frame_instant: Instant,
|
||||
frame_count: u32,
|
||||
fps: f32,
|
||||
font_state: FontState,
|
||||
}
|
||||
|
||||
struct FontState {
|
||||
brush: TextBrush<FontRef<'static>>,
|
||||
section: OwnedSection,
|
||||
scale: f32,
|
||||
color: wgpu::Color,
|
||||
}
|
||||
|
||||
impl<'window> Renderer<'window> {
|
||||
|
@ -485,7 +454,6 @@ impl<'window> Renderer<'window> {
|
|||
multiview: None,
|
||||
cache: None,
|
||||
});
|
||||
|
||||
|
||||
let camera = Camera::new(&device, &camera_bind_group_layout, width, height);
|
||||
|
||||
|
@ -508,6 +476,36 @@ impl<'window> Renderer<'window> {
|
|||
// surface_config.format,
|
||||
);
|
||||
|
||||
let font_bytes = include_bytes!("DejaVuSans.ttf");
|
||||
let font = FontRef::try_from_slice(font_bytes).map_err(|e| {
|
||||
RenderContextError::new(
|
||||
ContextErrorKind::DeviceRequest,
|
||||
Some("Font loading".into()),
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
|
||||
let brush =
|
||||
BrushBuilder::using_font(font).build(&device, width, height, surface_config.format);
|
||||
let base_width = 1280.0;
|
||||
let base_scale = 30.0;
|
||||
let scale = base_scale * (surface_config.width as f32 / base_width as f32).clamp(0.5, 2.0);
|
||||
let color = wgpu::Color::WHITE;
|
||||
|
||||
let section = OwnedSection::default()
|
||||
.add_text(OwnedText::new("FPS: 0.00").with_scale(scale).with_color([
|
||||
color.r as f32,
|
||||
color.g as f32,
|
||||
color.b as f32,
|
||||
color.a as f32,
|
||||
]))
|
||||
.with_screen_position((10.0, 10.0))
|
||||
.with_bounds((base_scale * 200.0, base_scale * 2.0))
|
||||
.with_layout(
|
||||
Layout::default()
|
||||
.h_align(HorizontalAlign::Left)
|
||||
.v_align(VerticalAlign::Top),
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
device,
|
||||
|
@ -530,6 +528,13 @@ impl<'window> Renderer<'window> {
|
|||
frame_count: 0,
|
||||
depth_texture,
|
||||
depth_texture_view,
|
||||
fps: 0f32,
|
||||
font_state: FontState {
|
||||
brush,
|
||||
section,
|
||||
scale,
|
||||
color,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -549,12 +554,19 @@ impl<'window> Renderer<'window> {
|
|||
|
||||
pub fn resize(&mut self, new_size: (u32, u32)) {
|
||||
let (width, height) = new_size;
|
||||
let (depth_texture,depth_view) = create_depth_texture(&self.device, width, height);
|
||||
let (depth_texture, depth_view) = create_depth_texture(&self.device, width, height);
|
||||
self.surface_config.width = width.max(1);
|
||||
self.surface_config.height = height.max(1);
|
||||
self.surface.configure(&self.device, &self.surface_config);
|
||||
self.depth_texture = depth_texture;
|
||||
self.depth_texture_view = depth_view;
|
||||
self.font_state
|
||||
.brush
|
||||
.resize_view(width as f32, height as f32, &self.queue);
|
||||
let base_width = 1280.0;
|
||||
let base_scale = 30.0;
|
||||
let scale = base_scale * (width as f32 / base_width as f32).clamp(0.5, 2.0);
|
||||
self.font_state.scale = scale;
|
||||
self.camera.resize(width, height);
|
||||
}
|
||||
|
||||
|
@ -565,7 +577,8 @@ impl<'window> Renderer<'window> {
|
|||
|
||||
for (i, model) in self.models.iter_mut().enumerate() {
|
||||
let angle = Rad(elapsed * 0.8 + i as f32 * 0.3);
|
||||
model.set_transform(Matrix4::from_angle_x(angle) * Matrix4::from_angle_y(angle));
|
||||
model.set_transform(Matrix4::from_angle_y(angle));
|
||||
// model.set_transform(Matrix4::from_angle_x(angle) * Matrix4::from_angle_y(angle));
|
||||
model.update(&self.queue);
|
||||
}
|
||||
|
||||
|
@ -587,6 +600,25 @@ impl<'window> Renderer<'window> {
|
|||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("Render Encoder"),
|
||||
});
|
||||
let fps_text = format!("FPS: {:.2}", self.fps);
|
||||
self.font_state.section.text.clear();
|
||||
self.font_state.section.text.push(
|
||||
OwnedText::new(fps_text)
|
||||
.with_scale(self.font_state.scale)
|
||||
.with_color([
|
||||
self.font_state.color.r as f32,
|
||||
self.font_state.color.g as f32,
|
||||
self.font_state.color.b as f32,
|
||||
self.font_state.color.a as f32,
|
||||
]),
|
||||
);
|
||||
if let Err(e) = self.font_state.brush.queue(
|
||||
&self.device,
|
||||
&self.queue,
|
||||
&[self.font_state.section.clone()],
|
||||
) {
|
||||
error!("Failed to queue text: {}", e);
|
||||
}
|
||||
|
||||
{
|
||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
|
@ -622,15 +654,35 @@ impl<'window> Renderer<'window> {
|
|||
render_pass.draw_indexed(0..model.index_count, 0, 0..1);
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut text_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("Text Render Pass"),
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
occlusion_query_set: None,
|
||||
timestamp_writes: None,
|
||||
});
|
||||
|
||||
self.font_state.brush.draw(&mut text_pass);
|
||||
}
|
||||
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
surface_texture.present();
|
||||
|
||||
self.frame_count += 1;
|
||||
|
||||
let elapsed_secs = self.last_frame_instant.elapsed().as_secs_f32();
|
||||
if elapsed_secs >= 1.0 {
|
||||
let fps = self.frame_count as f32 / elapsed_secs;
|
||||
trace!("FPS: {:.2}", fps);
|
||||
// trace!("Renderer FPS: {:.2}", fps);
|
||||
self.fps = fps;
|
||||
self.frame_count = 0;
|
||||
self.last_frame_instant = Instant::now();
|
||||
}
|
||||
|
@ -640,8 +692,14 @@ impl<'window> Renderer<'window> {
|
|||
self.bg_color = color;
|
||||
}
|
||||
|
||||
pub fn bg_color(&self) -> wgpu::Color {
|
||||
self.bg_color
|
||||
pub fn bg_color(&self) -> &wgpu::Color {
|
||||
&self.bg_color
|
||||
}
|
||||
pub fn text_color(&self) -> &wgpu::Color {
|
||||
&self.font_state.color
|
||||
}
|
||||
pub fn set_text_color(&mut self, color: wgpu::Color) {
|
||||
self.font_state.color = color;
|
||||
}
|
||||
}
|
||||
fn create_depth_texture(
|
||||
|
@ -670,4 +728,4 @@ fn create_depth_texture(
|
|||
let texture = device.create_texture(&desc);
|
||||
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
(texture, view)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
||||
use ctx::{Renderer, Vertex};
|
||||
use tobj::LoadOptions;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use tobj::{LoadOptions, Model};
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
use wgpu::rwh::HasWindowHandle;
|
||||
use winit::application::ApplicationHandler;
|
||||
|
@ -34,163 +36,51 @@ impl WindowContext<'_> {
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct App<'window> {
|
||||
windows: HashMap<WindowId, WindowContext<'window>>,
|
||||
windows: ahash::AHashMap<WindowId, WindowContext<'window>>,
|
||||
}
|
||||
static CUBE_VERTICES: &[Vertex] = &[
|
||||
Vertex {
|
||||
position: [-0.5, -0.5, 0.5],
|
||||
normal: [0.0, 0.0, 1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, -0.5, 0.5],
|
||||
normal: [0.0, 0.0, 1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, 0.5, 0.5],
|
||||
normal: [0.0, 0.0, 1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, 0.5, 0.5],
|
||||
normal: [0.0, 0.0, 1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, 0.5, 0.5],
|
||||
normal: [0.0, 0.0, 1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, -0.5, 0.5],
|
||||
normal: [0.0, 0.0, 1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, -0.5, -0.5],
|
||||
normal: [0.0, 0.0, -1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, -0.5, -0.5],
|
||||
normal: [0.0, 0.0, -1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, 0.5, -0.5],
|
||||
normal: [0.0, 0.0, -1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, 0.5, -0.5],
|
||||
normal: [0.0, 0.0, -1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, 0.5, -0.5],
|
||||
normal: [0.0, 0.0, -1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, -0.5, -0.5],
|
||||
normal: [0.0, 0.0, -1.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, -0.5, 0.5],
|
||||
normal: [1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, -0.5, -0.5],
|
||||
normal: [1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, 0.5, -0.5],
|
||||
normal: [1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, 0.5, -0.5],
|
||||
normal: [1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, 0.5, 0.5],
|
||||
normal: [1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, -0.5, 0.5],
|
||||
normal: [1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, -0.5, -0.5],
|
||||
normal: [-1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, -0.5, 0.5],
|
||||
normal: [-1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, 0.5, 0.5],
|
||||
normal: [-1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, 0.5, 0.5],
|
||||
normal: [-1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, 0.5, -0.5],
|
||||
normal: [-1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, -0.5, -0.5],
|
||||
normal: [-1.0, 0.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, 0.5, 0.5],
|
||||
normal: [0.0, 1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, 0.5, 0.5],
|
||||
normal: [0.0, 1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, 0.5, -0.5],
|
||||
normal: [0.0, 1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, 0.5, -0.5],
|
||||
normal: [0.0, 1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, 0.5, -0.5],
|
||||
normal: [0.0, 1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, 0.5, 0.5],
|
||||
normal: [0.0, 1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, -0.5, -0.5],
|
||||
normal: [0.0, -1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, -0.5, -0.5],
|
||||
normal: [0.0, -1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, -0.5, 0.5],
|
||||
normal: [0.0, -1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [0.5, -0.5, 0.5],
|
||||
normal: [0.0, -1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, -0.5, 0.5],
|
||||
normal: [0.0, -1.0, 0.0],
|
||||
},
|
||||
Vertex {
|
||||
position: [-0.5, -0.5, -0.5],
|
||||
normal: [0.0, -1.0, 0.0],
|
||||
},
|
||||
];
|
||||
const CUBE_INDICES: &[u32] = &[
|
||||
0, 1, 2, 2, 3, 0,
|
||||
4, 5, 6, 6, 7, 4,
|
||||
8, 9, 10, 10, 11, 8,
|
||||
12, 13, 14, 14, 15, 12,
|
||||
16, 17, 18, 18, 19, 16,
|
||||
20, 21, 22, 22, 23, 20,
|
||||
];
|
||||
|
||||
static CUBE_OBJ: &str = "
|
||||
# Blender 4.2.3 LTS
|
||||
# www.blender.org
|
||||
mtllib cube.mtl
|
||||
o Cube
|
||||
v 1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
vn -1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -1.0000 -0.0000
|
||||
vn 1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 -1.0000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.875000 0.750000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.625000 1.000000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.375000 0.000000
|
||||
vt 0.625000 0.000000
|
||||
vt 0.625000 0.250000
|
||||
vt 0.375000 0.250000
|
||||
vt 0.125000 0.500000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.125000 0.750000
|
||||
s 0
|
||||
usemtl Material
|
||||
f 1/1/1 5/2/1 7/3/1 3/4/1
|
||||
f 4/5/2 3/4/2 7/6/2 8/7/2
|
||||
f 8/8/3 7/9/3 5/10/3 6/11/3
|
||||
f 6/12/4 2/13/4 4/5/4 8/14/4
|
||||
f 2/13/5 1/1/5 3/4/5 4/5/5
|
||||
f 6/11/6 5/10/6 1/1/6 2/13/6
|
||||
";
|
||||
|
||||
impl App<'_> {
|
||||
fn create_main_window(&mut self, event_loop: &ActiveEventLoop) {
|
||||
|
@ -202,9 +92,9 @@ impl App<'_> {
|
|||
match Renderer::new_blocking(window.clone()) {
|
||||
Ok(mut wgpu_ctx) => {
|
||||
let obj = match tobj::load_obj(
|
||||
"test.obj",
|
||||
"Pumpkin.obj",
|
||||
&LoadOptions {
|
||||
triangulate: true,
|
||||
triangulate: true,
|
||||
single_index: true,
|
||||
..Default::default()
|
||||
},
|
||||
|
@ -215,29 +105,10 @@ impl App<'_> {
|
|||
panic!()
|
||||
}
|
||||
};
|
||||
let mesh = &obj.0.get(0).unwrap().mesh;
|
||||
let (combined_vertices, combined_indices) = parse_obj(&obj.0);
|
||||
|
||||
let vertices: Vec<Vertex> = (0..mesh.positions.len() / 3)
|
||||
.map(|i| Vertex {
|
||||
position: [
|
||||
mesh.positions[i * 3],
|
||||
mesh.positions[i * 3 + 1],
|
||||
mesh.positions[i * 3 + 2],
|
||||
],
|
||||
normal: if !mesh.normals.is_empty() {
|
||||
[
|
||||
mesh.normals[i * 3],
|
||||
mesh.normals[i * 3 + 1],
|
||||
mesh.normals[i * 3 + 2],
|
||||
]
|
||||
} else {
|
||||
[0.0; 3]
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
wgpu_ctx.add_model(&combined_vertices, &combined_indices);
|
||||
|
||||
wgpu_ctx.add_model(&vertices, &mesh.indices);
|
||||
// wgpu_ctx.add_model(CUBE_VERTICES,CUBE_INDICES);
|
||||
self.windows.insert(
|
||||
window_id,
|
||||
WindowContext {
|
||||
|
@ -289,12 +160,21 @@ impl App<'_> {
|
|||
fn toggle_background(&mut self, window_id: WindowId) {
|
||||
if let Some(window_context) = self.windows.get_mut(&window_id) {
|
||||
let current_color = window_context.ctx.bg_color();
|
||||
|
||||
let new_color = match current_color {
|
||||
wgpu::Color::WHITE => wgpu::Color::BLACK,
|
||||
wgpu::Color::BLACK => wgpu::Color::WHITE,
|
||||
&wgpu::Color::WHITE => wgpu::Color::BLACK,
|
||||
&wgpu::Color::BLACK => wgpu::Color::WHITE,
|
||||
_ => wgpu::Color::WHITE,
|
||||
};
|
||||
let new_text_color = match window_context.ctx.text_color() {
|
||||
&wgpu::Color::WHITE => wgpu::Color::BLACK,
|
||||
&wgpu::Color::BLACK => wgpu::Color::WHITE,
|
||||
_ => wgpu::Color::WHITE,
|
||||
};
|
||||
|
||||
println!("new text color {new_text_color:#?}");
|
||||
window_context.ctx.set_bg_color(new_color);
|
||||
window_context.ctx.set_text_color(new_text_color);
|
||||
debug!("Toggled background color for window {:?}", window_id);
|
||||
} else {
|
||||
warn!("No window context for toggling background: {:?}", window_id);
|
||||
|
@ -318,7 +198,29 @@ impl App<'_> {
|
|||
let window_id = window.id();
|
||||
match Renderer::new_blocking(window.clone()) {
|
||||
Ok(mut wgpu_ctx) => {
|
||||
wgpu_ctx.add_model(CUBE_VERTICES,CUBE_INDICES);
|
||||
{
|
||||
let mut tmp_path: PathBuf = env::temp_dir();
|
||||
tmp_path.push("cube.obj");
|
||||
if let Err(e) = fs::write(&tmp_path, CUBE_OBJ) {
|
||||
error!("Failed to write cube OBJ to temp: {:?}", e);
|
||||
}
|
||||
|
||||
let load_options = tobj::LoadOptions {
|
||||
triangulate: true,
|
||||
single_index: true,
|
||||
..Default::default()
|
||||
};
|
||||
match tobj::load_obj(tmp_path.to_str().unwrap(), &load_options) {
|
||||
Ok(cube_model) => {
|
||||
let (cube_vertices, cube_indices) =
|
||||
parse_obj(&cube_model.0);
|
||||
wgpu_ctx.add_model(&cube_vertices, &cube_indices);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to load cube OBJ from temp file: {:?}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.windows.insert(
|
||||
window_id,
|
||||
WindowContext {
|
||||
|
@ -375,6 +277,39 @@ impl App<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_obj(obj: &Vec<Model>) -> (Vec<Vertex>, Vec<u32>) {
|
||||
let mut combined_vertices = Vec::new();
|
||||
let mut combined_indices = Vec::new();
|
||||
let mut vertex_offset = 0;
|
||||
|
||||
for object in obj {
|
||||
let mesh: &_ = &object.mesh;
|
||||
let vertices: Vec<Vertex> = (0..mesh.positions.len() / 3)
|
||||
.map(|i| Vertex {
|
||||
position: [
|
||||
mesh.positions[i * 3],
|
||||
mesh.positions[i * 3 + 1],
|
||||
mesh.positions[i * 3 + 2],
|
||||
],
|
||||
normal: if !mesh.normals.is_empty() {
|
||||
[
|
||||
mesh.normals[i * 3],
|
||||
mesh.normals[i * 3 + 1],
|
||||
mesh.normals[i * 3 + 2],
|
||||
]
|
||||
} else {
|
||||
[0.0; 3]
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
combined_vertices.extend(vertices);
|
||||
combined_indices.extend(mesh.indices.iter().map(|&index| index + vertex_offset));
|
||||
vertex_offset += (mesh.positions.len() as u32) / 3;
|
||||
}
|
||||
|
||||
(combined_vertices, combined_indices)
|
||||
}
|
||||
|
||||
impl ApplicationHandler for App<'_> {
|
||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||
if self.windows.is_empty() {
|
||||
|
|
42
engine/src/core/render/shader.wgsl
Normal file
42
engine/src/core/render/shader.wgsl
Normal file
|
@ -0,0 +1,42 @@
|
|||
struct CameraUniform {
|
||||
view: mat4x4<f32>,
|
||||
proj: mat4x4<f32>,
|
||||
};
|
||||
|
||||
struct ModelUniform {
|
||||
model: mat4x4<f32>,
|
||||
};
|
||||
|
||||
@group(0) @binding(0)
|
||||
var<uniform> camera: CameraUniform;
|
||||
|
||||
@group(1) @binding(0)
|
||||
var<uniform> model: ModelUniform;
|
||||
|
||||
struct VertexInput {
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) normal: vec3<f32>,
|
||||
};
|
||||
|
||||
@vertex
|
||||
fn vs_main(input: VertexInput) -> VertexOutput {
|
||||
var output: VertexOutput;
|
||||
let model_pos = model.model * vec4<f32>(input.position, 1.0);
|
||||
output.clip_position = camera.proj * camera.view * model_pos;
|
||||
output.normal = input.normal;
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let ambient: f32 = 0.2;
|
||||
let light_dir = normalize(vec3<f32>(0.5, 1.0, 0.5));
|
||||
let diffuse = clamp(dot(normalize(input.normal), light_dir), 0.0, 1.0);
|
||||
let brightness = ambient + (1.0 - ambient) * diffuse;
|
||||
return vec4<f32>(0.7 * brightness, 0.7 * brightness, 0.9 * brightness, 1.0);
|
||||
}
|
|
@ -5,9 +5,7 @@ use tokio::runtime;
|
|||
#[allow(unused_imports)]
|
||||
use tracing::{debug, error, info, warn};
|
||||
use tracing::{level_filters::LevelFilter, subscriber::set_global_default};
|
||||
use tracing_subscriber::{layer::Filter, util::SubscriberInitExt};
|
||||
use winit::event_loop::EventLoop;
|
||||
pub mod bint;
|
||||
pub mod core;
|
||||
|
||||
fn init_logger() {
|
||||
|
@ -27,7 +25,6 @@ fn init_logger() {
|
|||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
init_logger();
|
||||
// bint::main();
|
||||
if !cfg!(debug_assertions) {
|
||||
info!("{}", "Debug mode disabled".bright_blue());
|
||||
set_panic_hook();
|
||||
|
|
12
flake.lock
generated
12
flake.lock
generated
|
@ -77,11 +77,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1742422364,
|
||||
"narHash": "sha256-mNqIplmEohk5jRkqYqG19GA8MbQ/D4gQSK0Mu4LvfRQ=",
|
||||
"lastModified": 1743095683,
|
||||
"narHash": "sha256-gWd4urRoLRe8GLVC/3rYRae1h+xfQzt09xOfb0PaHSk=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a84ebe20c6bc2ecbcfb000a50776219f48d134cc",
|
||||
"rev": "5e5402ecbcb27af32284d4a62553c019a3a49ea6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -138,11 +138,11 @@
|
|||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1742610648,
|
||||
"narHash": "sha256-9jWi3gw3fEIgEslnFjH/s1I+Iyf1+4t5B1Ed1FOiy8o=",
|
||||
"lastModified": 1743215516,
|
||||
"narHash": "sha256-52qbrkG65U1hyrQWltgHTgH4nm0SJL+9TWv2UDCEPNI=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "c60d41987df3c853e2a842de2c63ded40400979b",
|
||||
"rev": "524463199fdee49338006b049bc376b965a2cfed",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -52,7 +52,9 @@
|
|||
devShells.default = pkgs.mkShell {
|
||||
name = "zenyx";
|
||||
nativeBuildInputs = with pkgs; [
|
||||
rust-bin.stable.latest.default
|
||||
(rust-bin.stable.latest.default.override {
|
||||
extensions = ["rust-src" "cargo" "rustfmt" "clippy"];
|
||||
})
|
||||
pkg-config
|
||||
];
|
||||
buildInputs = buildInputs;
|
||||
|
|
BIN
test.obj
(Stored with Git LFS)
BIN
test.obj
(Stored with Git LFS)
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue