Meshify chunks
This commit is contained in:
parent
da7f7759ad
commit
033c257d3b
11 changed files with 264 additions and 393 deletions
49
src/aabb.rs
49
src/aabb.rs
|
@ -1,49 +0,0 @@
|
|||
use cgmath::Vector3;
|
||||
use std::ops::{Div, Sub};
|
||||
|
||||
pub struct Aabb<T> {
|
||||
pub min: Vector3<T>,
|
||||
pub max: Vector3<T>,
|
||||
}
|
||||
|
||||
impl<T: Ord + Copy + Sub<Output = T> + Div<Output = T>> Aabb<T> {
|
||||
pub fn intersects_ray(
|
||||
&self,
|
||||
ray_origin: Vector3<T>,
|
||||
ray_direction: Vector3<T>,
|
||||
) -> Option<(T, T)> {
|
||||
let mut t_min = (self.min.x - ray_origin.x) / ray_direction.x;
|
||||
let mut t_max = (self.max.x - ray_origin.x) / ray_direction.x;
|
||||
if t_min > t_max {
|
||||
std::mem::swap(&mut t_min, &mut t_max);
|
||||
}
|
||||
|
||||
let mut ty_min = (self.min.y - ray_origin.y) / ray_direction.y;
|
||||
let mut ty_max = (self.max.y - ray_origin.y) / ray_direction.y;
|
||||
if ty_min > ty_max {
|
||||
std::mem::swap(&mut ty_min, &mut ty_max);
|
||||
}
|
||||
|
||||
if t_min > ty_max || ty_min > t_max {
|
||||
return None;
|
||||
}
|
||||
|
||||
t_min = T::max(t_min, ty_min);
|
||||
t_max = T::min(t_min, ty_max);
|
||||
|
||||
let mut tz_min = (self.min.z - ray_origin.z) / ray_direction.z;
|
||||
let mut tz_max = (self.max.z - ray_origin.z) / ray_direction.z;
|
||||
if tz_min > tz_max {
|
||||
std::mem::swap(&mut tz_min, &mut tz_max);
|
||||
}
|
||||
|
||||
if t_min > tz_max || tz_min > t_max {
|
||||
return None;
|
||||
}
|
||||
|
||||
t_min = T::max(t_min, tz_min);
|
||||
t_max = T::max(t_max, tz_max);
|
||||
|
||||
Some((t_min, t_max))
|
||||
}
|
||||
}
|
115
src/chunk.rs
115
src/chunk.rs
|
@ -1,5 +1,7 @@
|
|||
use crate::instance::Instance;
|
||||
use ahash::AHashMap;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use crate::{cube, quad::Quad, vertex::Vertex};
|
||||
use ahash::{AHashMap, AHashSet};
|
||||
use cgmath::{InnerSpace, Vector3};
|
||||
use noise::utils::{NoiseMapBuilder, PlaneMapBuilder};
|
||||
|
||||
|
@ -7,8 +9,11 @@ use noise::utils::{NoiseMapBuilder, PlaneMapBuilder};
|
|||
pub enum BlockType {
|
||||
Cobblestone,
|
||||
Dirt,
|
||||
Grass,
|
||||
Stone,
|
||||
Grass,
|
||||
Bedrock,
|
||||
Sand,
|
||||
Gravel,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
@ -16,7 +21,7 @@ pub struct Block {
|
|||
pub block_type: BlockType,
|
||||
}
|
||||
|
||||
const CHUNK_SIZE: usize = 16;
|
||||
pub(crate) const CHUNK_SIZE: usize = 16;
|
||||
|
||||
type ChunkBlocks = [[[Option<Block>; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE];
|
||||
|
||||
|
@ -85,6 +90,12 @@ impl Chunk {
|
|||
block_type: BlockType::Grass,
|
||||
});
|
||||
}
|
||||
|
||||
if chunk_y == 0 {
|
||||
blocks[0][z][x] = Some(Block {
|
||||
block_type: BlockType::Bedrock,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,53 +106,91 @@ impl Chunk {
|
|||
}
|
||||
|
||||
fn check_visible(&self, x: usize, y: usize, z: usize) -> bool {
|
||||
(x > 0 && y > 0 && z > 0 && self.get_block(x - 1, y - 1, z - 1).is_some())
|
||||
&& (y > 0 && z > 0 && self.get_block(x + 1, y - 1, z - 1).is_some())
|
||||
&& (x > 0 && z > 0 && self.get_block(x - 1, y + 1, z - 1).is_some())
|
||||
&& (z > 0 && self.get_block(x + 1, y + 1, z - 1).is_some())
|
||||
&& (x > 0 && y > 0 && self.get_block(x - 1, y - 1, z + 1).is_some())
|
||||
&& (y > 0 && self.get_block(x + 1, y - 1, z + 1).is_some())
|
||||
&& (x > 0 && self.get_block(x - 1, y + 1, z + 1).is_some())
|
||||
&& (x > 0 && y > 0 && z > 0 && self.get_block(x + 1, y + 1, z + 1).is_some())
|
||||
self.get_block(x - 1, y - 1, z - 1).is_some()
|
||||
&& self.get_block(x + 1, y - 1, z - 1).is_some()
|
||||
&& self.get_block(x - 1, y + 1, z - 1).is_some()
|
||||
&& self.get_block(x + 1, y + 1, z - 1).is_some()
|
||||
&& self.get_block(x - 1, y - 1, z + 1).is_some()
|
||||
&& self.get_block(x + 1, y - 1, z + 1).is_some()
|
||||
&& self.get_block(x - 1, y + 1, z + 1).is_some()
|
||||
&& self.get_block(x + 1, y + 1, z + 1).is_some()
|
||||
}
|
||||
|
||||
pub fn to_instances(&self, offset: Vector3<i32>) -> Vec<(BlockType, Vec<Instance>)> {
|
||||
let mut map: AHashMap<BlockType, Vec<Instance>> = AHashMap::new();
|
||||
pub fn to_instances(&self, offset: Vector3<i32>) -> (Vec<Vertex>, Vec<u16>) {
|
||||
let mut quads: Vec<(BlockType, i32, Vector3<i32>, Quad)> = Vec::new();
|
||||
|
||||
for (y, y_blocks) in self.blocks.iter().enumerate() {
|
||||
let mut culled = AHashMap::new();
|
||||
let mut todo = VecDeque::new();
|
||||
for (z, z_blocks) in y_blocks.iter().enumerate() {
|
||||
for (x, block) in z_blocks.iter().enumerate() {
|
||||
if let Some(block) = block {
|
||||
let position = Vector3::new(
|
||||
(x as i32 + offset.x * 16) as f32,
|
||||
(y as i32 + offset.y * 16) as f32,
|
||||
(z as i32 + offset.z * 16) as f32,
|
||||
);
|
||||
|
||||
// Don't add the block if it's not visible
|
||||
if self.check_visible(x, y, z) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let instances = map.entry(block.block_type).or_default();
|
||||
instances.push(Instance {
|
||||
position: position.into(),
|
||||
highlighted: (self.highlighted == Some(Vector3::new(x, y, z))) as i32,
|
||||
});
|
||||
culled.insert((x, z), block.block_type);
|
||||
todo.push_back((x, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut visited = AHashSet::new();
|
||||
while let Some((x, z)) = todo.pop_front() {
|
||||
if visited.contains(&(x, z)) {
|
||||
continue;
|
||||
}
|
||||
visited.insert((x, z));
|
||||
|
||||
if let Some(&block_type) = &culled.get(&(x, z)) {
|
||||
// Extend horizontally
|
||||
let mut xmax = x + 1;
|
||||
for x_ in x..CHUNK_SIZE {
|
||||
xmax = x_ + 1;
|
||||
if culled.get(&(x_ + 1, z)) != Some(&block_type)
|
||||
|| visited.contains(&(x_ + 1, z))
|
||||
{
|
||||
break;
|
||||
}
|
||||
visited.insert((x_ + 1, z));
|
||||
}
|
||||
|
||||
// Extend vertically
|
||||
let mut zmax = z + 1;
|
||||
'z: for z_ in z..CHUNK_SIZE {
|
||||
zmax = z_ + 1;
|
||||
for x_ in x..xmax {
|
||||
if culled.get(&(x_, z_ + 1)) != Some(&block_type)
|
||||
|| visited.contains(&(x_, z_ + 1))
|
||||
{
|
||||
break 'z;
|
||||
}
|
||||
}
|
||||
for x_ in x..xmax {
|
||||
visited.insert((x_, z_ + 1));
|
||||
}
|
||||
}
|
||||
|
||||
let quad = Quad::new(x as i32, z as i32, (xmax - x) as i32, (zmax - z) as i32);
|
||||
quads.push((block_type, y as i32, offset, quad));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map.drain().collect()
|
||||
}
|
||||
let mut vertices = Vec::new();
|
||||
let mut indices = Vec::new();
|
||||
for (quad_index, (_, y, offset, quad)) in quads.iter().enumerate() {
|
||||
#[rustfmt::skip]
|
||||
let v = cube::vertices(quad, *y, *offset, (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1));
|
||||
vertices.extend(&v);
|
||||
|
||||
pub fn get_mut_block(&mut self, x: usize, y: usize, z: usize) -> Option<&mut Block> {
|
||||
self.blocks
|
||||
.get_mut(y)
|
||||
.and_then(|blocks| blocks.get_mut(z))
|
||||
.and_then(|blocks| blocks.get_mut(x))
|
||||
.and_then(|block| block.as_mut())
|
||||
for index in cube::INDICES {
|
||||
indices.push(index + quad_index as u16 * 24);
|
||||
}
|
||||
}
|
||||
|
||||
(vertices, indices)
|
||||
}
|
||||
|
||||
pub fn get_block(&self, x: usize, y: usize, z: usize) -> Option<&Block> {
|
||||
|
|
123
src/cube.rs
123
src/cube.rs
|
@ -1,82 +1,67 @@
|
|||
use crate::vertex::Vertex;
|
||||
use cgmath::Vector3;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const VERTICES: &[Vertex] = &[
|
||||
// Left
|
||||
Vertex { position: [0.0, 0.0, 0.0], texture_coordinates: [1.0, 1.0], normal: [-1.0, 0.0, 0.0] },
|
||||
Vertex { position: [0.0, 0.0, 1.0], texture_coordinates: [0.0, 1.0], normal: [-1.0, 0.0, 0.0] },
|
||||
Vertex { position: [0.0, 1.0, 1.0], texture_coordinates: [0.0, 0.0], normal: [-1.0, 0.0, 0.0] },
|
||||
Vertex { position: [0.0, 1.0, 0.0], texture_coordinates: [1.0, 0.0], normal: [-1.0, 0.0, 0.0] },
|
||||
use crate::{quad::Quad, vertex::Vertex};
|
||||
|
||||
// Right
|
||||
Vertex { position: [1.0, 0.0, 0.0], texture_coordinates: [0.0, 1.0], normal: [ 1.0, 0.0, 0.0] },
|
||||
Vertex { position: [1.0, 0.0, 1.0], texture_coordinates: [1.0, 1.0], normal: [ 1.0, 0.0, 0.0] },
|
||||
Vertex { position: [1.0, 1.0, 1.0], texture_coordinates: [1.0, 0.0], normal: [ 1.0, 0.0, 0.0] },
|
||||
Vertex { position: [1.0, 1.0, 0.0], texture_coordinates: [0.0, 0.0], normal: [ 1.0, 0.0, 0.0] },
|
||||
const S: f32 = 512.0 / 4096.0;
|
||||
|
||||
// Back
|
||||
Vertex { position: [0.0, 0.0, 0.0], texture_coordinates: [1.0, 1.0], normal: [ 0.0, 0.0, -1.0] },
|
||||
Vertex { position: [0.0, 1.0, 0.0], texture_coordinates: [1.0, 0.0], normal: [ 0.0, 0.0, -1.0] },
|
||||
Vertex { position: [1.0, 1.0, 0.0], texture_coordinates: [0.0, 0.0], normal: [ 0.0, 0.0, -1.0] },
|
||||
Vertex { position: [1.0, 0.0, 0.0], texture_coordinates: [0.0, 1.0], normal: [ 0.0, 0.0, -1.0] },
|
||||
pub fn vertices(
|
||||
quad: &Quad,
|
||||
y: i32,
|
||||
offset: Vector3<i32>,
|
||||
left: (i32, i32),
|
||||
right: (i32, i32),
|
||||
back: (i32, i32),
|
||||
front: (i32, i32),
|
||||
bottom: (i32, i32),
|
||||
top: (i32, i32),
|
||||
) -> [Vertex; 24] {
|
||||
let w = quad.w as f32;
|
||||
let h = quad.h as f32;
|
||||
|
||||
// Front
|
||||
Vertex { position: [0.0, 0.0, 1.0], texture_coordinates: [0.0, 1.0], normal: [ 0.0, 0.0, 1.0] },
|
||||
Vertex { position: [0.0, 1.0, 1.0], texture_coordinates: [0.0, 0.0], normal: [ 0.0, 0.0, 1.0] },
|
||||
Vertex { position: [1.0, 1.0, 1.0], texture_coordinates: [1.0, 0.0], normal: [ 0.0, 0.0, 1.0] },
|
||||
Vertex { position: [1.0, 0.0, 1.0], texture_coordinates: [1.0, 1.0], normal: [ 0.0, 0.0, 1.0] },
|
||||
let x = (quad.x + offset.x) as f32;
|
||||
let y = (y + offset.y) as f32;
|
||||
let z = (quad.y + offset.z) as f32;
|
||||
|
||||
// Bottom
|
||||
Vertex { position: [0.0, 0.0, 0.0], texture_coordinates: [1.0, 0.0], normal: [ 0.0, -1.0, 0.0] },
|
||||
Vertex { position: [0.0, 0.0, 1.0], texture_coordinates: [1.0, 1.0], normal: [ 0.0, -1.0, 0.0] },
|
||||
Vertex { position: [1.0, 0.0, 1.0], texture_coordinates: [0.0, 1.0], normal: [ 0.0, -1.0, 0.0] },
|
||||
Vertex { position: [1.0, 0.0, 0.0], texture_coordinates: [0.0, 0.0], normal: [ 0.0, -1.0, 0.0] },
|
||||
#[rustfmt::skip]
|
||||
let vertices = [
|
||||
// Left
|
||||
Vertex { position: [x, y, z ], texture_coordinates: [left.0 as f32 * S + S, left.1 as f32 * S + S], normal: [-1.0, 0.0, 0.0] },
|
||||
Vertex { position: [x, y, z + h ], texture_coordinates: [left.0 as f32 * S, left.1 as f32 * S + S], normal: [-1.0, 0.0, 0.0] },
|
||||
Vertex { position: [x, y + 1.0, z + h ], texture_coordinates: [left.0 as f32 * S, left.1 as f32 * S ], normal: [-1.0, 0.0, 0.0] },
|
||||
Vertex { position: [x, y + 1.0, z ], texture_coordinates: [left.0 as f32 * S + S, left.1 as f32 * S ], normal: [-1.0, 0.0, 0.0] },
|
||||
|
||||
// Top
|
||||
Vertex { position: [0.0, 1.0, 0.0], texture_coordinates: [0.0, 0.0], normal: [ 0.0, 1.0, 0.0] },
|
||||
Vertex { position: [0.0, 1.0, 1.0], texture_coordinates: [0.0, 1.0], normal: [ 0.0, 1.0, 0.0] },
|
||||
Vertex { position: [1.0, 1.0, 1.0], texture_coordinates: [1.0, 1.0], normal: [ 0.0, 1.0, 0.0] },
|
||||
Vertex { position: [1.0, 1.0, 0.0], texture_coordinates: [1.0, 0.0], normal: [ 0.0, 1.0, 0.0] },
|
||||
];
|
||||
// Right
|
||||
Vertex { position: [x + w, y, z ], texture_coordinates: [right.0 as f32 * S, right.1 as f32 * S + S], normal: [1.0, 0.0, 0.0] },
|
||||
Vertex { position: [x + w, y, z + h ], texture_coordinates: [right.0 as f32 * S + S, right.1 as f32 * S + S], normal: [1.0, 0.0, 0.0] },
|
||||
Vertex { position: [x + w, y + 1.0, z + h ], texture_coordinates: [right.0 as f32 * S + S, right.1 as f32 * S ], normal: [1.0, 0.0, 0.0] },
|
||||
Vertex { position: [x + w, y + 1.0, z ], texture_coordinates: [right.0 as f32 * S, right.1 as f32 * S ], normal: [1.0, 0.0, 0.0] },
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const VERTICES_GRASS: &[Vertex] = &[
|
||||
// Left
|
||||
Vertex { position: [0.0, 0.0, 0.0], texture_coordinates: [0.5, 0.5], normal: [-1.0, 0.0, 0.0] },
|
||||
Vertex { position: [0.0, 0.0, 1.0], texture_coordinates: [0.0, 0.5], normal: [-1.0, 0.0, 0.0] },
|
||||
Vertex { position: [0.0, 1.0, 1.0], texture_coordinates: [0.0, 0.0], normal: [-1.0, 0.0, 0.0] },
|
||||
Vertex { position: [0.0, 1.0, 0.0], texture_coordinates: [0.5, 0.0], normal: [-1.0, 0.0, 0.0] },
|
||||
// Back
|
||||
Vertex { position: [x, y, z ], texture_coordinates: [back.0 as f32 * S + S, back.1 as f32 * S + S], normal: [0.0, 0.0, -1.0] },
|
||||
Vertex { position: [x, y + 1.0, z ], texture_coordinates: [back.0 as f32 * S + S, back.1 as f32 * S ], normal: [0.0, 0.0, -1.0] },
|
||||
Vertex { position: [x + w, y + 1.0, z ], texture_coordinates: [back.0 as f32 * S, back.1 as f32 * S ], normal: [0.0, 0.0, -1.0] },
|
||||
Vertex { position: [x + w, y, z ], texture_coordinates: [back.0 as f32 * S, back.1 as f32 * S + S], normal: [0.0, 0.0, -1.0] },
|
||||
|
||||
// Right
|
||||
Vertex { position: [1.0, 0.0, 0.0], texture_coordinates: [0.0, 0.5], normal: [ 1.0, 0.0, 0.0] },
|
||||
Vertex { position: [1.0, 0.0, 1.0], texture_coordinates: [0.5, 0.5], normal: [ 1.0, 0.0, 0.0] },
|
||||
Vertex { position: [1.0, 1.0, 1.0], texture_coordinates: [0.5, 0.0], normal: [ 1.0, 0.0, 0.0] },
|
||||
Vertex { position: [1.0, 1.0, 0.0], texture_coordinates: [0.0, 0.0], normal: [ 1.0, 0.0, 0.0] },
|
||||
// Front
|
||||
Vertex { position: [x, y, z + h], texture_coordinates: [front.0 as f32 * S, front.1 as f32 * S + S], normal: [0.0, 0.0, 1.0] },
|
||||
Vertex { position: [x, y + 1.0, z + h], texture_coordinates: [front.0 as f32 * S, front.1 as f32 * S ], normal: [0.0, 0.0, 1.0] },
|
||||
Vertex { position: [x + w, y + 1.0, z + h], texture_coordinates: [front.0 as f32 * S + S, front.1 as f32 * S ], normal: [0.0, 0.0, 1.0] },
|
||||
Vertex { position: [x + w, y, z + h], texture_coordinates: [front.0 as f32 * S + S, front.1 as f32 * S + S], normal: [0.0, 0.0, 1.0] },
|
||||
|
||||
// Back
|
||||
Vertex { position: [0.0, 0.0, 0.0], texture_coordinates: [0.5, 0.5], normal: [ 0.0, 0.0, -1.0] },
|
||||
Vertex { position: [0.0, 1.0, 0.0], texture_coordinates: [0.5, 0.0], normal: [ 0.0, 0.0, -1.0] },
|
||||
Vertex { position: [1.0, 1.0, 0.0], texture_coordinates: [0.0, 0.0], normal: [ 0.0, 0.0, -1.0] },
|
||||
Vertex { position: [1.0, 0.0, 0.0], texture_coordinates: [0.0, 0.5], normal: [ 0.0, 0.0, -1.0] },
|
||||
// Bottom
|
||||
Vertex { position: [x, y, z + 0.0], texture_coordinates: [bottom.0 as f32 * S + S, bottom.1 as f32 * S ], normal: [0.0, -1.0, 0.0] },
|
||||
Vertex { position: [x, y, z + h ], texture_coordinates: [bottom.0 as f32 * S + S, bottom.1 as f32 * S + S], normal: [0.0, -1.0, 0.0] },
|
||||
Vertex { position: [x + w, y, z + h ], texture_coordinates: [bottom.0 as f32 * S, bottom.1 as f32 * S + S], normal: [0.0, -1.0, 0.0] },
|
||||
Vertex { position: [x + w, y, z ], texture_coordinates: [bottom.0 as f32 * S, bottom.1 as f32 * S ], normal: [0.0, -1.0, 0.0] },
|
||||
|
||||
// Front
|
||||
Vertex { position: [0.0, 0.0, 1.0], texture_coordinates: [0.0, 0.5], normal: [ 0.0, 0.0, 1.0] },
|
||||
Vertex { position: [0.0, 1.0, 1.0], texture_coordinates: [0.0, 0.0], normal: [ 0.0, 0.0, 1.0] },
|
||||
Vertex { position: [1.0, 1.0, 1.0], texture_coordinates: [0.5, 0.0], normal: [ 0.0, 0.0, 1.0] },
|
||||
Vertex { position: [1.0, 0.0, 1.0], texture_coordinates: [0.5, 0.5], normal: [ 0.0, 0.0, 1.0] },
|
||||
|
||||
// Bottom
|
||||
Vertex { position: [0.0, 0.0, 0.0], texture_coordinates: [0.5, 0.5], normal: [ 0.0, -1.0, 0.0] },
|
||||
Vertex { position: [0.0, 0.0, 1.0], texture_coordinates: [0.5, 1.0], normal: [ 0.0, -1.0, 0.0] },
|
||||
Vertex { position: [1.0, 0.0, 1.0], texture_coordinates: [0.0, 1.0], normal: [ 0.0, -1.0, 0.0] },
|
||||
Vertex { position: [1.0, 0.0, 0.0], texture_coordinates: [0.0, 0.5], normal: [ 0.0, -1.0, 0.0] },
|
||||
|
||||
// Top
|
||||
Vertex { position: [0.0, 1.0, 0.0], texture_coordinates: [0.5, 0.0], normal: [ 0.0, 1.0, 0.0] },
|
||||
Vertex { position: [0.0, 1.0, 1.0], texture_coordinates: [0.5, 0.5], normal: [ 0.0, 1.0, 0.0] },
|
||||
Vertex { position: [1.0, 1.0, 1.0], texture_coordinates: [1.0, 0.5], normal: [ 0.0, 1.0, 0.0] },
|
||||
Vertex { position: [1.0, 1.0, 0.0], texture_coordinates: [1.0, 0.0], normal: [ 0.0, 1.0, 0.0] },
|
||||
];
|
||||
// Top
|
||||
Vertex { position: [x, y + 1.0, z ], texture_coordinates: [top.0 as f32 * S, top.1 as f32 * S ], normal: [0.0, 1.0, 0.0] },
|
||||
Vertex { position: [x, y + 1.0, z + h], texture_coordinates: [top.0 as f32 * S, top.1 as f32 * S + S], normal: [0.0, 1.0, 0.0] },
|
||||
Vertex { position: [x + w, y + 1.0, z + h], texture_coordinates: [top.0 as f32 * S + S, top.1 as f32 * S + S], normal: [0.0, 1.0, 0.0] },
|
||||
Vertex { position: [x + w, y + 1.0, z ], texture_coordinates: [top.0 as f32 * S + S, top.1 as f32 * S ], normal: [0.0, 1.0, 0.0] },
|
||||
];
|
||||
vertices
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const INDICES: &[u16] = &[
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
#[repr(C)]
|
||||
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
pub struct Instance {
|
||||
pub position: [f32; 3],
|
||||
pub highlighted: i32,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferLayout {
|
||||
array_stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Instance,
|
||||
attributes: &[
|
||||
// position: [f32; 3]
|
||||
wgpu::VertexAttribute {
|
||||
offset: 0,
|
||||
shader_location: 5,
|
||||
format: wgpu::VertexFormat::Float32x3,
|
||||
},
|
||||
// highlighted: i32
|
||||
wgpu::VertexAttribute {
|
||||
offset: 12,
|
||||
shader_location: 6,
|
||||
format: wgpu::VertexFormat::Sint32,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@ mod aabb;
|
|||
mod camera;
|
||||
mod chunk;
|
||||
mod cube;
|
||||
mod instance;
|
||||
mod light;
|
||||
mod quad;
|
||||
mod state;
|
||||
mod texture;
|
||||
mod uniforms;
|
||||
|
|
13
src/quad.rs
Normal file
13
src/quad.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
#[derive(Debug)]
|
||||
pub struct Quad {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub w: i32,
|
||||
pub h: i32,
|
||||
}
|
||||
|
||||
impl Quad {
|
||||
pub fn new(x: i32, y: i32, w: i32, h: i32) -> Self {
|
||||
Quad { x, y, w, h }
|
||||
}
|
||||
}
|
|
@ -27,23 +27,15 @@ struct VertexOutput {
|
|||
[[location(0)]] texture_coordinates: vec2<f32>;
|
||||
[[location(1)]] world_normal: vec3<f32>;
|
||||
[[location(2)]] world_position: vec3<f32>;
|
||||
[[location(3)]] highlighted: i32;
|
||||
};
|
||||
|
||||
struct InstanceInput {
|
||||
[[location(5)]] position: vec3<f32>;
|
||||
[[location(6)]] highlighted: i32;
|
||||
};
|
||||
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn main(model: VertexInput, instance: InstanceInput) -> VertexOutput {
|
||||
fn main(model: VertexInput) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.texture_coordinates = model.texture_coordinates;
|
||||
out.world_normal = model.normal;
|
||||
out.world_position = model.position + instance.position;
|
||||
out.world_position = model.position;
|
||||
out.clip_position = uniforms.view_projection * vec4<f32>(out.world_position, 1.0);
|
||||
out.highlighted = instance.highlighted;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -69,9 +61,6 @@ fn main(in: VertexOutput) -> [[location(0)]] vec4<f32> {
|
|||
let specular_color = specular_strength * light.color;
|
||||
|
||||
var result: vec3<f32> = (ambient_color + diffuse_color + specular_color) * object_color.xyz;
|
||||
if (in.highlighted != 0) {
|
||||
result = result + 0.3;
|
||||
}
|
||||
|
||||
return vec4<f32>(result, object_color.a);
|
||||
}
|
||||
|
|
95
src/state.rs
95
src/state.rs
|
@ -1,19 +1,13 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use cgmath::{EuclideanSpace, InnerSpace, Rad};
|
||||
use cgmath::{InnerSpace, Rad};
|
||||
use wgpu::util::{BufferInitDescriptor, DeviceExt};
|
||||
use winit::{
|
||||
event::{DeviceEvent, ElementState, KeyboardInput, VirtualKeyCode},
|
||||
window::Window,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
chunk::{Block, BlockType},
|
||||
cube,
|
||||
texture::Texture,
|
||||
vertex::Vertex,
|
||||
world_state::WorldState,
|
||||
};
|
||||
use crate::{texture::Texture, vertex::Vertex, world_state::WorldState};
|
||||
|
||||
const UI_SCALE_X: f32 = 0.0045;
|
||||
const UI_SCALE_Y: f32 = 0.008;
|
||||
|
@ -387,33 +381,32 @@ impl State {
|
|||
..
|
||||
}) => self.input_keyboard(key, state),
|
||||
|
||||
DeviceEvent::Button {
|
||||
button,
|
||||
state: ElementState::Pressed,
|
||||
} if self.mouse_grabbed => {
|
||||
let camera = &self.world_state.camera;
|
||||
|
||||
// if let Some((pos, axis)) = self
|
||||
// .world_state
|
||||
// .chunk
|
||||
// .raycast(camera.position.to_vec(), camera.direction())
|
||||
// {
|
||||
// if *button == 1 {
|
||||
// self.world_state.chunk.blocks[pos.y][pos.z][pos.x].take();
|
||||
// dbg!(&pos);
|
||||
// self.world_state.update_chunk(&self.render_queue);
|
||||
// } else if *button == 3 {
|
||||
// let new_pos = pos.map(|x| x as i32) - axis;
|
||||
// dbg!(&axis, &new_pos);
|
||||
// self.world_state.chunk.blocks[new_pos.y as usize][new_pos.z as usize]
|
||||
// [new_pos.x as usize] = Some(Block {
|
||||
// block_type: BlockType::Cobblestone,
|
||||
// });
|
||||
// self.world_state.update_chunk(&self.render_queue);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// DeviceEvent::Button {
|
||||
// button,
|
||||
// state: ElementState::Pressed,
|
||||
// } if self.mouse_grabbed => {
|
||||
// let camera = &self.world_state.camera;
|
||||
|
||||
// // if let Some((pos, axis)) = self
|
||||
// // .world_state
|
||||
// // .chunk
|
||||
// // .raycast(camera.position.to_vec(), camera.direction())
|
||||
// // {
|
||||
// // if *button == 1 {
|
||||
// // self.world_state.chunk.blocks[pos.y][pos.z][pos.x].take();
|
||||
// // dbg!(&pos);
|
||||
// // self.world_state.update_chunk(&self.render_queue);
|
||||
// // } else if *button == 3 {
|
||||
// // let new_pos = pos.map(|x| x as i32) - axis;
|
||||
// // dbg!(&axis, &new_pos);
|
||||
// // self.world_state.chunk.blocks[new_pos.y as usize][new_pos.z as usize]
|
||||
// // [new_pos.x as usize] = Some(Block {
|
||||
// // block_type: BlockType::Cobblestone,
|
||||
// // });
|
||||
// // self.world_state.update_chunk(&self.render_queue);
|
||||
// // }
|
||||
// // }
|
||||
// }
|
||||
DeviceEvent::MouseMotion { delta: (dx, dy) } => self.input_mouse(*dx, *dy),
|
||||
_ => (),
|
||||
}
|
||||
|
@ -486,33 +479,16 @@ impl State {
|
|||
render_pass.set_bind_group(1, &self.world_state.uniform_bind_group, &[]);
|
||||
render_pass.set_bind_group(2, &self.world_state.light_bind_group, &[]);
|
||||
|
||||
render_pass.set_index_buffer(
|
||||
self.world_state.index_buffer.slice(..),
|
||||
wgpu::IndexFormat::Uint16,
|
||||
);
|
||||
// Set the texture
|
||||
let texture_bind_group = &self.world_state.texture_bind_group;
|
||||
render_pass.set_bind_group(0, texture_bind_group, &[]);
|
||||
|
||||
for (block_type, offset, instance_list) in &self.world_state.instance_lists {
|
||||
// Set the texture
|
||||
let texture_bind_group = &self.world_state.texture_bind_groups[block_type];
|
||||
render_pass.set_bind_group(0, texture_bind_group, &[]);
|
||||
for (chunk_vertices, chunk_indices, index_count) in &self.world_state.chunk_buffers {
|
||||
render_pass.set_vertex_buffer(0, chunk_vertices.slice(..));
|
||||
render_pass.set_index_buffer(chunk_indices.slice(..), wgpu::IndexFormat::Uint16);
|
||||
|
||||
// Set the vertex buffer
|
||||
let vertex_buffer = match block_type {
|
||||
BlockType::Grass => self.world_state.vertex_buffer_grass.slice(..),
|
||||
_ => self.world_state.vertex_buffer.slice(..),
|
||||
};
|
||||
render_pass.set_vertex_buffer(0, vertex_buffer);
|
||||
|
||||
// Set the instance buffer
|
||||
let instance_buffer = &self.world_state.instance_buffers[&(*block_type, *offset)];
|
||||
render_pass.set_vertex_buffer(1, instance_buffer.slice(..));
|
||||
|
||||
render_pass.draw_indexed(
|
||||
0..cube::INDICES.len() as u32,
|
||||
0,
|
||||
0..instance_list.len() as u32,
|
||||
);
|
||||
triangle_count += cube::INDICES.len() / 3 * instance_list.len();
|
||||
render_pass.draw_indexed(0..*index_count as u32, 0, 0..1);
|
||||
triangle_count += index_count / 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -539,6 +515,7 @@ impl State {
|
|||
|
||||
render_pass.set_bind_group(0, &self.ui_texture_bind_group, &[]);
|
||||
render_pass.draw_indexed(0..CROSSHAIR_INDICES.len() as u32, 0, 0..1);
|
||||
|
||||
triangle_count += CROSSHAIR_INDICES.len() / 3;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ impl Texture {
|
|||
bytes: &[u8],
|
||||
label: &str,
|
||||
) -> anyhow::Result<Self> {
|
||||
println!("decoding image");
|
||||
let image = image::load_from_memory(bytes)?;
|
||||
let rgba = image.into_rgba8();
|
||||
let (width, height) = rgba.dimensions();
|
||||
|
@ -69,6 +70,7 @@ impl Texture {
|
|||
depth_or_array_layers: 1,
|
||||
};
|
||||
|
||||
println!("creating texture");
|
||||
let texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: Some(label),
|
||||
size: texture_size,
|
||||
|
@ -79,6 +81,7 @@ impl Texture {
|
|||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||
});
|
||||
|
||||
println!("writing texture");
|
||||
queue.write_texture(
|
||||
wgpu::ImageCopyTexture {
|
||||
texture: &texture,
|
||||
|
@ -94,13 +97,15 @@ impl Texture {
|
|||
texture_size,
|
||||
);
|
||||
|
||||
println!("creating texture view");
|
||||
let view = texture.create_view(&wgpu::TextureViewDescriptor {
|
||||
label: Some(&format!("texture_view_{}", label)),
|
||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||
array_layer_count: NonZeroU32::new(1),
|
||||
..wgpu::TextureViewDescriptor::default()
|
||||
});
|
||||
|
||||
println!("done");
|
||||
|
||||
Ok(Self {
|
||||
texture,
|
||||
sampler: None,
|
||||
|
|
35
src/world.rs
35
src/world.rs
|
@ -1,23 +1,21 @@
|
|||
use crate::{chunk::Chunk, vertex::Vertex};
|
||||
use cgmath::Vector3;
|
||||
|
||||
use crate::{
|
||||
chunk::{BlockType, Chunk},
|
||||
instance::Instance,
|
||||
};
|
||||
|
||||
pub struct World {
|
||||
chunks: Vec<Vec<Vec<Chunk>>>,
|
||||
}
|
||||
|
||||
const WORLD_SIZE: usize = 16;
|
||||
|
||||
impl World {
|
||||
pub fn generate() -> Self {
|
||||
let mut chunks = Vec::with_capacity(16);
|
||||
for y in 0..16 {
|
||||
let mut chunks_z = Vec::with_capacity(16);
|
||||
for z in 0..16 {
|
||||
let mut chunks_x = Vec::with_capacity(16);
|
||||
for x in 0..16 {
|
||||
let chunk = Chunk::generate(x, y, z);
|
||||
let mut chunks = Vec::with_capacity(WORLD_SIZE);
|
||||
for y in 0..WORLD_SIZE {
|
||||
let mut chunks_z = Vec::with_capacity(WORLD_SIZE);
|
||||
for z in 0..WORLD_SIZE {
|
||||
let mut chunks_x = Vec::with_capacity(WORLD_SIZE);
|
||||
for x in 0..WORLD_SIZE {
|
||||
let chunk = Chunk::generate(x as i32, y as i32, z as i32);
|
||||
chunks_x.push(chunk);
|
||||
}
|
||||
chunks_z.push(chunks_x);
|
||||
|
@ -28,18 +26,15 @@ impl World {
|
|||
Self { chunks }
|
||||
}
|
||||
|
||||
pub fn to_instances(&self) -> Vec<(BlockType, Vector3<i32>, Vec<Instance>)> {
|
||||
pub fn to_instances(&self) -> Vec<(Vec<Vertex>, Vec<u16>)> {
|
||||
let instant = std::time::Instant::now();
|
||||
|
||||
let mut instance_lists = Vec::new();
|
||||
let mut instances = Vec::new();
|
||||
|
||||
for (y, chunks_y) in self.chunks.iter().enumerate() {
|
||||
for (z, chunks_z) in chunks_y.iter().enumerate() {
|
||||
for (x, chunk) in chunks_z.iter().enumerate() {
|
||||
let offset = Vector3::new(x as i32, y as i32, z as i32);
|
||||
for (block_type, instances) in chunk.to_instances(offset) {
|
||||
instance_lists.push((block_type, offset, instances));
|
||||
}
|
||||
let offset = Vector3::new(x as i32 * 16, y as i32 * 16, z as i32 * 16);
|
||||
instances.push(chunk.to_instances(offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +42,6 @@ impl World {
|
|||
let elapsed = instant.elapsed();
|
||||
println!("generating world instances took {:?}", elapsed);
|
||||
|
||||
instance_lists
|
||||
instances
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
use std::{mem::size_of, time::Instant};
|
||||
use std::time::Instant;
|
||||
|
||||
use ahash::AHashMap;
|
||||
use cgmath::{Vector3, Zero};
|
||||
use wgpu::{
|
||||
util::{BufferInitDescriptor, DeviceExt},
|
||||
BufferAddress, BufferDescriptor,
|
||||
};
|
||||
use cgmath::Vector3;
|
||||
use wgpu::util::{BufferInitDescriptor, DeviceExt};
|
||||
use winit::dpi::PhysicalSize;
|
||||
|
||||
use crate::{
|
||||
camera::{Camera, Projection},
|
||||
chunk::{Block, BlockType, Chunk},
|
||||
cube,
|
||||
instance::Instance,
|
||||
light::Light,
|
||||
texture::Texture,
|
||||
uniforms::Uniforms,
|
||||
|
@ -25,24 +18,21 @@ pub struct WorldState {
|
|||
pub uniforms: Uniforms,
|
||||
pub uniform_buffer: wgpu::Buffer,
|
||||
pub uniform_bind_group: wgpu::BindGroup,
|
||||
pub texture_bind_groups: AHashMap<BlockType, wgpu::BindGroup>,
|
||||
pub texture_bind_group: wgpu::BindGroup,
|
||||
pub camera: Camera,
|
||||
pub projection: Projection,
|
||||
pub instance_lists: Vec<(BlockType, Vector3<i32>, Vec<Instance>)>,
|
||||
pub vertex_buffer: wgpu::Buffer,
|
||||
pub vertex_buffer_grass: wgpu::Buffer,
|
||||
pub index_buffer: wgpu::Buffer,
|
||||
pub instance_buffers: AHashMap<(BlockType, Vector3<i32>), wgpu::Buffer>,
|
||||
pub depth_texture: Texture,
|
||||
pub light_bind_group: wgpu::BindGroup,
|
||||
pub world: World,
|
||||
|
||||
pub chunk_buffers: Vec<(wgpu::Buffer, wgpu::Buffer, usize)>,
|
||||
}
|
||||
|
||||
impl WorldState {
|
||||
fn create_textures(
|
||||
render_device: &wgpu::Device,
|
||||
render_queue: &wgpu::Queue,
|
||||
) -> (wgpu::BindGroupLayout, AHashMap<BlockType, wgpu::BindGroup>) {
|
||||
) -> (wgpu::BindGroupLayout, wgpu::BindGroup) {
|
||||
let sampler = render_device.create_sampler(&wgpu::SamplerDescriptor::default());
|
||||
|
||||
let bind_group_layout =
|
||||
|
@ -71,39 +61,32 @@ impl WorldState {
|
|||
],
|
||||
});
|
||||
|
||||
let bind_groups: AHashMap<BlockType, wgpu::BindGroup> = [
|
||||
(BlockType::Cobblestone, "assets/block/cobblestone.png"),
|
||||
(BlockType::Dirt, "assets/block/dirt.png"),
|
||||
(BlockType::Grass, "assets/block_temp/grass.png"),
|
||||
(BlockType::Stone, "assets/block/stone.png"),
|
||||
]
|
||||
.iter()
|
||||
.map(|(block_type, texture_path)| {
|
||||
let bytes = std::fs::read(texture_path).unwrap();
|
||||
let texture =
|
||||
Texture::from_bytes(render_device, render_queue, &bytes, "block texture").unwrap();
|
||||
let instant = std::time::Instant::now();
|
||||
let texture = Texture::from_bytes(
|
||||
render_device,
|
||||
render_queue,
|
||||
include_bytes!("../assets/atlas.png"),
|
||||
"Block texture atlas",
|
||||
)
|
||||
.unwrap();
|
||||
println!("loading block texture atlas took {:?}", instant.elapsed());
|
||||
|
||||
(
|
||||
*block_type,
|
||||
render_device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("block texture bind group"),
|
||||
layout: &bind_group_layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Sampler(&sampler),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::TextureView(&texture.view),
|
||||
},
|
||||
],
|
||||
}),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
let bind_group = render_device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("Block texture atlas bind group"),
|
||||
layout: &bind_group_layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Sampler(&sampler),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::TextureView(&texture.view),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
(bind_group_layout, bind_groups)
|
||||
(bind_group_layout, bind_group)
|
||||
}
|
||||
|
||||
fn create_camera(swap_chain_descriptor: &wgpu::SwapChainDescriptor) -> (Camera, Projection) {
|
||||
|
@ -249,7 +232,7 @@ impl WorldState {
|
|||
vertex: wgpu::VertexState {
|
||||
module: &shader,
|
||||
entry_point: "main",
|
||||
buffers: &[Vertex::desc(), Instance::desc()],
|
||||
buffers: &[Vertex::desc()],
|
||||
},
|
||||
fragment: Some(wgpu::FragmentState {
|
||||
module: &shader,
|
||||
|
@ -267,11 +250,7 @@ impl WorldState {
|
|||
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
strip_index_format: None,
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: if wireframe {
|
||||
None
|
||||
} else {
|
||||
Some(wgpu::Face::Back)
|
||||
},
|
||||
cull_mode: Some(wgpu::Face::Back),
|
||||
polygon_mode: if wireframe {
|
||||
wgpu::PolygonMode::Line
|
||||
} else {
|
||||
|
@ -295,47 +274,29 @@ impl WorldState {
|
|||
})
|
||||
}
|
||||
|
||||
fn create_instances(
|
||||
render_device: &wgpu::Device,
|
||||
world: &World,
|
||||
) -> (
|
||||
Vec<(BlockType, Vector3<i32>, Vec<Instance>)>,
|
||||
AHashMap<(BlockType, Vector3<i32>), wgpu::Buffer>,
|
||||
) {
|
||||
let instance_lists = world.to_instances();
|
||||
|
||||
let instance_buffers = instance_lists
|
||||
.iter()
|
||||
.map(|(block_type, offset, _)| {
|
||||
let buffer = render_device.create_buffer(&BufferDescriptor {
|
||||
label: Some("instance_buffer"),
|
||||
size: (size_of::<Instance>() * 16 * 16 * 16) as BufferAddress,
|
||||
usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
((*block_type, *offset), buffer)
|
||||
})
|
||||
.collect();
|
||||
|
||||
(instance_lists, instance_buffers)
|
||||
}
|
||||
|
||||
pub fn update_chunk(&mut self, render_queue: &wgpu::Queue) {
|
||||
pub fn update_chunk(&mut self, render_device: &wgpu::Device) {
|
||||
let instant = Instant::now();
|
||||
|
||||
self.instance_lists = self.world.to_instances();
|
||||
|
||||
for (block_type, offset, instance_list) in &self.instance_lists {
|
||||
if let Some(instance_buffer) = self.instance_buffers.get_mut(&(*block_type, *offset)) {
|
||||
render_queue.write_buffer(instance_buffer, 0, bytemuck::cast_slice(&instance_list));
|
||||
} else {
|
||||
todo!();
|
||||
}
|
||||
let world_geometry = self.world.to_instances();
|
||||
self.chunk_buffers.clear();
|
||||
for (chunk_vertices, chunk_indices) in world_geometry {
|
||||
self.chunk_buffers.push((
|
||||
render_device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: &bytemuck::cast_slice(&chunk_vertices),
|
||||
usage: wgpu::BufferUsage::VERTEX,
|
||||
}),
|
||||
render_device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: &bytemuck::cast_slice(&chunk_indices),
|
||||
usage: wgpu::BufferUsage::INDEX,
|
||||
}),
|
||||
chunk_indices.len(),
|
||||
));
|
||||
}
|
||||
|
||||
let elapsed = instant.elapsed();
|
||||
println!("Chunk update took {:?}", elapsed);
|
||||
println!("World update took {:?}", elapsed);
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
|
@ -343,10 +304,9 @@ impl WorldState {
|
|||
render_queue: &wgpu::Queue,
|
||||
swap_chain_descriptor: &wgpu::SwapChainDescriptor,
|
||||
) -> WorldState {
|
||||
// let chunk = Chunk::generate(0, 0, 0);
|
||||
let world = World::generate();
|
||||
|
||||
let (world_texture_layout, texture_bind_groups) =
|
||||
let (world_texture_layout, texture_bind_group) =
|
||||
Self::create_textures(&render_device, &render_queue);
|
||||
|
||||
let (camera, projection) = Self::create_camera(&swap_chain_descriptor);
|
||||
|
@ -366,25 +326,6 @@ impl WorldState {
|
|||
],
|
||||
);
|
||||
|
||||
let vertex_buffer = render_device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: Some("vertex_buffer"),
|
||||
contents: bytemuck::cast_slice(cube::VERTICES),
|
||||
usage: wgpu::BufferUsage::VERTEX,
|
||||
});
|
||||
let grass_vertex_buffer = render_device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: Some("grass vertex buffer"),
|
||||
contents: bytemuck::cast_slice(cube::VERTICES_GRASS),
|
||||
usage: wgpu::BufferUsage::VERTEX,
|
||||
});
|
||||
|
||||
let index_buffer = render_device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: Some("index_buffer"),
|
||||
contents: bytemuck::cast_slice(cube::INDICES),
|
||||
usage: wgpu::BufferUsage::INDEX,
|
||||
});
|
||||
|
||||
let (instance_lists, instance_buffers) = Self::create_instances(&render_device, &world);
|
||||
|
||||
let depth_texture =
|
||||
Texture::create_depth_texture(&render_device, &swap_chain_descriptor, "depth_texture");
|
||||
|
||||
|
@ -393,20 +334,16 @@ impl WorldState {
|
|||
uniforms,
|
||||
uniform_buffer,
|
||||
uniform_bind_group,
|
||||
texture_bind_groups,
|
||||
texture_bind_group,
|
||||
camera,
|
||||
projection,
|
||||
instance_lists,
|
||||
vertex_buffer,
|
||||
vertex_buffer_grass: grass_vertex_buffer,
|
||||
index_buffer,
|
||||
instance_buffers,
|
||||
depth_texture,
|
||||
light_bind_group,
|
||||
world,
|
||||
chunk_buffers: Vec::new(),
|
||||
};
|
||||
|
||||
world_state.update_chunk(&render_queue);
|
||||
world_state.update_chunk(render_device);
|
||||
|
||||
world_state
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue