basic working polygon renderer
This commit is contained in:
213
Cargo.lock
generated
213
Cargo.lock
generated
@@ -321,9 +321,9 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||
|
||||
[[package]]
|
||||
name = "block2"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43ff7d91d3c1d568065b06c899777d1e48dcf76103a672a0adbc238a7f247f1e"
|
||||
checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
|
||||
dependencies = [
|
||||
"objc2",
|
||||
]
|
||||
@@ -417,9 +417,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77e53693616d3075149f4ead59bdeecd204ac6b8192d8969757601b74bddf00f"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
@@ -1200,15 +1200,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objc-sys"
|
||||
version = "0.3.3"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da284c198fb9b7b0603f8635185e85fbd5b64ee154b1ed406d489077de2d6d60"
|
||||
checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
|
||||
|
||||
[[package]]
|
||||
name = "objc2"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4b25e1034d0e636cd84707ccdaa9f81243d399196b8a773946dcffec0401659"
|
||||
checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
|
||||
dependencies = [
|
||||
"objc-sys",
|
||||
"objc2-encode",
|
||||
@@ -1216,21 +1216,172 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objc2-app-kit"
|
||||
version = "0.2.0"
|
||||
version = "0.2.2"
|
||||
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 = [
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-core-data",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-data"
|
||||
version = "0.2.0"
|
||||
version = "0.2.2"
|
||||
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 = [
|
||||
"block2",
|
||||
"objc2",
|
||||
@@ -1238,20 +1389,16 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-encode"
|
||||
version = "4.0.1"
|
||||
name = "objc2-user-notifications"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88658da63e4cc2c8adb1262902cd6af51094df0488b760d6fd27194269c0950a"
|
||||
|
||||
[[package]]
|
||||
name = "objc2-foundation"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfaefe14254871ea16c7d88968c0ff14ba554712a20d76421eec52f0a7fb8904"
|
||||
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"block2",
|
||||
"dispatch",
|
||||
"objc2",
|
||||
"objc2-core-location",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2123,9 +2270,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wgpu"
|
||||
version = "0.20.0"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32ff1bfee408e1028e2e3acbf6d32d98b08a5a059ccbf5f33305534453ba5d3e"
|
||||
checksum = "90e37c7b9921b75dfd26dd973fdcbce36f13dfa6e2dc82aece584e0ed48c355c"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"cfg-if",
|
||||
@@ -2149,9 +2296,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wgpu-core"
|
||||
version = "0.20.0"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac6a86eaa5e763e59c73cf9e97d55fffd4dfda69fd8bda19589fcf851ddfef1f"
|
||||
checksum = "d59e0d5fc509601c69e4e1fa06c1eb3c4c9f12956a5e30c79b61ef1c1be7daf0"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bit-vec",
|
||||
@@ -2176,9 +2323,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wgpu-hal"
|
||||
version = "0.20.0"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d71c8ae05170583049b65ee562fd839fdc0b3e9ddb84f4e40c9d5f8ea0d4c8c"
|
||||
checksum = "6aa24c3889f885a3fb9133b454c8418bfcfaadcfe4ed3be96ac80e76703b863b"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"arrayvec",
|
||||
@@ -2494,17 +2641,18 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
||||
[[package]]
|
||||
name = "winit"
|
||||
version = "0.30.0"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea9e6d5d66cbf702e0dd820302144f51b69a95acdc495dd98ca280ff206562b1"
|
||||
checksum = "763759577d7e92f618ecaca2f5fe415512cae924cfc9460d1c48e1c616c716aa"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"android-activity",
|
||||
"atomic-waker",
|
||||
"bitflags 2.5.0",
|
||||
"block2",
|
||||
"bytemuck",
|
||||
"calloop",
|
||||
"cfg_aliases 0.2.0",
|
||||
"cfg_aliases 0.2.1",
|
||||
"concurrent-queue",
|
||||
"core-foundation",
|
||||
"core-graphics",
|
||||
@@ -2517,6 +2665,7 @@ dependencies = [
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation",
|
||||
"objc2-ui-kit",
|
||||
"orbclient",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
|
||||
@@ -16,7 +16,7 @@ pollster = "0.3"
|
||||
rand = "0.8.5"
|
||||
simba = "0.8.1"
|
||||
smaa = "0.14.0"
|
||||
wgpu = "0.20"
|
||||
wgpu = "0.20.1"
|
||||
bevy_ecs = "0.13.2"
|
||||
bevy_derive = "0.13.2"
|
||||
winit = {version="0.30", features=["serde"]}
|
||||
winit = {version="0.30.1", features=["serde"]}
|
||||
|
||||
@@ -22,7 +22,11 @@ use crate::{
|
||||
};
|
||||
|
||||
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::{
|
||||
event::WindowEvent,
|
||||
window::{Window, WindowAttributes},
|
||||
@@ -44,6 +48,7 @@ pub struct Client<'a> {
|
||||
systems: ClientSystems,
|
||||
target: Instant,
|
||||
frame_time: Duration,
|
||||
the_thing: bool,
|
||||
}
|
||||
|
||||
pub struct ClientSystems {
|
||||
@@ -86,6 +91,7 @@ impl Client<'_> {
|
||||
server_id_map: HashMap::new(),
|
||||
target: Instant::now(),
|
||||
frame_time: FRAME_TIME,
|
||||
the_thing: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +112,13 @@ impl Client<'_> {
|
||||
.expect("WHAT");
|
||||
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 {
|
||||
self.target += self.frame_time;
|
||||
let mut commands = std::mem::take(&mut self.render_commands);
|
||||
|
||||
@@ -3,6 +3,7 @@ use crate::client::camera::Camera;
|
||||
use super::{voxel::VoxelColor, Renderer};
|
||||
use bevy_ecs::entity::Entity;
|
||||
use nalgebra::{Rotation3, Vector3};
|
||||
use ndarray::Array3;
|
||||
use std::sync::Arc;
|
||||
use winit::window::Window;
|
||||
|
||||
@@ -19,7 +20,7 @@ pub struct CreateVoxelGrid {
|
||||
pub pos: Vector3<f32>,
|
||||
pub orientation: Rotation3<f32>,
|
||||
pub dimensions: Vector3<usize>,
|
||||
pub grid: Vec<VoxelColor>,
|
||||
pub grid: Array3<VoxelColor>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
mod command;
|
||||
mod util;
|
||||
pub mod voxel;
|
||||
pub mod voxel_poly;
|
||||
|
||||
pub use command::*;
|
||||
use util::Texture;
|
||||
|
||||
use super::camera::Camera;
|
||||
use crate::client::rsc::CLEAR_COLOR;
|
||||
use nalgebra::Vector2;
|
||||
use smaa::{SmaaMode, SmaaTarget};
|
||||
use voxel::VoxelPipeline;
|
||||
use voxel_poly::VoxelPipeline;
|
||||
use winit::dpi::PhysicalSize;
|
||||
|
||||
pub struct Renderer<'a> {
|
||||
@@ -22,6 +24,7 @@ pub struct Renderer<'a> {
|
||||
voxel_pipeline: VoxelPipeline,
|
||||
smaa_target: SmaaTarget,
|
||||
camera: Camera,
|
||||
depth_texture: Texture,
|
||||
}
|
||||
|
||||
impl<'a> Renderer<'a> {
|
||||
@@ -67,7 +70,7 @@ impl<'a> Renderer<'a> {
|
||||
format: surface_format,
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
present_mode: surface_caps.present_modes[0],
|
||||
present_mode: wgpu::PresentMode::AutoVsync,
|
||||
alpha_mode: surface_caps.alpha_modes[0],
|
||||
view_formats: vec![],
|
||||
desired_maximum_frame_latency: 2,
|
||||
@@ -87,10 +90,12 @@ impl<'a> Renderer<'a> {
|
||||
SmaaMode::Smaa1X,
|
||||
);
|
||||
|
||||
let depth_texture = Texture::create_depth_texture(&device, &config, "depth_texture");
|
||||
|
||||
Self {
|
||||
camera: Camera::default(),
|
||||
size: Vector2::new(size.width, size.height),
|
||||
voxel_pipeline: VoxelPipeline::new(&device, &config.format),
|
||||
voxel_pipeline: VoxelPipeline::new(&device, &config),
|
||||
staging_belt,
|
||||
surface,
|
||||
encoder: Self::create_encoder(&device),
|
||||
@@ -98,6 +103,7 @@ impl<'a> Renderer<'a> {
|
||||
config,
|
||||
queue,
|
||||
smaa_target,
|
||||
depth_texture,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +133,14 @@ impl<'a> Renderer<'a> {
|
||||
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,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
@@ -149,6 +162,8 @@ impl<'a> Renderer<'a> {
|
||||
self.smaa_target
|
||||
.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.device,
|
||||
&mut self.encoder,
|
||||
|
||||
@@ -5,7 +5,7 @@ use super::buf::{ArrBuf, ArrBufUpdate, BufMove};
|
||||
pub struct Instances<T: bytemuck::Pod> {
|
||||
buf: ArrBuf<T>,
|
||||
location: u32,
|
||||
attrs: [VertexAttribute; 1],
|
||||
attrs: Vec<VertexAttribute>,
|
||||
}
|
||||
|
||||
impl<T: bytemuck::Pod> Instances<T> {
|
||||
@@ -24,7 +24,7 @@ impl<T: bytemuck::Pod> Instances<T> {
|
||||
device: &wgpu::Device,
|
||||
label: &str,
|
||||
location: u32,
|
||||
format: wgpu::VertexFormat,
|
||||
attrs: &[wgpu::VertexAttribute],
|
||||
) -> Self {
|
||||
Self {
|
||||
buf: ArrBuf::init(
|
||||
@@ -33,11 +33,26 @@ impl<T: bytemuck::Pod> Instances<T> {
|
||||
BufferUsages::VERTEX,
|
||||
),
|
||||
location,
|
||||
attrs: [wgpu::VertexAttribute {
|
||||
format,
|
||||
offset: 0,
|
||||
shader_location: location,
|
||||
}],
|
||||
attrs: attrs.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
self.buf.mov(mov);
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.buf.len()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,12 @@ mod buf;
|
||||
mod instance;
|
||||
mod storage;
|
||||
mod uniform;
|
||||
mod vertex;
|
||||
mod texture;
|
||||
|
||||
pub use buf::*;
|
||||
pub use instance::*;
|
||||
pub use storage::*;
|
||||
pub use uniform::*;
|
||||
pub use vertex::*;
|
||||
pub use texture::*;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use super::buf::{ArrBuf, ArrBufUpdate, BufMove};
|
||||
use wgpu::BufferUsages;
|
||||
|
||||
pub struct Storage<T: bytemuck::Pod + PartialEq> {
|
||||
pub struct Storage<T: bytemuck::Pod> {
|
||||
binding: u32,
|
||||
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 {
|
||||
Self {
|
||||
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 {
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: self.binding,
|
||||
|
||||
55
src/client/render/util/texture.rs
Normal file
55
src/client/render/util/texture.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,17 @@ impl<T: Default + 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 {
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: self.binding,
|
||||
|
||||
86
src/client/render/util/vertex.rs
Normal file
86
src/client/render/util/vertex.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
@@ -150,7 +150,7 @@ impl VoxelPipeline {
|
||||
|
||||
let updates = [ArrBufUpdate {
|
||||
offset,
|
||||
data: &grid,
|
||||
data: &grid.as_slice().unwrap(),
|
||||
}];
|
||||
let size = offset + grid.len();
|
||||
self.voxels.update(device, encoder, belt, size, &updates);
|
||||
@@ -226,7 +226,6 @@ impl VoxelPipeline {
|
||||
width: size.x,
|
||||
height: size.y,
|
||||
zoom: camera.scale,
|
||||
padding: 0,
|
||||
transform,
|
||||
};
|
||||
self.view.update(device, encoder, belt, data)
|
||||
|
||||
@@ -6,15 +6,13 @@ struct GlobalLight {
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) tex_coords: vec2<f32>,
|
||||
};
|
||||
|
||||
struct View {
|
||||
transform: mat4x4<f32>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
zoom: f32,
|
||||
padding: u32,
|
||||
transform: mat4x4<f32>,
|
||||
};
|
||||
|
||||
struct VoxelGroup {
|
||||
|
||||
@@ -3,11 +3,10 @@ use nalgebra::Transform3;
|
||||
#[repr(C, align(16))]
|
||||
#[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)]
|
||||
pub struct View {
|
||||
pub transform: Transform3<f32>,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub zoom: f32,
|
||||
pub padding: u32,
|
||||
pub transform: Transform3<f32>,
|
||||
}
|
||||
|
||||
unsafe impl bytemuck::Pod for View {}
|
||||
@@ -18,7 +17,6 @@ impl Default for View {
|
||||
width: 1,
|
||||
height: 1,
|
||||
zoom: 1.0,
|
||||
padding: 0,
|
||||
transform: Transform3::identity(),
|
||||
}
|
||||
}
|
||||
|
||||
11
src/client/render/voxel_poly/group.rs
Normal file
11
src/client/render/voxel_poly/group.rs
Normal 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 {}
|
||||
12
src/client/render/voxel_poly/instance.rs
Normal file
12
src/client/render/voxel_poly/instance.rs
Normal 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 {}
|
||||
@@ -1,26 +1,47 @@
|
||||
use super::uniform::Uniform;
|
||||
use nalgebra::{Projective3, Translation3, Rotation3};
|
||||
|
||||
mod view;
|
||||
mod color;
|
||||
mod vertex;
|
||||
mod group;
|
||||
mod instance;
|
||||
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 {
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
view: Uniform<View>,
|
||||
bind_group_layout: wgpu::BindGroupLayout,
|
||||
bind_group: wgpu::BindGroup,
|
||||
voxel_groups: Storage<VoxelGroup>,
|
||||
voxels: Storage<VoxelColor>,
|
||||
arst: bool,
|
||||
bind_groups: Vec<wgpu::BindGroup>,
|
||||
vertices: Vec<Instances<VoxelFace>>,
|
||||
}
|
||||
|
||||
const WIDTH: u32 = 300;
|
||||
const HEIGHT: u32 = 300;
|
||||
const INSTANCE_ATTRS: [wgpu::VertexAttribute; 2] = [
|
||||
VertexAttribute {
|
||||
format: VertexFormat::Uint32,
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
},
|
||||
VertexAttribute {
|
||||
format: VertexFormat::Uint32,
|
||||
offset: 4,
|
||||
shader_location: 1,
|
||||
},
|
||||
];
|
||||
|
||||
impl VoxelPipeline {
|
||||
pub fn new(device: &wgpu::Device, format: &wgpu::TextureFormat) -> Self {
|
||||
pub fn new(device: &wgpu::Device, config: &SurfaceConfiguration) -> Self {
|
||||
// shaders
|
||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||
label: Some("Tile Shader"),
|
||||
@@ -28,29 +49,19 @@ impl VoxelPipeline {
|
||||
});
|
||||
|
||||
let view = Uniform::<View>::init(device, "view", 0);
|
||||
let voxels = Storage::init(device, "voxels", 1);
|
||||
let voxel_groups = Storage::init(device, "voxel groups", 2);
|
||||
let example_faces =
|
||||
Instances::<VoxelFace>::init(device, "voxel groups", 0, &INSTANCE_ATTRS);
|
||||
let example_group = Uniform::<FaceGroup>::init(device, "voxel group", 1);
|
||||
|
||||
// bind groups
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
entries: &[
|
||||
view.bind_group_layout_entry(),
|
||||
voxels.bind_group_layout_entry(),
|
||||
voxel_groups.bind_group_layout_entry(),
|
||||
example_group.bind_group_layout_entry(),
|
||||
],
|
||||
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
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
@@ -65,14 +76,14 @@ impl VoxelPipeline {
|
||||
vertex: wgpu::VertexState {
|
||||
module: &shader,
|
||||
entry_point: "vs_main",
|
||||
buffers: &[],
|
||||
buffers: &[example_faces.desc()],
|
||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||
},
|
||||
fragment: Some(wgpu::FragmentState {
|
||||
module: &shader,
|
||||
entry_point: "fs_main",
|
||||
targets: &[Some(wgpu::ColorTargetState {
|
||||
format: *format,
|
||||
format: config.format,
|
||||
blend: Some(wgpu::BlendState::REPLACE),
|
||||
write_mask: wgpu::ColorWrites::ALL,
|
||||
})],
|
||||
@@ -82,12 +93,18 @@ impl VoxelPipeline {
|
||||
topology: wgpu::PrimitiveTopology::TriangleStrip,
|
||||
strip_index_format: None,
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: None,
|
||||
cull_mode: Some(wgpu::Face::Back),
|
||||
polygon_mode: wgpu::PolygonMode::Fill,
|
||||
unclipped_depth: 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 {
|
||||
count: 1,
|
||||
mask: !0,
|
||||
@@ -99,165 +116,123 @@ impl VoxelPipeline {
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
view,
|
||||
bind_group,
|
||||
bind_group_layout,
|
||||
voxels,
|
||||
voxel_groups,
|
||||
arst: false,
|
||||
bind_groups: Vec::new(),
|
||||
vertices: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
pub fn update_view(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
encoder: &mut wgpu::CommandEncoder,
|
||||
belt: &mut wgpu::util::StagingBelt,
|
||||
update_data: &RenderUpdateData,
|
||||
size: Vector2<u32>,
|
||||
camera: &Camera,
|
||||
) {
|
||||
if !self.arst {
|
||||
let lx = 15;
|
||||
let ly = 10;
|
||||
let lz = 10;
|
||||
let mut data = vec![VoxelColor::none(); lx * ly * lz];
|
||||
for x in 0..lx {
|
||||
for y in 0..ly {
|
||||
data[x + y * lx] = VoxelColor {
|
||||
r: (x as f32 / lx as f32 * 255.0) as u8,
|
||||
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 mut transform = (Translation3::from(camera.pos) * camera.orientation)
|
||||
.inverse()
|
||||
.to_matrix();
|
||||
transform = transform.append_nonuniform_scaling(&Vector3::new(1.0, 1.0, -1.0));
|
||||
let projection = Perspective3::new(
|
||||
size.x as f32 / size.y as f32,
|
||||
std::f32::consts::PI / 2.0,
|
||||
0.1,
|
||||
1000.0,
|
||||
);
|
||||
let proj = Projective3::identity()
|
||||
* Translation3::new(0.0, 0.0, 20.0)
|
||||
* Rotation3::from_axis_angle(&Vector3::y_axis(), 0.5)
|
||||
* Translation3::new(-(lx as f32 / 2.0), -(ly as f32 / 2.0), -(lz as f32 / 2.0));
|
||||
let group = VoxelGroup {
|
||||
transform: proj,
|
||||
transform_inv: proj.inverse(),
|
||||
dimensions: Vector3::new(lx as u32, ly as u32, lz as u32),
|
||||
offset: 0,
|
||||
transform = projection.as_matrix() * transform;
|
||||
let data = View {
|
||||
width: size.x,
|
||||
height: size.y,
|
||||
zoom: camera.scale,
|
||||
transform,
|
||||
};
|
||||
let proj2 = Projective3::identity()
|
||||
* 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);
|
||||
self.view.update(device, encoder, belt, data)
|
||||
}
|
||||
|
||||
pub fn draw<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) {
|
||||
render_pass.set_pipeline(&self.pipeline);
|
||||
render_pass.set_bind_group(0, &self.bind_group, &[]);
|
||||
render_pass.draw(0..4, 0..1);
|
||||
for i in 0..self.bind_groups.len() {
|
||||
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,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
// Vertex shader
|
||||
|
||||
struct InstanceInput {
|
||||
@location(0) index: u32,
|
||||
@location(1) color: u32,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
@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 {
|
||||
transform: mat4x4<f32>,
|
||||
width: u32,
|
||||
@@ -14,31 +24,51 @@ struct View {
|
||||
|
||||
struct VoxelGroup {
|
||||
transform: mat4x4<f32>,
|
||||
transform_inv: mat4x4<f32>,
|
||||
dimensions: vec3<u32>,
|
||||
offset: u32,
|
||||
face: u32,
|
||||
};
|
||||
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
@group(0) @binding(1)
|
||||
var<storage, read> voxels: array<u32>;
|
||||
@group(0) @binding(2)
|
||||
var<storage, read> voxel_groups: array<VoxelGroup>;
|
||||
var<uniform> group: 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
|
||||
fn vs_main(
|
||||
@builtin(vertex_index) vi: u32,
|
||||
@builtin(instance_index) ii: u32,
|
||||
in: InstanceInput
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
|
||||
var pos = vec2<f32>(
|
||||
f32(vi % 2u) * 2.0 - 1.0,
|
||||
f32(vi / 2u) * 2.0 - 1.0,
|
||||
let invert = select(0.0, 1.0, group.face / 3 == 1);
|
||||
let invert_mult = 1.0 - invert * 2.0;
|
||||
var square_pos = vec2<f32>(
|
||||
f32(vi % 2u),
|
||||
invert + invert_mult * f32(vi / 2u),
|
||||
);
|
||||
out.clip_position = vec4<f32>(pos.x, pos.y, 0.0, 1.0);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -48,22 +78,5 @@ fn vs_main(
|
||||
fn fs_main(
|
||||
in: VertexOutput,
|
||||
) -> @location(0) vec4<f32> {
|
||||
// get position of the pixel; eye at origin, pixel on plane z = 1
|
||||
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;
|
||||
return in.color;
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct Vertex {
|
||||
position: [f32; 3],
|
||||
color: [f32; 3],
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
use nalgebra::{Transform3, Translation3};
|
||||
|
||||
use crate::client::render::uniform::UniformData;
|
||||
use nalgebra::Matrix4;
|
||||
|
||||
#[repr(C, align(16))]
|
||||
#[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)]
|
||||
pub struct View {
|
||||
pub transform: Transform3<f32>,
|
||||
pub transform: Matrix4<f32>,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub zoom: f32,
|
||||
@@ -19,29 +17,7 @@ impl Default for View {
|
||||
width: 1,
|
||||
height: 1,
|
||||
zoom: 1.0,
|
||||
transform: Transform3::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
|
||||
transform: Matrix4::identity(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
use bevy_ecs::{
|
||||
entity::Entity,
|
||||
query::{Added, Changed, Or},
|
||||
@@ -31,7 +33,7 @@ pub fn add_grid(
|
||||
grid.len_of(Axis(1)),
|
||||
grid.len_of(Axis(2)),
|
||||
),
|
||||
grid: grid.iter().cloned().collect(),
|
||||
grid: grid.deref().clone(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
7
src/world/chunk.rs
Normal file
7
src/world/chunk.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use crate::client::render::voxel::VoxelColor;
|
||||
|
||||
use super::component::TrackedGrid;
|
||||
|
||||
pub struct Chunk {
|
||||
grid: TrackedGrid<VoxelColor>
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod component;
|
||||
pub mod generation;
|
||||
pub mod chunk;
|
||||
|
||||
Reference in New Issue
Block a user