use super::{group_render::is_gpu_layer, GpuEnvelopesData, GpuGroupData, TilemapCorner};
use crate::{
buffer::{GpuBuffer, GpuDeviceExt},
textures::MapresStorage,
Camera,
};
use twmap::TwMap;
use vek::Vec2;
use wgpu::{Device, Queue};
pub struct GpuMapDataStatic {
pub(crate) textures: MapresStorage,
pub(crate) groups: Vec<GpuGroupData>,
}
pub struct GpuMapDataDyn {
pub(crate) envelopes: GpuEnvelopesData,
pub(crate) tilemap_vertices: Vec<Vec<Option<GpuBuffer<[TilemapCorner; 4]>>>>,
}
impl GpuMapDataStatic {
pub fn upload(map: &TwMap, device: &Device, queue: &Queue) -> Self {
let envelopes = GpuEnvelopesData::upload(map, device);
let groups = map
.groups
.iter()
.map(|group| GpuGroupData::upload(group, &envelopes, &map.images, device, queue))
.collect();
let textures = MapresStorage::upload(map, device, queue);
Self { textures, groups }
}
}
impl GpuMapDataDyn {
pub fn upload(map: &TwMap, device: &Device) -> GpuMapDataDyn {
let envelopes = GpuEnvelopesData::upload(map, device);
let mut tilemap_vertices = Vec::new();
for group in &map.groups {
let mut tilemaps = Vec::new();
for layer in group.layers.iter().filter(is_gpu_layer) {
if let twmap::Layer::Tiles(_) = layer {
tilemaps.push(Some(device.buffer(
&[TilemapCorner::default(); 4],
Some("TilemapCorner"),
wgpu::BufferUsages::VERTEX,
)));
} else {
tilemaps.push(None);
}
}
tilemap_vertices.push(tilemaps);
}
GpuMapDataDyn {
envelopes,
tilemap_vertices,
}
}
pub fn update(
&self,
envelopes: &[twmap::Envelope],
data: &GpuMapDataStatic,
camera: &Camera,
render_target_size: Vec2<u32>,
client_time: i64,
server_time: i64,
queue: &Queue,
) {
self.envelopes
.update(envelopes, client_time, server_time, queue);
for (group, group_data) in self.tilemap_vertices.iter().zip(data.groups.iter()) {
group_data.update(
group,
camera,
render_target_size,
envelopes,
client_time,
server_time,
queue,
);
}
}
}