twgpu 0.4.1

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

use super::super::{GpuGroupData, GpuMapDataStatic, GpuQuadsData, GpuQuadsStatic};
use crate::map::GpuMapDataDyn;
use crate::textures::Samplers;
use crate::{GpuCamera, TwRenderPass};

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

pub struct GpuQuadsRender {
    pub render_bundle: Option<RenderBundle>,
}

impl GpuQuadsStatic {
    pub fn prepare_render(
        &self,
        layer: &QuadsLayer,
        data: &GpuQuadsData,
        group: &GpuGroupData,
        map_data_static: &GpuMapDataStatic,
        map_data_dyn: &GpuMapDataDyn,
        camera: &GpuCamera,
        samplers: &Samplers,
        device: &Device,
    ) -> GpuQuadsRender {
        if layer.quads.len() == 0 {
            return GpuQuadsRender {
                render_bundle: None,
            };
        }
        let bind_group = device.create_bind_group(&BindGroupDescriptor {
            label: LABEL,
            layout: &self.bind_group_layout,
            entries: &[
                camera.bind_group_entry(0),
                BindGroupEntry {
                    binding: 1,
                    resource: BindingResource::TextureView(&map_data_dyn.envelopes.view()),
                },
                group.info_buffer.bind_group_entry(2),
                BindGroupEntry {
                    binding: 3,
                    resource: BindingResource::TextureView(
                        &map_data_static.textures.view_texture(layer.image),
                    ),
                },
                samplers.repeating(4),
            ],
        });
        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, data.vertex_buffer.full_slice());
        bundle_encoder.set_index_buffer(data.index_buffer.full_slice(), IndexFormat::Uint32);
        bundle_encoder.set_bind_group(0, &bind_group, &[]);
        bundle_encoder.draw_indexed(0..data.index_buffer.len() as u32, 0, 0..1);
        let render_bundle = bundle_encoder.finish(&RenderBundleDescriptor { label: LABEL });
        let render_bundle = Some(render_bundle);
        GpuQuadsRender { render_bundle }
    }
}

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