twgpu 0.4.1

Render Teeworlds and DDNet maps
Documentation
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,
            );
        }
    }
}