twgpu 0.4.1

Render Teeworlds and DDNet maps
Documentation
use wgpu::{
    include_wgsl, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType,
    BlendState, ColorTargetState, ColorWrites, Device, FragmentState, PipelineCompilationOptions,
    PipelineLayoutDescriptor, PrimitiveState, PrimitiveTopology, RenderPipeline,
    RenderPipelineDescriptor, ShaderStages, TextureFormat, TextureSampleType, TextureViewDimension,
    VertexState,
};

use super::tilemap_data::TilemapCorner;
use crate::textures::{Mapres, Samplers};

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

pub struct GpuTilemapStatic {
    pub format: TextureFormat,
    pub bind_group_layout: BindGroupLayout,
    pub pipeline: RenderPipeline,
}

impl GpuTilemapStatic {
    pub fn tilemap_layout_entry(binding: u32) -> BindGroupLayoutEntry {
        BindGroupLayoutEntry {
            binding,
            visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
            ty: BindingType::Texture {
                sample_type: TextureSampleType::Uint,
                view_dimension: TextureViewDimension::D2,
                multisampled: false,
            },
            count: None,
        }
    }

    pub fn new(format: TextureFormat, device: &Device) -> Self {
        let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
            label: LABEL,
            entries: &[
                Mapres::texture_layout_entry(3, TextureViewDimension::D2Array),
                Samplers::bind_group_layout_entry(4),
                Self::tilemap_layout_entry(5),
            ],
        });
        let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
            label: LABEL,
            bind_group_layouts: &[&bind_group_layout],
            push_constant_ranges: &[],
        });
        let shader_module = device.create_shader_module(include_wgsl!("tilemap_shader.wgsl"));
        let vertex_state = VertexState {
            module: &shader_module,
            entry_point: Some("vs_main"),
            compilation_options: PipelineCompilationOptions::default(),
            buffers: &[TilemapCorner::vertex_buffer_layout()],
        };
        let fragment_state = FragmentState {
            module: &shader_module,
            entry_point: Some("fs_main"),
            compilation_options: PipelineCompilationOptions::default(),
            targets: &[Some(ColorTargetState {
                format,
                blend: Some(BlendState::ALPHA_BLENDING),
                write_mask: ColorWrites::all(),
            })],
        };
        let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
            label: LABEL,
            layout: Some(&pipeline_layout),
            vertex: vertex_state,
            primitive: PrimitiveState {
                topology: PrimitiveTopology::TriangleStrip,
                ..PrimitiveState::default()
            },
            depth_stencil: None,
            multisample: Default::default(),
            fragment: Some(fragment_state),
            multiview: None,
            cache: None,
        });
        GpuTilemapStatic {
            format,
            bind_group_layout,
            pipeline,
        }
    }
}