formatting

This commit is contained in:
Chance 2025-03-29 20:20:40 -04:00 committed by BitSyndicate
parent d0d0e7c016
commit 11194e863e
13 changed files with 515 additions and 2689 deletions

223
Cargo.lock generated
View file

@ -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"

View file

@ -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

View file

@ -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}
'';

View file

@ -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"

View file

@ -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}")
}

Binary file not shown.

View file

@ -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)
}
}

View file

@ -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() {

View 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);
}

View file

@ -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
View file

@ -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": {

View file

@ -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;

2066
test.obj

File diff suppressed because it is too large Load diff