twgpu 0.4.1

Render Teeworlds and DDNet maps
Documentation
use twmap::TilesLayer;
use wgpu::{
    BindGroupDescriptor, BindGroupEntry, BindingResource, Device, RenderBundle,
    RenderBundleDescriptor, RenderBundleEncoderDescriptor, TextureViewDescriptor,
};

use crate::buffer::GpuBuffer;
use crate::map::GpuMapDataStatic;
use crate::textures::Samplers;
use crate::TwRenderPass;

use super::{GpuTilemapData, GpuTilemapStatic, TilemapCorner};

const LABEL: Option<&str> = Some("Tilemap Render");

pub struct GpuTilemapRender {
    pub render_bundle: RenderBundle,
}

impl GpuTilemapStatic {
    pub fn prepare_render(
        &self,
        layer: &TilesLayer,
        data: &GpuTilemapData,
        vertices: &GpuBuffer<[TilemapCorner; 4]>,
        map_data_static: &GpuMapDataStatic,
        samplers: &Samplers,
        device: &Device,
    ) -> GpuTilemapRender {
        let tilemap_view = data.tilemap.create_view(&TextureViewDescriptor::default());
        let bind_group = device.create_bind_group(&BindGroupDescriptor {
            label: LABEL,
            layout: &self.bind_group_layout,
            entries: &[
                BindGroupEntry {
                    binding: 3,
                    resource: BindingResource::TextureView(
                        &map_data_static.textures.view_array_texture(layer.image),
                    ),
                },
                samplers.clamp_to_edge(4),
                BindGroupEntry {
                    binding: 5,
                    resource: BindingResource::TextureView(&tilemap_view),
                },
            ],
        });
        let mut bundle_encoder =
            device.create_render_bundle_encoder(&RenderBundleEncoderDescriptor {
                label: LABEL,
                color_formats: &[Some(self.format)],
                depth_stencil: None,
                sample_count: 1,
                multiview: None,
            });
        bundle_encoder.set_pipeline(&self.pipeline);
        bundle_encoder.set_vertex_buffer(0, vertices.slice());
        bundle_encoder.set_bind_group(0, &bind_group, &[]);
        bundle_encoder.draw(0..4, 0..1);
        let render_bundle = bundle_encoder.finish(&RenderBundleDescriptor { label: LABEL });
        GpuTilemapRender { render_bundle }
    }
}

impl GpuTilemapRender {
    pub fn render<'pass>(&'pass self, render_pass: &mut TwRenderPass<'pass>) {
        render_pass
            .render_pass
            .execute_bundles([&self.render_bundle]);
    }
}