1use crate::data_structures::texture::{self, Texture};
2
3#[repr(C)]
4#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
5pub struct Vertex {
6 pub position: [f32; 3],
7 pub tex_coords: [f32; 2],
8}
9
10impl Vertex {
11 pub fn desc() -> wgpu::VertexBufferLayout<'static> {
12 use std::mem;
13 wgpu::VertexBufferLayout {
14 array_stride: mem::size_of::<Vertex>() as wgpu::BufferAddress,
15 step_mode: wgpu::VertexStepMode::Vertex,
16 attributes: &[
17 wgpu::VertexAttribute {
18 offset: 0,
19 shader_location: 0,
20 format: wgpu::VertexFormat::Float32x3,
21 },
22 wgpu::VertexAttribute {
23 offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
24 shader_location: 1,
25 format: wgpu::VertexFormat::Float32x2,
26 },
27 ],
28 }
29 }
30}
31
32#[allow(dead_code)]
33fn mk_shader(device: &wgpu::Device) -> wgpu::ShaderModule {
34 device.create_shader_module(wgpu::ShaderModuleDescriptor {
35 label: Some("Shader"),
36 source: wgpu::ShaderSource::Wgsl(include_str!("icon.wgsl").into()),
37 })
38}
39
40#[allow(dead_code)]
41fn mk_bind_group_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
42 device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
43 entries: &[
44 wgpu::BindGroupLayoutEntry {
45 binding: 0,
46 visibility: wgpu::ShaderStages::FRAGMENT,
47 ty: wgpu::BindingType::Texture {
48 multisampled: false,
49 view_dimension: wgpu::TextureViewDimension::D2,
50 sample_type: wgpu::TextureSampleType::Float { filterable: true },
51 },
52 count: None,
53 },
54 wgpu::BindGroupLayoutEntry {
55 binding: 1,
56 visibility: wgpu::ShaderStages::FRAGMENT,
57 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
58 count: None,
59 },
60 ],
61 label: Some("Menu texture_bind_group_layout"),
62 })
63}
64
65#[allow(dead_code)]
70fn mk_bind_group(
71 device: &wgpu::Device,
72 texture_atlas: Texture,
73 texture_bind_group_layout: &wgpu::BindGroupLayout,
74) -> wgpu::BindGroup {
75 device.create_bind_group(&wgpu::BindGroupDescriptor {
76 layout: texture_bind_group_layout,
77 entries: &[
78 wgpu::BindGroupEntry {
79 binding: 0,
80 resource: wgpu::BindingResource::TextureView(&texture_atlas.view),
81 },
82 wgpu::BindGroupEntry {
83 binding: 1,
84 resource: wgpu::BindingResource::Sampler(&texture_atlas.sampler.unwrap()),
85 },
86 ],
87 label: Some("diffuse_bind_group"),
88 })
89}
90
91fn mk_pipeline_layout(
92 device: &wgpu::Device,
93 texture_bind_group_layout: wgpu::BindGroupLayout,
94) -> wgpu::PipelineLayout {
95 device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
96 label: Some("Menu Render Pipeline Layout"),
97 bind_group_layouts: &[&texture_bind_group_layout],
98 push_constant_ranges: &[],
99 })
100}
101
102fn mk_texture_bind_group_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
103 device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
104 entries: &[
105 wgpu::BindGroupLayoutEntry {
106 binding: 0,
107 visibility: wgpu::ShaderStages::FRAGMENT,
108 ty: wgpu::BindingType::Texture {
109 multisampled: false,
110 view_dimension: wgpu::TextureViewDimension::D2,
111 sample_type: wgpu::TextureSampleType::Float { filterable: true },
112 },
113 count: None,
114 },
115 wgpu::BindGroupLayoutEntry {
116 binding: 1,
117 visibility: wgpu::ShaderStages::FRAGMENT,
118 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
119 count: None,
120 },
121 ],
122 label: Some("Menu texture_bind_group_layout"),
123 })
124}
125
126fn mk_render_pipeline(
127 device: &wgpu::Device,
128 config: &wgpu::SurfaceConfiguration,
129 render_pipeline_layout: &wgpu::PipelineLayout,
130 shader: &wgpu::ShaderModule,
131) -> wgpu::RenderPipeline {
132 device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
133 label: Some("Menu Render Pipeline"),
134 layout: Some(&render_pipeline_layout),
135 vertex: wgpu::VertexState {
136 module: shader,
137 entry_point: Some("vs_main"),
138 buffers: &[Vertex::desc()],
139 compilation_options: Default::default(),
140 },
141 fragment: Some(wgpu::FragmentState {
142 module: shader,
143 entry_point: Some("fs_main"),
144 targets: &[Some(wgpu::ColorTargetState {
145 format: config.format,
146 blend: Some(wgpu::BlendState {
147 color: wgpu::BlendComponent::OVER,
148 alpha: wgpu::BlendComponent::OVER,
149 }),
150 write_mask: wgpu::ColorWrites::ALL,
151 })],
152 compilation_options: Default::default(),
153 }),
154 primitive: wgpu::PrimitiveState {
155 topology: wgpu::PrimitiveTopology::TriangleList,
156 strip_index_format: None,
157 front_face: wgpu::FrontFace::Ccw,
158 cull_mode: Some(wgpu::Face::Back),
159 polygon_mode: wgpu::PolygonMode::Fill,
160 unclipped_depth: false,
161 conservative: false,
162 },
163 depth_stencil: Some(wgpu::DepthStencilState {
164 format: texture::Texture::DEPTH_FORMAT,
165 depth_write_enabled: true,
166 depth_compare: wgpu::CompareFunction::Less,
167 stencil: wgpu::StencilState::default(),
168 bias: wgpu::DepthBiasState::default(),
169 }),
170 multisample: wgpu::MultisampleState {
171 count: 1,
172 mask: !0,
173 alpha_to_coverage_enabled: false,
174 },
175 multiview: None,
176 cache: None,
178 })
179}
180
181pub fn mk_gui_pipeline(device: &wgpu::Device, config: &wgpu::SurfaceConfiguration) -> wgpu::RenderPipeline {
182 let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
183 label: Some("Shader"),
184 source: wgpu::ShaderSource::Wgsl(include_str!("icon.wgsl").into()),
185 });
186 let texture_bind_group_layout = mk_texture_bind_group_layout(device);
187 let render_pipeline_layout = &mk_pipeline_layout(device, texture_bind_group_layout);
188 mk_render_pipeline(device, config, render_pipeline_layout, &shader)
189}