basic working polygon renderer

This commit is contained in:
2024-06-15 03:03:48 -04:00
parent 219213ee24
commit aa466a248c
23 changed files with 639 additions and 300 deletions

213
Cargo.lock generated
View File

@@ -321,9 +321,9 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]] [[package]]
name = "block2" name = "block2"
version = "0.5.0" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43ff7d91d3c1d568065b06c899777d1e48dcf76103a672a0adbc238a7f247f1e" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
dependencies = [ dependencies = [
"objc2", "objc2",
] ]
@@ -417,9 +417,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]] [[package]]
name = "cfg_aliases" name = "cfg_aliases"
version = "0.2.0" 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 = "77e53693616d3075149f4ead59bdeecd204ac6b8192d8969757601b74bddf00f" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]] [[package]]
name = "codespan-reporting" name = "codespan-reporting"
@@ -1200,15 +1200,15 @@ dependencies = [
[[package]] [[package]]
name = "objc-sys" name = "objc-sys"
version = "0.3.3" version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da284c198fb9b7b0603f8635185e85fbd5b64ee154b1ed406d489077de2d6d60" checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
[[package]] [[package]]
name = "objc2" name = "objc2"
version = "0.5.1" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4b25e1034d0e636cd84707ccdaa9f81243d399196b8a773946dcffec0401659" checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
dependencies = [ dependencies = [
"objc-sys", "objc-sys",
"objc2-encode", "objc2-encode",
@@ -1216,21 +1216,172 @@ dependencies = [
[[package]] [[package]]
name = "objc2-app-kit" name = "objc2-app-kit"
version = "0.2.0" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb79768a710a9a1798848179edb186d1af7e8a8679f369e4b8d201dd2a034047" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
dependencies = [
"bitflags 2.5.0",
"block2",
"libc",
"objc2",
"objc2-core-data",
"objc2-core-image",
"objc2-foundation",
"objc2-quartz-core",
]
[[package]]
name = "objc2-cloud-kit"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
dependencies = [
"bitflags 2.5.0",
"block2",
"objc2",
"objc2-core-location",
"objc2-foundation",
]
[[package]]
name = "objc2-contacts"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
dependencies = [ dependencies = [
"block2", "block2",
"objc2", "objc2",
"objc2-core-data",
"objc2-foundation", "objc2-foundation",
] ]
[[package]] [[package]]
name = "objc2-core-data" name = "objc2-core-data"
version = "0.2.0" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e092bc42eaf30a08844e6a076938c60751225ec81431ab89f5d1ccd9f958d6c" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
dependencies = [
"bitflags 2.5.0",
"block2",
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-core-image"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
dependencies = [
"block2",
"objc2",
"objc2-foundation",
"objc2-metal",
]
[[package]]
name = "objc2-core-location"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
dependencies = [
"block2",
"objc2",
"objc2-contacts",
"objc2-foundation",
]
[[package]]
name = "objc2-encode"
version = "4.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8"
[[package]]
name = "objc2-foundation"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.5.0",
"block2",
"dispatch",
"libc",
"objc2",
]
[[package]]
name = "objc2-link-presentation"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
dependencies = [
"block2",
"objc2",
"objc2-app-kit",
"objc2-foundation",
]
[[package]]
name = "objc2-metal"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
dependencies = [
"bitflags 2.5.0",
"block2",
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-quartz-core"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
dependencies = [
"bitflags 2.5.0",
"block2",
"objc2",
"objc2-foundation",
"objc2-metal",
]
[[package]]
name = "objc2-symbols"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc"
dependencies = [
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-ui-kit"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
dependencies = [
"bitflags 2.5.0",
"block2",
"objc2",
"objc2-cloud-kit",
"objc2-core-data",
"objc2-core-image",
"objc2-core-location",
"objc2-foundation",
"objc2-link-presentation",
"objc2-quartz-core",
"objc2-symbols",
"objc2-uniform-type-identifiers",
"objc2-user-notifications",
]
[[package]]
name = "objc2-uniform-type-identifiers"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
dependencies = [ dependencies = [
"block2", "block2",
"objc2", "objc2",
@@ -1238,20 +1389,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "objc2-encode" name = "objc2-user-notifications"
version = "4.0.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88658da63e4cc2c8adb1262902cd6af51094df0488b760d6fd27194269c0950a" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
[[package]]
name = "objc2-foundation"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfaefe14254871ea16c7d88968c0ff14ba554712a20d76421eec52f0a7fb8904"
dependencies = [ dependencies = [
"bitflags 2.5.0",
"block2", "block2",
"dispatch",
"objc2", "objc2",
"objc2-core-location",
"objc2-foundation",
] ]
[[package]] [[package]]
@@ -2123,9 +2270,9 @@ dependencies = [
[[package]] [[package]]
name = "wgpu" name = "wgpu"
version = "0.20.0" version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32ff1bfee408e1028e2e3acbf6d32d98b08a5a059ccbf5f33305534453ba5d3e" checksum = "90e37c7b9921b75dfd26dd973fdcbce36f13dfa6e2dc82aece584e0ed48c355c"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"cfg-if", "cfg-if",
@@ -2149,9 +2296,9 @@ dependencies = [
[[package]] [[package]]
name = "wgpu-core" name = "wgpu-core"
version = "0.20.0" version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac6a86eaa5e763e59c73cf9e97d55fffd4dfda69fd8bda19589fcf851ddfef1f" checksum = "d59e0d5fc509601c69e4e1fa06c1eb3c4c9f12956a5e30c79b61ef1c1be7daf0"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"bit-vec", "bit-vec",
@@ -2176,9 +2323,9 @@ dependencies = [
[[package]] [[package]]
name = "wgpu-hal" name = "wgpu-hal"
version = "0.20.0" version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d71c8ae05170583049b65ee562fd839fdc0b3e9ddb84f4e40c9d5f8ea0d4c8c" checksum = "6aa24c3889f885a3fb9133b454c8418bfcfaadcfe4ed3be96ac80e76703b863b"
dependencies = [ dependencies = [
"android_system_properties", "android_system_properties",
"arrayvec", "arrayvec",
@@ -2494,17 +2641,18 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]] [[package]]
name = "winit" name = "winit"
version = "0.30.0" version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea9e6d5d66cbf702e0dd820302144f51b69a95acdc495dd98ca280ff206562b1" checksum = "763759577d7e92f618ecaca2f5fe415512cae924cfc9460d1c48e1c616c716aa"
dependencies = [ dependencies = [
"ahash", "ahash",
"android-activity", "android-activity",
"atomic-waker", "atomic-waker",
"bitflags 2.5.0", "bitflags 2.5.0",
"block2",
"bytemuck", "bytemuck",
"calloop", "calloop",
"cfg_aliases 0.2.0", "cfg_aliases 0.2.1",
"concurrent-queue", "concurrent-queue",
"core-foundation", "core-foundation",
"core-graphics", "core-graphics",
@@ -2517,6 +2665,7 @@ dependencies = [
"objc2", "objc2",
"objc2-app-kit", "objc2-app-kit",
"objc2-foundation", "objc2-foundation",
"objc2-ui-kit",
"orbclient", "orbclient",
"percent-encoding", "percent-encoding",
"pin-project", "pin-project",

View File

@@ -16,7 +16,7 @@ pollster = "0.3"
rand = "0.8.5" rand = "0.8.5"
simba = "0.8.1" simba = "0.8.1"
smaa = "0.14.0" smaa = "0.14.0"
wgpu = "0.20" wgpu = "0.20.1"
bevy_ecs = "0.13.2" bevy_ecs = "0.13.2"
bevy_derive = "0.13.2" bevy_derive = "0.13.2"
winit = {version="0.30", features=["serde"]} winit = {version="0.30.1", features=["serde"]}

View File

@@ -22,7 +22,11 @@ use crate::{
}; };
use self::{input::Input, render::Renderer, ClientState}; use self::{input::Input, render::Renderer, ClientState};
use std::{collections::HashMap, sync::Arc, time::{Duration, Instant}}; use std::{
collections::HashMap,
sync::Arc,
time::{Duration, Instant},
};
use winit::{ use winit::{
event::WindowEvent, event::WindowEvent,
window::{Window, WindowAttributes}, window::{Window, WindowAttributes},
@@ -44,6 +48,7 @@ pub struct Client<'a> {
systems: ClientSystems, systems: ClientSystems,
target: Instant, target: Instant,
frame_time: Duration, frame_time: Duration,
the_thing: bool,
} }
pub struct ClientSystems { pub struct ClientSystems {
@@ -86,6 +91,7 @@ impl Client<'_> {
server_id_map: HashMap::new(), server_id_map: HashMap::new(),
target: Instant::now(), target: Instant::now(),
frame_time: FRAME_TIME, frame_time: FRAME_TIME,
the_thing: false,
} }
} }
@@ -106,6 +112,13 @@ impl Client<'_> {
.expect("WHAT"); .expect("WHAT");
self.world.clear_trackers(); self.world.clear_trackers();
if self.state.camera.pos.y < -10.0 {
self.the_thing = !self.the_thing;
if self.the_thing == true {
let thing = include_bytes!("../../../../videos/meme/rab_falls_and_dies.mp4");
}
}
if now >= self.target { if now >= self.target {
self.target += self.frame_time; self.target += self.frame_time;
let mut commands = std::mem::take(&mut self.render_commands); let mut commands = std::mem::take(&mut self.render_commands);

View File

@@ -3,6 +3,7 @@ use crate::client::camera::Camera;
use super::{voxel::VoxelColor, Renderer}; use super::{voxel::VoxelColor, Renderer};
use bevy_ecs::entity::Entity; use bevy_ecs::entity::Entity;
use nalgebra::{Rotation3, Vector3}; use nalgebra::{Rotation3, Vector3};
use ndarray::Array3;
use std::sync::Arc; use std::sync::Arc;
use winit::window::Window; use winit::window::Window;
@@ -19,7 +20,7 @@ pub struct CreateVoxelGrid {
pub pos: Vector3<f32>, pub pos: Vector3<f32>,
pub orientation: Rotation3<f32>, pub orientation: Rotation3<f32>,
pub dimensions: Vector3<usize>, pub dimensions: Vector3<usize>,
pub grid: Vec<VoxelColor>, pub grid: Array3<VoxelColor>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@@ -1,14 +1,16 @@
mod command; mod command;
mod util; mod util;
pub mod voxel; pub mod voxel;
pub mod voxel_poly;
pub use command::*; pub use command::*;
use util::Texture;
use super::camera::Camera; use super::camera::Camera;
use crate::client::rsc::CLEAR_COLOR; use crate::client::rsc::CLEAR_COLOR;
use nalgebra::Vector2; use nalgebra::Vector2;
use smaa::{SmaaMode, SmaaTarget}; use smaa::{SmaaMode, SmaaTarget};
use voxel::VoxelPipeline; use voxel_poly::VoxelPipeline;
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
pub struct Renderer<'a> { pub struct Renderer<'a> {
@@ -22,6 +24,7 @@ pub struct Renderer<'a> {
voxel_pipeline: VoxelPipeline, voxel_pipeline: VoxelPipeline,
smaa_target: SmaaTarget, smaa_target: SmaaTarget,
camera: Camera, camera: Camera,
depth_texture: Texture,
} }
impl<'a> Renderer<'a> { impl<'a> Renderer<'a> {
@@ -67,7 +70,7 @@ impl<'a> Renderer<'a> {
format: surface_format, format: surface_format,
width: size.width, width: size.width,
height: size.height, height: size.height,
present_mode: surface_caps.present_modes[0], present_mode: wgpu::PresentMode::AutoVsync,
alpha_mode: surface_caps.alpha_modes[0], alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![], view_formats: vec![],
desired_maximum_frame_latency: 2, desired_maximum_frame_latency: 2,
@@ -87,10 +90,12 @@ impl<'a> Renderer<'a> {
SmaaMode::Smaa1X, SmaaMode::Smaa1X,
); );
let depth_texture = Texture::create_depth_texture(&device, &config, "depth_texture");
Self { Self {
camera: Camera::default(), camera: Camera::default(),
size: Vector2::new(size.width, size.height), size: Vector2::new(size.width, size.height),
voxel_pipeline: VoxelPipeline::new(&device, &config.format), voxel_pipeline: VoxelPipeline::new(&device, &config),
staging_belt, staging_belt,
surface, surface,
encoder: Self::create_encoder(&device), encoder: Self::create_encoder(&device),
@@ -98,6 +103,7 @@ impl<'a> Renderer<'a> {
config, config,
queue, queue,
smaa_target, smaa_target,
depth_texture,
} }
} }
@@ -127,7 +133,14 @@ impl<'a> Renderer<'a> {
store: wgpu::StoreOp::Store, store: wgpu::StoreOp::Store,
}, },
})], })],
depth_stencil_attachment: None, depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
view: &self.depth_texture.view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None, timestamp_writes: None,
occlusion_query_set: None, occlusion_query_set: None,
}); });
@@ -149,6 +162,8 @@ impl<'a> Renderer<'a> {
self.smaa_target self.smaa_target
.resize(&self.device, size.width, size.height); .resize(&self.device, size.width, size.height);
self.depth_texture =
Texture::create_depth_texture(&self.device, &self.config, "depth_texture");
self.voxel_pipeline.update_view( self.voxel_pipeline.update_view(
&self.device, &self.device,
&mut self.encoder, &mut self.encoder,

View File

@@ -5,7 +5,7 @@ use super::buf::{ArrBuf, ArrBufUpdate, BufMove};
pub struct Instances<T: bytemuck::Pod> { pub struct Instances<T: bytemuck::Pod> {
buf: ArrBuf<T>, buf: ArrBuf<T>,
location: u32, location: u32,
attrs: [VertexAttribute; 1], attrs: Vec<VertexAttribute>,
} }
impl<T: bytemuck::Pod> Instances<T> { impl<T: bytemuck::Pod> Instances<T> {
@@ -24,7 +24,7 @@ impl<T: bytemuck::Pod> Instances<T> {
device: &wgpu::Device, device: &wgpu::Device,
label: &str, label: &str,
location: u32, location: u32,
format: wgpu::VertexFormat, attrs: &[wgpu::VertexAttribute],
) -> Self { ) -> Self {
Self { Self {
buf: ArrBuf::init( buf: ArrBuf::init(
@@ -33,11 +33,26 @@ impl<T: bytemuck::Pod> Instances<T> {
BufferUsages::VERTEX, BufferUsages::VERTEX,
), ),
location, location,
attrs: [wgpu::VertexAttribute { attrs: attrs.to_vec(),
format, }
offset: 0, }
shader_location: location,
}], pub fn init_with(
device: &wgpu::Device,
label: &str,
location: u32,
attrs: &[wgpu::VertexAttribute],
data: &[T],
) -> Self {
Self {
buf: ArrBuf::init_with(
device,
&(label.to_owned() + " Instance"),
BufferUsages::VERTEX,
data,
),
location,
attrs: attrs.to_vec(),
} }
} }
@@ -56,4 +71,8 @@ impl<T: bytemuck::Pod> Instances<T> {
pub fn mov(&mut self, mov: BufMove) { pub fn mov(&mut self, mov: BufMove) {
self.buf.mov(mov); self.buf.mov(mov);
} }
pub fn len(&self) -> usize {
self.buf.len()
}
} }

View File

@@ -2,8 +2,12 @@ mod buf;
mod instance; mod instance;
mod storage; mod storage;
mod uniform; mod uniform;
mod vertex;
mod texture;
pub use buf::*; pub use buf::*;
pub use instance::*; pub use instance::*;
pub use storage::*; pub use storage::*;
pub use uniform::*; pub use uniform::*;
pub use vertex::*;
pub use texture::*;

View File

@@ -1,12 +1,12 @@
use super::buf::{ArrBuf, ArrBufUpdate, BufMove}; use super::buf::{ArrBuf, ArrBufUpdate, BufMove};
use wgpu::BufferUsages; use wgpu::BufferUsages;
pub struct Storage<T: bytemuck::Pod + PartialEq> { pub struct Storage<T: bytemuck::Pod> {
binding: u32, binding: u32,
buf: ArrBuf<T>, buf: ArrBuf<T>,
} }
impl<T: PartialEq + bytemuck::Pod> Storage<T> { impl<T: bytemuck::Pod> Storage<T> {
pub fn init(device: &wgpu::Device, label: &str, binding: u32) -> Self { pub fn init(device: &wgpu::Device, label: &str, binding: u32) -> Self {
Self { Self {
buf: ArrBuf::init( buf: ArrBuf::init(
@@ -30,7 +30,7 @@ impl<T: PartialEq + bytemuck::Pod> Storage<T> {
} }
} }
impl<T: PartialEq + bytemuck::Pod> Storage<T> { impl<T: bytemuck::Pod> Storage<T> {
pub fn bind_group_layout_entry(&self) -> wgpu::BindGroupLayoutEntry { pub fn bind_group_layout_entry(&self) -> wgpu::BindGroupLayoutEntry {
wgpu::BindGroupLayoutEntry { wgpu::BindGroupLayoutEntry {
binding: self.binding, binding: self.binding,

View File

@@ -0,0 +1,55 @@
pub struct Texture {
pub texture: wgpu::Texture,
pub view: wgpu::TextureView,
pub sampler: wgpu::Sampler,
}
impl Texture {
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; // 1.
pub fn create_depth_texture(
device: &wgpu::Device,
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {
let size = wgpu::Extent3d {
// 2.
width: config.width,
height: config.height,
depth_or_array_layers: 1,
};
let desc = wgpu::TextureDescriptor {
label: Some(label),
size,
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: Self::DEPTH_FORMAT,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT // 3.
| wgpu::TextureUsages::TEXTURE_BINDING,
view_formats: &[],
};
let texture = device.create_texture(&desc);
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
// 4.
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: Some(wgpu::CompareFunction::LessEqual), // 5.
lod_min_clamp: 0.0,
lod_max_clamp: 100.0,
..Default::default()
});
Self {
texture,
view,
sampler,
}
}
}

View File

@@ -23,6 +23,17 @@ impl<T: Default + bytemuck::Pod> Uniform<T> {
} }
impl<T: PartialEq + bytemuck::Pod> Uniform<T> { impl<T: PartialEq + bytemuck::Pod> Uniform<T> {
pub fn init_with(device: &wgpu::Device, name: &str, binding: u32, data: &[T]) -> Self {
Self {
buffer: device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some(&(name.to_owned() + " Uniform Buf")),
contents: bytemuck::cast_slice(data),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
}),
binding,
ty: PhantomData,
}
}
pub fn bind_group_layout_entry(&self) -> wgpu::BindGroupLayoutEntry { pub fn bind_group_layout_entry(&self) -> wgpu::BindGroupLayoutEntry {
wgpu::BindGroupLayoutEntry { wgpu::BindGroupLayoutEntry {
binding: self.binding, binding: self.binding,

View File

@@ -0,0 +1,86 @@
use wgpu::{BufferUsages, VertexAttribute};
use super::buf::{ArrBuf, ArrBufUpdate, BufMove};
pub struct Vertices<T: bytemuck::Pod> {
buf: ArrBuf<T>,
location: u32,
attrs: [VertexAttribute; 1],
}
impl<T: bytemuck::Pod> Vertices<T> {
pub fn update(
&mut self,
device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder,
belt: &mut wgpu::util::StagingBelt,
size: usize,
updates: &[ArrBufUpdate<T>],
) -> bool {
self.buf.update(device, encoder, belt, size, updates)
}
pub fn init(
device: &wgpu::Device,
label: &str,
location: u32,
format: wgpu::VertexFormat,
) -> Self {
Self {
buf: ArrBuf::init(
device,
&(label.to_owned() + " Instance"),
BufferUsages::VERTEX,
),
location,
attrs: [wgpu::VertexAttribute {
format,
offset: 0,
shader_location: location,
}],
}
}
pub fn init_with(
device: &wgpu::Device,
label: &str,
location: u32,
format: wgpu::VertexFormat,
data: &[T],
) -> Self {
Self {
buf: ArrBuf::init_with(
device,
&(label.to_owned() + " Instance"),
BufferUsages::VERTEX,
data,
),
location,
attrs: [wgpu::VertexAttribute {
format,
offset: 0,
shader_location: location,
}],
}
}
pub fn set_in<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) {
render_pass.set_vertex_buffer(self.location, self.buf.buffer().slice(..));
}
pub fn desc(&self) -> wgpu::VertexBufferLayout {
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<T>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &self.attrs,
}
}
pub fn mov(&mut self, mov: BufMove) {
self.buf.mov(mov);
}
pub fn len(&self) -> usize {
self.buf.len()
}
}

View File

@@ -150,7 +150,7 @@ impl VoxelPipeline {
let updates = [ArrBufUpdate { let updates = [ArrBufUpdate {
offset, offset,
data: &grid, data: &grid.as_slice().unwrap(),
}]; }];
let size = offset + grid.len(); let size = offset + grid.len();
self.voxels.update(device, encoder, belt, size, &updates); self.voxels.update(device, encoder, belt, size, &updates);
@@ -226,7 +226,6 @@ impl VoxelPipeline {
width: size.x, width: size.x,
height: size.y, height: size.y,
zoom: camera.scale, zoom: camera.scale,
padding: 0,
transform, transform,
}; };
self.view.update(device, encoder, belt, data) self.view.update(device, encoder, belt, data)

View File

@@ -6,15 +6,13 @@ struct GlobalLight {
struct VertexOutput { struct VertexOutput {
@builtin(position) clip_position: vec4<f32>, @builtin(position) clip_position: vec4<f32>,
@location(0) tex_coords: vec2<f32>,
}; };
struct View { struct View {
transform: mat4x4<f32>,
width: u32, width: u32,
height: u32, height: u32,
zoom: f32, zoom: f32,
padding: u32,
transform: mat4x4<f32>,
}; };
struct VoxelGroup { struct VoxelGroup {

View File

@@ -3,11 +3,10 @@ use nalgebra::Transform3;
#[repr(C, align(16))] #[repr(C, align(16))]
#[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)] #[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)]
pub struct View { pub struct View {
pub transform: Transform3<f32>,
pub width: u32, pub width: u32,
pub height: u32, pub height: u32,
pub zoom: f32, pub zoom: f32,
pub padding: u32,
pub transform: Transform3<f32>,
} }
unsafe impl bytemuck::Pod for View {} unsafe impl bytemuck::Pod for View {}
@@ -18,7 +17,6 @@ impl Default for View {
width: 1, width: 1,
height: 1, height: 1,
zoom: 1.0, zoom: 1.0,
padding: 0,
transform: Transform3::identity(), transform: Transform3::identity(),
} }
} }

View File

@@ -0,0 +1,11 @@
use nalgebra::{Transform3, Vector3};
#[repr(C, align(16))]
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Zeroable, Default)]
pub struct FaceGroup {
pub transform: Transform3<f32>,
pub dimensions: Vector3<u32>,
pub face: u32,
}
unsafe impl bytemuck::Pod for FaceGroup {}

View File

@@ -0,0 +1,12 @@
use bytemuck::Zeroable;
use crate::client::render::voxel::VoxelColor;
#[repr(C)]
#[derive(Copy, Clone, Debug, Zeroable)]
pub struct VoxelFace {
pub index: u32,
pub color: VoxelColor,
}
unsafe impl bytemuck::Pod for VoxelFace {}

View File

@@ -1,26 +1,47 @@
use super::uniform::Uniform;
use nalgebra::{Projective3, Translation3, Rotation3};
mod view;
mod color; mod color;
mod vertex; mod group;
mod instance;
mod square; mod square;
mod view;
use core::panic;
use group::FaceGroup;
use instance::VoxelFace;
use nalgebra::{Perspective3, Transform3, Translation3, Vector2, Vector3};
use view::View;
use wgpu::{SurfaceConfiguration, VertexAttribute, VertexFormat};
use crate::client::camera::Camera;
use super::{
util::{Instances, Texture, Uniform},
CreateVoxelGrid, UpdateGridTransform,
};
pub struct VoxelPipeline { pub struct VoxelPipeline {
pipeline: wgpu::RenderPipeline, pipeline: wgpu::RenderPipeline,
view: Uniform<View>, view: Uniform<View>,
bind_group_layout: wgpu::BindGroupLayout, bind_group_layout: wgpu::BindGroupLayout,
bind_group: wgpu::BindGroup, bind_groups: Vec<wgpu::BindGroup>,
voxel_groups: Storage<VoxelGroup>, vertices: Vec<Instances<VoxelFace>>,
voxels: Storage<VoxelColor>,
arst: bool,
} }
const WIDTH: u32 = 300; const INSTANCE_ATTRS: [wgpu::VertexAttribute; 2] = [
const HEIGHT: u32 = 300; VertexAttribute {
format: VertexFormat::Uint32,
offset: 0,
shader_location: 0,
},
VertexAttribute {
format: VertexFormat::Uint32,
offset: 4,
shader_location: 1,
},
];
impl VoxelPipeline { impl VoxelPipeline {
pub fn new(device: &wgpu::Device, format: &wgpu::TextureFormat) -> Self { pub fn new(device: &wgpu::Device, config: &SurfaceConfiguration) -> Self {
// shaders // shaders
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Tile Shader"), label: Some("Tile Shader"),
@@ -28,29 +49,19 @@ impl VoxelPipeline {
}); });
let view = Uniform::<View>::init(device, "view", 0); let view = Uniform::<View>::init(device, "view", 0);
let voxels = Storage::init(device, "voxels", 1); let example_faces =
let voxel_groups = Storage::init(device, "voxel groups", 2); Instances::<VoxelFace>::init(device, "voxel groups", 0, &INSTANCE_ATTRS);
let example_group = Uniform::<FaceGroup>::init(device, "voxel group", 1);
// bind groups // bind groups
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[ entries: &[
view.bind_group_layout_entry(), view.bind_group_layout_entry(),
voxels.bind_group_layout_entry(), example_group.bind_group_layout_entry(),
voxel_groups.bind_group_layout_entry(),
], ],
label: Some("tile_bind_group_layout"), label: Some("tile_bind_group_layout"),
}); });
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_group_layout,
entries: &[
view.bind_group_entry(),
voxels.bind_group_entry(),
voxel_groups.bind_group_entry(),
],
label: Some("tile_bind_group"),
});
// pipeline // pipeline
let render_pipeline_layout = let render_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
@@ -65,14 +76,14 @@ impl VoxelPipeline {
vertex: wgpu::VertexState { vertex: wgpu::VertexState {
module: &shader, module: &shader,
entry_point: "vs_main", entry_point: "vs_main",
buffers: &[], buffers: &[example_faces.desc()],
compilation_options: wgpu::PipelineCompilationOptions::default(), compilation_options: wgpu::PipelineCompilationOptions::default(),
}, },
fragment: Some(wgpu::FragmentState { fragment: Some(wgpu::FragmentState {
module: &shader, module: &shader,
entry_point: "fs_main", entry_point: "fs_main",
targets: &[Some(wgpu::ColorTargetState { targets: &[Some(wgpu::ColorTargetState {
format: *format, format: config.format,
blend: Some(wgpu::BlendState::REPLACE), blend: Some(wgpu::BlendState::REPLACE),
write_mask: wgpu::ColorWrites::ALL, write_mask: wgpu::ColorWrites::ALL,
})], })],
@@ -82,12 +93,18 @@ impl VoxelPipeline {
topology: wgpu::PrimitiveTopology::TriangleStrip, topology: wgpu::PrimitiveTopology::TriangleStrip,
strip_index_format: None, strip_index_format: None,
front_face: wgpu::FrontFace::Ccw, front_face: wgpu::FrontFace::Ccw,
cull_mode: None, cull_mode: Some(wgpu::Face::Back),
polygon_mode: wgpu::PolygonMode::Fill, polygon_mode: wgpu::PolygonMode::Fill,
unclipped_depth: false, unclipped_depth: false,
conservative: false, conservative: false,
}, },
depth_stencil: None, depth_stencil: Some(wgpu::DepthStencilState {
format: Texture::DEPTH_FORMAT,
depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Less,
stencil: wgpu::StencilState::default(),
bias: wgpu::DepthBiasState::default(),
}),
multisample: wgpu::MultisampleState { multisample: wgpu::MultisampleState {
count: 1, count: 1,
mask: !0, mask: !0,
@@ -99,165 +116,123 @@ impl VoxelPipeline {
Self { Self {
pipeline: render_pipeline, pipeline: render_pipeline,
view, view,
bind_group,
bind_group_layout, bind_group_layout,
voxels, bind_groups: Vec::new(),
voxel_groups, vertices: Vec::new(),
arst: false,
} }
} }
pub fn update( pub fn update_view(
&mut self, &mut self,
device: &wgpu::Device, device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder, encoder: &mut wgpu::CommandEncoder,
belt: &mut wgpu::util::StagingBelt, belt: &mut wgpu::util::StagingBelt,
update_data: &RenderUpdateData, size: Vector2<u32>,
camera: &Camera,
) { ) {
if !self.arst { let mut transform = (Translation3::from(camera.pos) * camera.orientation)
let lx = 15; .inverse()
let ly = 10; .to_matrix();
let lz = 10; transform = transform.append_nonuniform_scaling(&Vector3::new(1.0, 1.0, -1.0));
let mut data = vec![VoxelColor::none(); lx * ly * lz]; let projection = Perspective3::new(
for x in 0..lx { size.x as f32 / size.y as f32,
for y in 0..ly { std::f32::consts::PI / 2.0,
data[x + y * lx] = VoxelColor { 0.1,
r: (x as f32 / lx as f32 * 255.0) as u8, 1000.0,
g: (y as f32 / ly as f32 * 255.0) as u8,
b: 0,
a: 100,
};
}
}
for x in 0..lx {
for y in 0..ly {
data[x + y * lx + 3 * lx * ly] = VoxelColor {
r: (x as f32 / lx as f32 * 255.0) as u8,
g: (y as f32 / ly as f32 * 255.0) as u8,
b: 100,
a: 255,
};
}
}
for i in 0..lx.min(ly.min(lz)) {
data[i + i * lx + i * lx * ly] = VoxelColor::white();
}
let lx2 = 1000;
let ly2 = 2;
let lz2 = 1000;
let offset2 = data.len();
let mut data2 = vec![VoxelColor::none(); lx2 * ly2 * lz2];
let paint = VoxelColor {
r: 255,
g: 0,
b: 255,
a: 255,
};
for x in 0..lx2 {
data2[x + (ly2 - 1) * lx2] = paint;
data2[x + (ly2 - 1) * lx2 + (lz2 - 1) * lx2 * ly2] = paint;
}
for z in 0..lz2 {
data2[(ly2 - 1) * lx2 + z * lx2 * ly2] = paint;
data2[lx2 - 1 + (ly2 - 1) * lx2 + z * lx2 * ly2] = paint;
}
for x in 0..lx2 {
for z in 0..lz2 {
data2[x + z * lx2 * ly2] = rand::random();
}
}
data.append(&mut data2);
let lx3 = 3;
let ly3 = 3;
let lz3 = 3;
let offset3 = data.len();
data.append(&mut vec![
VoxelColor {
r: 255,
g: 0,
b: 255,
a: 255,
};
lx3 * ly3 * lz3
]);
self.voxels.update(
device,
encoder,
belt,
data.len(),
&[ArrBufUpdate { offset: 0, data }],
); );
let proj = Projective3::identity() transform = projection.as_matrix() * transform;
* Translation3::new(0.0, 0.0, 20.0) let data = View {
* Rotation3::from_axis_angle(&Vector3::y_axis(), 0.5) width: size.x,
* Translation3::new(-(lx as f32 / 2.0), -(ly as f32 / 2.0), -(lz as f32 / 2.0)); height: size.y,
let group = VoxelGroup { zoom: camera.scale,
transform: proj, transform,
transform_inv: proj.inverse(),
dimensions: Vector3::new(lx as u32, ly as u32, lz as u32),
offset: 0,
}; };
let proj2 = Projective3::identity() self.view.update(device, encoder, belt, data)
* Translation3::new(0.0, -2.1, 20.0)
* Translation3::new(
-(lx2 as f32 / 2.0),
-(ly2 as f32 / 2.0),
-(lz2 as f32 / 2.0),
);
let group2 = VoxelGroup {
transform: proj2,
transform_inv: proj2.inverse(),
dimensions: Vector3::new(lx2 as u32, ly2 as u32, lz2 as u32),
offset: offset2 as u32,
};
let proj3 = Projective3::identity()
* Translation3::new(0.0, 0.0, 16.5)
* Rotation3::from_axis_angle(&Vector3::y_axis(), std::f32::consts::PI / 4.0)
* Rotation3::from_axis_angle(
&UnitVector3::new_normalize(Vector3::new(1.0, 0.0, 1.0)),
std::f32::consts::PI / 4.0,
)
* Translation3::new(
-(lx3 as f32 / 2.0),
-(ly3 as f32 / 2.0),
-(lz3 as f32 / 2.0),
);
let group3 = VoxelGroup {
transform: proj3,
transform_inv: proj3.inverse(),
dimensions: Vector3::new(lx3 as u32, ly3 as u32, lz3 as u32),
offset: offset3 as u32,
};
let groups = vec![group, group2, group3];
self.voxel_groups.update(
device,
encoder,
belt,
groups.len(),
&[ArrBufUpdate {
offset: 0,
data: groups,
}],
);
self.bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &self.bind_group_layout,
entries: &[
self.view.bind_group_entry(),
self.voxels.bind_group_entry(),
self.voxel_groups.bind_group_entry(),
],
label: Some("tile_bind_group"),
});
self.arst = true;
}
self.view.update(device, encoder, belt, update_data);
} }
pub fn draw<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) { pub fn draw<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) {
render_pass.set_pipeline(&self.pipeline); render_pass.set_pipeline(&self.pipeline);
render_pass.set_bind_group(0, &self.bind_group, &[]); for i in 0..self.bind_groups.len() {
render_pass.draw(0..4, 0..1); render_pass.set_bind_group(0, &self.bind_groups[i], &[]);
let vertices = &self.vertices[i];
vertices.set_in(render_pass);
render_pass.draw(0..4, 0..vertices.len() as u32);
}
}
pub fn add_group(
&mut self,
device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder,
belt: &mut wgpu::util::StagingBelt,
CreateVoxelGrid {
id,
pos,
orientation,
dimensions,
grid,
}: CreateVoxelGrid,
) {
let proj = Transform3::identity()
* Translation3::from(pos)
* orientation
* Translation3::from(-dimensions.cast() / 2.0);
for face in 0..6 {
let group = FaceGroup {
dimensions: dimensions.cast(),
transform: proj,
face,
};
let uniform = Uniform::init_with(device, "voxel group", 1, &[group]);
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &self.bind_group_layout,
entries: &[self.view.bind_group_entry(), uniform.bind_group_entry()],
label: Some("voxel bind group"),
});
self.bind_groups.push(bind_group);
let mut data = Vec::new();
let n_offset = match face % 3 {
0 => 1,
1 => dimensions.z * dimensions.y,
2 => dimensions.z,
_ => 0,
} as i32
* ((face as i32 / 3) * 2 - 1);
let face_dir = (face as i32 / 3) * 2 - 1;
for (i, ((x, y, z), color)) in grid.indexed_iter().enumerate() {
let neighbor = match face {
0 => if z > 0 {Some((x, y, z - 1))} else {None},
2 => if y > 0 {Some((x, y - 1, z))} else {None},
1 => if x > 0 {Some((x - 1, y, z))} else {None},
3 => if z < dimensions.z - 1 {Some((x, y, z + 1))} else {None},
5 => if y < dimensions.y - 1 {Some((x, y + 1, z))} else {None},
4 => if x < dimensions.x - 1 {Some((x + 1, y, z))} else {None},
_ => panic!("what"),
}.map(|p| grid.get(p).unwrap());
if color.a > 0 && !neighbor.is_some_and(|c| c.a == color.a) {
data.push(VoxelFace {
index: i as u32,
color: *color,
});
}
}
self.vertices.push(Instances::init_with(
device,
"vvvvv",
0,
&INSTANCE_ATTRS,
&data,
));
}
}
pub fn update_transform(
&mut self,
device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder,
staging_belt: &mut wgpu::util::StagingBelt,
update: UpdateGridTransform,
) {
} }
} }

View File

@@ -1,10 +1,20 @@
// Vertex shader // Vertex shader
struct InstanceInput {
@location(0) index: u32,
@location(1) color: u32,
};
struct VertexOutput { struct VertexOutput {
@builtin(position) clip_position: vec4<f32>, @builtin(position) clip_position: vec4<f32>,
@location(0) tex_coords: vec2<f32>, @location(0) color: vec4<f32>,
}; };
struct VoxelFace {
index: u32,
color: u32,
}
struct View { struct View {
transform: mat4x4<f32>, transform: mat4x4<f32>,
width: u32, width: u32,
@@ -14,31 +24,51 @@ struct View {
struct VoxelGroup { struct VoxelGroup {
transform: mat4x4<f32>, transform: mat4x4<f32>,
transform_inv: mat4x4<f32>,
dimensions: vec3<u32>, dimensions: vec3<u32>,
offset: u32, face: u32,
}; };
@group(0) @binding(0) @group(0) @binding(0)
var<uniform> view: View; var<uniform> view: View;
@group(0) @binding(1) @group(0) @binding(1)
var<storage, read> voxels: array<u32>; var<uniform> group: VoxelGroup;
@group(0) @binding(2)
var<storage, read> voxel_groups: array<VoxelGroup>; const DIRECTIONS = array(
vec3<f32>(1.0, 1.0, 0.0),
vec3<f32>(0.0, 1.0, 1.0),
vec3<f32>(1.0, 0.0, 1.0),
);
@vertex @vertex
fn vs_main( fn vs_main(
@builtin(vertex_index) vi: u32, @builtin(vertex_index) vi: u32,
@builtin(instance_index) ii: u32, in: InstanceInput
) -> VertexOutput { ) -> VertexOutput {
var out: VertexOutput; var out: VertexOutput;
var pos = vec2<f32>( let invert = select(0.0, 1.0, group.face / 3 == 1);
f32(vi % 2u) * 2.0 - 1.0, let invert_mult = 1.0 - invert * 2.0;
f32(vi / 2u) * 2.0 - 1.0, var square_pos = vec2<f32>(
) ; f32(vi % 2u),
out.clip_position = vec4<f32>(pos.x, pos.y, 0.0, 1.0); invert + invert_mult * f32(vi / 2u),
out.tex_coords = pos; );
var cube_pos = vec3<f32>(invert);
square_pos *= invert_mult;
cube_pos[(group.face) % 3] += square_pos.x;
cube_pos[(group.face + 1) % 3] += square_pos.y;
var pos = vec4<f32>(
cube_pos,
1.0,
);
pos += vec4<f32>(
f32(in.index / (group.dimensions.z * group.dimensions.y)),
f32((in.index / group.dimensions.z) % group.dimensions.y),
f32(in.index % group.dimensions.z),
0.0,
);
pos = view.transform * group.transform * pos;
out.clip_position = pos;
out.color = unpack4x8unorm(in.color);
return out; return out;
} }
@@ -48,22 +78,5 @@ fn vs_main(
fn fs_main( fn fs_main(
in: VertexOutput, in: VertexOutput,
) -> @location(0) vec4<f32> { ) -> @location(0) vec4<f32> {
// get position of the pixel; eye at origin, pixel on plane z = 1 return in.color;
let win_dim = vec2<f32>(f32(view.width), f32(view.height));
let aspect = win_dim.y / win_dim.x;
let pixel_pos = vec3<f32>(
(in.clip_position.xy / win_dim - vec2<f32>(0.5)) * vec2<f32>(2.0, -2.0 * aspect),
1.0
);
// move to position in world
let pos = view.transform * vec4<f32>(pixel_pos, 1.0);
let dir = view.transform * vec4<f32>(normalize(pixel_pos), 0.0);
var color = trace_full(pos, dir);
let light_mult = clamp((-dot(dir.xyz, normalize(GLOBAL_LIGHT)) - 0.99) * 200.0, 0.0, 1.0);
let sky_color = light_mult * vec3<f32>(1.0, 1.0, 1.0);
color += vec4<f32>(sky_color * (1.0 - color.a), 1.0 - color.a);
color.a = 1.0;
return color;
} }

View File

@@ -1,6 +0,0 @@
#[repr(C)]
#[derive(Copy, Clone, Debug)]
struct Vertex {
position: [f32; 3],
color: [f32; 3],
}

View File

@@ -1,11 +1,9 @@
use nalgebra::{Transform3, Translation3}; use nalgebra::Matrix4;
use crate::client::render::uniform::UniformData;
#[repr(C, align(16))] #[repr(C, align(16))]
#[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)] #[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)]
pub struct View { pub struct View {
pub transform: Transform3<f32>, pub transform: Matrix4<f32>,
pub width: u32, pub width: u32,
pub height: u32, pub height: u32,
pub zoom: f32, pub zoom: f32,
@@ -19,29 +17,7 @@ impl Default for View {
width: 1, width: 1,
height: 1, height: 1,
zoom: 1.0, zoom: 1.0,
transform: Transform3::identity(), transform: Matrix4::identity(),
}
}
}
impl UniformData for View {
fn update(&mut self, data: &crate::client::render::RenderUpdateData) -> bool {
let camera = data.state.camera;
let new = Transform3::identity() * Translation3::from(camera.pos) * camera.orientation;
if new == self.transform
&& data.size.width == self.width
&& data.size.height == self.height
&& camera.scale == self.zoom
{
false
} else {
*self = Self {
width: data.size.width,
height: data.size.height,
zoom: camera.scale,
transform: new,
};
true
} }
} }
} }

View File

@@ -1,3 +1,5 @@
use std::ops::Deref;
use bevy_ecs::{ use bevy_ecs::{
entity::Entity, entity::Entity,
query::{Added, Changed, Or}, query::{Added, Changed, Or},
@@ -31,7 +33,7 @@ pub fn add_grid(
grid.len_of(Axis(1)), grid.len_of(Axis(1)),
grid.len_of(Axis(2)), grid.len_of(Axis(2)),
), ),
grid: grid.iter().cloned().collect(), grid: grid.deref().clone(),
})); }));
} }
} }

7
src/world/chunk.rs Normal file
View File

@@ -0,0 +1,7 @@
use crate::client::render::voxel::VoxelColor;
use super::component::TrackedGrid;
pub struct Chunk {
grid: TrackedGrid<VoxelColor>
}

View File

@@ -1,2 +1,3 @@
pub mod component; pub mod component;
pub mod generation; pub mod generation;
pub mod chunk;