Skip to content

Commit 7816ae5

Browse files
committed
fix: small rework on material/block type loading
1 parent d7a4932 commit 7816ae5

File tree

7 files changed

+143
-125
lines changed

7 files changed

+143
-125
lines changed

src/blocks/block_type.rs

Lines changed: 76 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -9,104 +9,78 @@ pub struct FaceTexture(u32);
99
#[derive(Clone, Copy, Debug)]
1010
pub struct BlockTypeConfigs {
1111
pub id: u32,
12-
// The amount to add to the block id (because some blocks have more than 1 texture)
13-
pub step: u32,
14-
// Different texture for top face
15-
pub top_texture: Option<FaceTexture>,
16-
// Different texture for bottom face
17-
pub bottom_texture: Option<FaceTexture>,
12+
// Integers representing the nth texture to use.
13+
pub textures: [FaceTexture; 3], // 1: Lateral texture, 2: Top texture, 3: Bottom texture
1814
pub is_translucent: bool,
1915
}
2016

17+
impl BlockTypeConfigs {
18+
pub fn get(block_type: BlockType) -> BlockTypeConfigs {
19+
match block_type {
20+
BlockType::Grass => BlockTypeConfigs {
21+
id: 0,
22+
textures: [FaceTexture(6), FaceTexture(7), FaceTexture(8)],
23+
is_translucent: false,
24+
},
25+
BlockType::Dirt => BlockTypeConfigs {
26+
id: 1,
27+
textures: [FaceTexture(0), FaceTexture(0), FaceTexture(0)],
28+
is_translucent: false,
29+
},
30+
31+
BlockType::Water => BlockTypeConfigs {
32+
id: 2,
33+
textures: [FaceTexture(1), FaceTexture(1), FaceTexture(1)],
34+
is_translucent: true,
35+
},
36+
37+
BlockType::Wood => BlockTypeConfigs {
38+
id: 3,
39+
textures: [FaceTexture(4), FaceTexture(5), FaceTexture(5)],
40+
is_translucent: false,
41+
},
42+
BlockType::Leaf => BlockTypeConfigs {
43+
id: 4,
44+
textures: [FaceTexture(2), FaceTexture(2), FaceTexture(2)],
45+
is_translucent: false,
46+
},
47+
BlockType::Stone => BlockTypeConfigs {
48+
id: 5,
49+
textures: [FaceTexture(3), FaceTexture(3), FaceTexture(3)],
50+
is_translucent: false,
51+
},
52+
}
53+
}
54+
}
55+
2156
#[repr(u32)]
22-
#[derive(Clone, Copy, Debug)]
57+
#[derive(Clone, Copy, Debug, PartialEq)]
2358
pub enum BlockType {
24-
Grass(BlockTypeConfigs),
25-
Dirt(BlockTypeConfigs),
26-
Water(BlockTypeConfigs),
27-
Wood(BlockTypeConfigs),
28-
Leaf(BlockTypeConfigs),
29-
Stone(BlockTypeConfigs),
59+
Grass,
60+
Dirt,
61+
Water,
62+
Wood,
63+
Leaf,
64+
Stone,
3065
}
3166
impl BlockType {
67+
pub fn get_config(&self) -> BlockTypeConfigs {
68+
BlockTypeConfigs::get(*self)
69+
}
70+
pub fn to_id(&self) -> u32 {
71+
self.get_config().id
72+
}
3273
pub fn from_id(id: u32) -> BlockType {
3374
match id {
34-
0 => Self::dirt(),
35-
1 => Self::water(),
36-
2 => Self::leaf(),
37-
3 => Self::stone(),
38-
4 => Self::wood(),
39-
5 => Self::grass(),
75+
0 => Self::Grass,
76+
1 => Self::Dirt,
77+
2 => Self::Water,
78+
3 => Self::Wood,
79+
4 => Self::Leaf,
80+
5 => Self::Stone,
4081
_ => panic!("Invalid id"),
4182
}
4283
}
43-
pub fn to_id(&self) -> u32 {
44-
// meh
45-
match self {
46-
Self::Grass(f) => f.id,
47-
Self::Dirt(f) => f.id,
48-
Self::Water(f) => f.id,
49-
Self::Wood(f) => f.id,
50-
Self::Leaf(f) => f.id,
51-
Self::Stone(f) => f.id,
52-
}
53-
}
54-
55-
pub fn dirt() -> Self {
56-
Self::Dirt(BlockTypeConfigs {
57-
id: 0,
58-
step: 0,
59-
bottom_texture: None,
60-
top_texture: None,
61-
is_translucent: false,
62-
})
63-
}
64-
pub fn water() -> Self {
65-
Self::Water(BlockTypeConfigs {
66-
id: 1,
67-
step: 0,
68-
bottom_texture: None,
69-
top_texture: None,
70-
is_translucent: true,
71-
})
72-
}
73-
pub fn leaf() -> Self {
74-
Self::Leaf(BlockTypeConfigs {
75-
id: 2,
76-
step: 0,
77-
bottom_texture: None,
78-
top_texture: None,
79-
is_translucent: false,
80-
})
81-
}
82-
pub fn stone() -> Self {
83-
Self::Stone(BlockTypeConfigs {
84-
id: 3,
85-
step: 0,
86-
bottom_texture: None,
87-
top_texture: None,
88-
is_translucent: false,
89-
})
90-
}
91-
pub fn wood() -> Self {
92-
Self::Wood(BlockTypeConfigs {
93-
id: 4,
94-
step: 0,
95-
bottom_texture: Some(FaceTexture(1)),
96-
top_texture: Some(FaceTexture(1)),
97-
is_translucent: false,
98-
})
99-
}
100-
101-
pub fn grass() -> Self {
102-
Self::Grass(BlockTypeConfigs {
103-
id: 5,
104-
step: 1,
105-
bottom_texture: Some(FaceTexture(2)),
106-
top_texture: Some(FaceTexture(1)),
107-
is_translucent: false,
108-
})
109-
}
11084
}
11185
impl BlockType {
11286
const U_STONE_THRESHOLD: u32 = 20;
@@ -118,59 +92,52 @@ impl BlockType {
11892
let scaler = (y as f32 - Self::U_STONE_THRESHOLD as f32) / 10.0;
11993
let res = t + scaler;
12094
if res > 1.0 {
121-
BlockType::stone()
95+
BlockType::Stone
12296
} else {
123-
BlockType::dirt()
97+
BlockType::Dirt
12498
}
12599
} else if y < Self::L_STONE_THRESHOLD {
126-
BlockType::stone()
100+
BlockType::Stone
127101
} else {
128-
BlockType::dirt()
102+
BlockType::Dirt
129103
}
130104
}
131105
}
132106

133107
const TEXTURE_SIZE: u32 = 256;
134108
const BLOCK_PER_ROW: u32 = 8;
109+
// 32px per block
135110
const BLOCK_OFFSET: u32 = TEXTURE_SIZE / BLOCK_PER_ROW;
136111
const BLOCK_OFFSET_NORMALIZED: f32 = BLOCK_OFFSET as f32 / TEXTURE_SIZE as f32;
137112

138113
fn get_base_coords(config: &BlockTypeConfigs, face_dir: FaceDirections) -> glam::Vec2 {
139114
let face_offset = match face_dir {
140-
FaceDirections::Top => config.top_texture.unwrap_or(FaceTexture(0)),
141-
FaceDirections::Bottom => config.bottom_texture.unwrap_or(FaceTexture(0)),
142-
_ => FaceTexture(0),
115+
FaceDirections::Top => config.textures[1],
116+
FaceDirections::Bottom => config.textures[2],
117+
_ => config.textures[0],
143118
};
119+
let y_offset = (face_offset.0 / BLOCK_PER_ROW) as f32;
120+
let x_offset = (face_offset.0 % BLOCK_PER_ROW) as f32;
144121

145-
let position = config.id + config.step + face_offset.0;
146-
let wrap = position / BLOCK_PER_ROW;
147-
148-
let low_bound = 1.0 - (BLOCK_OFFSET_NORMALIZED + (BLOCK_OFFSET_NORMALIZED * wrap as f32));
149-
let left_bound = (position as f32 % BLOCK_PER_ROW as f32) / BLOCK_PER_ROW as f32;
150-
glam::vec2(left_bound, low_bound)
122+
let low_bound = y_offset * BLOCK_OFFSET_NORMALIZED + BLOCK_OFFSET_NORMALIZED;
123+
let left_bound = x_offset * BLOCK_OFFSET_NORMALIZED;
124+
return glam::vec2(left_bound, low_bound);
151125
}
152126
fn get_tex_coords(config: &BlockTypeConfigs, face_dir: FaceDirections) -> [[f32; 2]; 4] {
153127
let bc = get_base_coords(config, face_dir);
154128
[
155129
[bc.x, bc.y],
156-
[bc.x, bc.y + BLOCK_OFFSET_NORMALIZED],
130+
[bc.x, bc.y - BLOCK_OFFSET_NORMALIZED],
157131
[
158132
bc.x + BLOCK_OFFSET_NORMALIZED,
159-
bc.y + BLOCK_OFFSET_NORMALIZED,
133+
bc.y - BLOCK_OFFSET_NORMALIZED,
160134
],
161135
[bc.x + BLOCK_OFFSET_NORMALIZED, bc.y],
162136
]
163137
}
164138

165139
impl TexturedBlock for BlockType {
166140
fn get_texcoords(&self, face_dir: FaceDirections) -> [[f32; 2]; 4] {
167-
match self {
168-
BlockType::Grass(config) => get_tex_coords(config, face_dir),
169-
BlockType::Dirt(config) => get_tex_coords(config, face_dir),
170-
BlockType::Water(config) => get_tex_coords(config, face_dir),
171-
BlockType::Stone(config) => get_tex_coords(config, face_dir),
172-
BlockType::Wood(config) => get_tex_coords(config, face_dir),
173-
BlockType::Leaf(config) => get_tex_coords(config, face_dir),
174-
}
141+
get_tex_coords(&self.get_config(), face_dir)
175142
}
176143
}

src/chunk.rs

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
use crate::blocks::block_type::BlockType::Water;
12
use crate::persistence::{Loadable, Saveable};
23
use crate::player::Player;
34
use crate::utils::math_utils::Plane;
4-
use crate::world::WorldChunk;
5+
use crate::world::{WorldChunk, WATER_HEIGHT_LEVEL};
56
use crate::{
67
blocks::{
78
block::{Block, BlockVertexData, FaceDirections},
@@ -34,6 +35,8 @@ pub struct Chunk {
3435
pub chunk_position_buffer: wgpu::Buffer,
3536
pub chunk_index_buffer: Option<wgpu::Buffer>,
3637
pub chunk_vertex_buffer: Option<wgpu::Buffer>,
38+
pub chunk_water_vertex_buffer: Option<wgpu::Buffer>,
39+
pub chunk_water_index_buffer: Option<wgpu::Buffer>,
3740
pub outside_blocks: Vec<Arc<RwLock<Block>>>,
3841
pub visible: bool,
3942
}
@@ -68,6 +71,11 @@ impl Chunk {
6871
.expect("Cannot delete oob block");
6972
y_blocks[block_r_position.y as usize] = None;
7073
}
74+
pub fn block_type_at(&self, position: &glam::Vec3) -> Option<BlockType> {
75+
let block = self.get_block_at_relative(position)?;
76+
let block_type = block.read().unwrap().block_type;
77+
Some(block_type.clone())
78+
}
7179
pub fn exists_block_at(&self, position: &glam::Vec3) -> bool {
7280
if let Some(y_blocks) = self
7381
.blocks
@@ -115,6 +123,8 @@ impl Chunk {
115123
}
116124
}
117125
pub fn build_mesh(&self, other_chunks: Vec<WorldChunk>) -> (u32, wgpu::Buffer, wgpu::Buffer) {
126+
let mut water_vertex: Vec<BlockVertexData> = vec![];
127+
let mut water_indices: Vec<u32> = vec![];
118128
let mut vertex: Vec<BlockVertexData> = vec![];
119129
let mut indices: Vec<u32> = vec![];
120130
let mut adjacent_chunks: Vec<((i32, i32), BlockVec)> =
@@ -182,18 +192,37 @@ impl Chunk {
182192
};
183193
}
184194
}
185-
} else if self.exists_block_at(&face_position) {
195+
} else if self.exists_block_at(&face_position)
196+
&& self.block_type_at(&face_position) != Some(BlockType::Water)
197+
{
186198
is_visible = false;
187199
}
188200

189201
if is_visible {
190202
let (mut vertex_data, index_data) =
191203
face.create_face_data(block_ptr.clone(), &adjacent_chunks);
192-
vertex.append(&mut vertex_data);
193-
let indices_offset = vertex.len() as u32 - 4;
194-
indices.append(
195-
&mut index_data.iter().map(|i| i + indices_offset).collect(),
196-
)
204+
match block.block_type {
205+
BlockType::Water => {
206+
water_vertex.append(&mut vertex_data);
207+
let indices_offset = water_vertex.len() as u32 - 4;
208+
water_indices.append(
209+
&mut index_data
210+
.iter()
211+
.map(|i| i + indices_offset)
212+
.collect(),
213+
)
214+
}
215+
_ => {
216+
vertex.append(&mut vertex_data);
217+
let indices_offset = vertex.len() as u32 - 4;
218+
indices.append(
219+
&mut index_data
220+
.iter()
221+
.map(|i| i + indices_offset)
222+
.collect(),
223+
)
224+
}
225+
}
197226
}
198227
}
199228
}
@@ -266,9 +295,11 @@ impl Chunk {
266295
for z in 0..CHUNK_SIZE {
267296
let y_top = Chunk::get_height_value(chunk_x, chunk_y, x, z, noise_data.clone());
268297

298+
let curr = &mut blocks.write().unwrap()[((x * CHUNK_SIZE) + z) as usize];
299+
269300
for y in 0..=y_top {
270301
let block_type = match BlockType::from_y_position(y) {
271-
BlockType::Dirt(..) if y == y_top => BlockType::grass(),
302+
BlockType::Dirt if y == y_top => BlockType::Grass,
272303
b => b,
273304
};
274305

@@ -278,14 +309,34 @@ impl Chunk {
278309
block_type,
279310
)));
280311

281-
let curr = &mut blocks.write().unwrap()[((x * CHUNK_SIZE) + z) as usize];
282312
curr.push(Some(block.clone()));
283313
}
314+
// Make sure the length is at least water level
315+
for y in curr.len()..=(WATER_HEIGHT_LEVEL as usize) {
316+
if let None = curr.get(y) {
317+
curr.push(None);
318+
}
319+
}
320+
321+
for y in 0..=WATER_HEIGHT_LEVEL as usize {
322+
if let Some(entry) = curr.get(y) {
323+
// If there's not a block on this level, place water
324+
if let None = entry {
325+
let block = Arc::new(RwLock::new(Block::new(
326+
glam::vec3(x as f32, y as f32, z as f32),
327+
(chunk_x, chunk_y),
328+
BlockType::Water,
329+
)));
330+
curr[y as usize] = Some(block);
331+
}
332+
}
333+
}
284334
}
285335
}
286336

287337
blocks
288338
}
339+
// TODO: Use white noise + check that the tree is not being placed on water.
289340
pub fn place_trees(&mut self) {
290341
let number_of_trees = rand::random::<f32>();
291342
let number_of_trees = f32::floor(number_of_trees * MAX_TREES_PER_CHUNK as f32) as u32;
@@ -413,6 +464,8 @@ impl Chunk {
413464
});
414465

415466
let mut chunk = Chunk {
467+
chunk_water_index_buffer: None,
468+
chunk_water_vertex_buffer: None,
416469
blocks,
417470
x,
418471
y,

src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
142142
state.update(delta_time.as_secs_f32(), total_time.as_secs_f32());
143143
}
144144
state.draw();
145-
146145
window.lock().unwrap().request_redraw();
147146
}
148147

src/material.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ impl Texture {
124124
let f = std::fs::File::open(path)?;
125125
let reader = std::io::BufReader::new(f);
126126
let image = image::load(reader, image::ImageFormat::Png)?;
127-
let image = image.flipv();
128127
let dimensions = image.dimensions();
129128
let rgba = image.as_rgba8().unwrap();
130129

0 commit comments

Comments
 (0)