wde_terrain/render/
renderer.rs1use std::collections::HashMap;
2
3use bevy::prelude::*;
4use wde_renderer::prelude::*;
5
6use crate::manager::{CHUNK_COUNT, CHUNK_RENDER_SUBDIVISIONS, ChunkPos, Terrain, TerrainDirtyTile};
7
8#[derive(Component, Reflect)]
12#[reflect(Component)]
13pub struct TerrainRenderer {
14 pub pos_to_layer: HashMap<ChunkPos, u32>,
16 #[reflect(ignore)]
18 pub heightmap_array: Option<Handle<Texture>>,
19 #[reflect(ignore)]
21 pub splatmap_array: Option<Handle<Texture>>,
22 #[reflect(ignore)]
24 pub dirty: Vec<TerrainDirtyTile>
25}
26
27impl TerrainRenderer {
28 pub fn new(asset_server: &AssetServer) -> Self {
30 let layer_count = CHUNK_COUNT * CHUNK_COUNT;
31 let usages = TextureUsages::COPY_SRC
32 | TextureUsages::COPY_DST
33 | TextureUsages::TEXTURE_BINDING
34 | TextureUsages::STORAGE_BINDING;
35
36 let heightmap_array = asset_server.add(Texture {
37 label: "terrain_heightmap_array".to_string(),
38 size: (CHUNK_RENDER_SUBDIVISIONS, CHUNK_RENDER_SUBDIVISIONS),
39 format: TextureFormat::R8Unorm,
40 usages,
41 layer_count,
42 ..Default::default()
43 });
44
45 let splatmap_array = asset_server.add(Texture {
46 label: "terrain_splatmap_array".to_string(),
47 size: (CHUNK_RENDER_SUBDIVISIONS, CHUNK_RENDER_SUBDIVISIONS),
48 format: TextureFormat::Rgba8Unorm,
49 usages,
50 layer_count,
51 ..Default::default()
52 });
53
54 let mut pos_to_layer = HashMap::new();
56 let mut layer = 0u32;
57 for i in 0..CHUNK_COUNT {
58 for j in 0..CHUNK_COUNT {
59 let px = i as i32 - (CHUNK_COUNT as i32) / 2;
60 let pz = j as i32 - (CHUNK_COUNT as i32) / 2;
61 pos_to_layer.insert(IVec2::new(px, pz), layer);
62 layer += 1;
63 }
64 }
65
66 Self {
67 pos_to_layer,
68 heightmap_array: Some(heightmap_array),
69 splatmap_array: Some(splatmap_array),
70 dirty: Vec::new()
71 }
72 }
73
74 pub fn extract_dirty(
76 mut renderer: Query<&mut TerrainRenderer>,
77 mut terrain: Query<&mut Terrain>
78 ) {
79 let (Ok(mut renderer), Ok(mut terrain)) = (renderer.single_mut(), terrain.single_mut())
80 else {
81 return;
82 };
83 renderer.dirty.clear();
84 renderer.dirty.append(&mut terrain.dirty_render);
85 }
86}