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,
}
}
}