ascending_graphics/maps/
render.rs1use crate::{
2 AsBufferPass, AtlasSet, GpuRenderer, GraphicsError, InstanceBuffer,
3 MAX_MAPS, Map, MapLayout, MapRaw, MapRenderPipeline, SetBuffers,
4 StaticVertexBuffer, TileVertex, instance_buffer::OrderedIndex,
5};
6use std::{collections::VecDeque, iter, mem};
7use wgpu::util::{DeviceExt, align_to};
8
9#[derive(Debug)]
12pub struct MapRenderer {
13 pub buffer: InstanceBuffer<TileVertex>,
15 pub unused_indexs: VecDeque<usize>,
17 pub(crate) map_buffer: wgpu::Buffer,
19 map_bind_group: wgpu::BindGroup,
21}
22
23impl MapRenderer {
24 pub fn new(
30 renderer: &mut GpuRenderer,
31 map_count: u32,
32 ) -> Result<Self, GraphicsError> {
33 let map_alignment: usize =
34 align_to(mem::size_of::<MapRaw>(), 16) as usize;
35
36 let maps: Vec<u8> =
37 iter::repeat_n(0u8, MAX_MAPS * map_alignment).collect();
38
39 let map_buffer = renderer.device().create_buffer_init(
40 &wgpu::util::BufferInitDescriptor {
41 label: Some("map uniform buffer"),
42 contents: &maps, usage: wgpu::BufferUsages::UNIFORM
44 | wgpu::BufferUsages::COPY_DST,
45 },
46 );
47
48 let layout = renderer.create_layout(MapLayout);
50
51 let map_bind_group =
53 renderer
54 .device()
55 .create_bind_group(&wgpu::BindGroupDescriptor {
56 layout: &layout,
57 entries: &[wgpu::BindGroupEntry {
58 binding: 0,
59 resource: map_buffer.as_entire_binding(),
60 }],
61 label: Some("map_bind_group"),
62 });
63
64 let mut unused_indexs = VecDeque::with_capacity(MAX_MAPS);
65
66 for i in 0..MAX_MAPS {
67 unused_indexs.push_back(i);
68 }
69
70 Ok(Self {
71 buffer: InstanceBuffer::with_capacity(
72 renderer.gpu_device(),
73 9_216 * map_count as usize,
74 ),
75 map_buffer,
76 map_bind_group,
77 unused_indexs,
78 })
79 }
80
81 pub fn add_buffer_store(
89 &mut self,
90 renderer: &GpuRenderer,
91 index: OrderedIndex,
92 buffer_layer: usize,
93 ) {
94 self.buffer.add_buffer_store(renderer, index, buffer_layer);
95 }
96
97 pub fn finalize(&mut self, renderer: &mut GpuRenderer) {
101 self.buffer.finalize(renderer);
102 }
103
104 pub fn update(
113 &mut self,
114 map: &mut Map,
115 renderer: &mut GpuRenderer,
116 atlas: &mut AtlasSet,
117 buffer_layers: [usize; 2],
118 ) {
119 if let Some((bottom, upper)) = map.update(renderer, atlas, self) {
120 self.add_buffer_store(renderer, bottom, buffer_layers[0]);
121 self.add_buffer_store(renderer, upper, buffer_layers[1]);
122 }
123 }
124
125 pub fn bind_group(&self) -> &wgpu::BindGroup {
128 &self.map_bind_group
129 }
130}
131
132pub trait RenderMap<'a, 'b>
134where
135 'b: 'a,
136{
137 fn render_map(
140 &mut self,
141 renderer: &'b GpuRenderer,
142 buffer: &'b MapRenderer,
143 atlas: &'b AtlasSet,
144 buffer_layer: usize,
145 );
146}
147
148impl<'a, 'b> RenderMap<'a, 'b> for wgpu::RenderPass<'a>
149where
150 'b: 'a,
151{
152 fn render_map(
153 &mut self,
154 renderer: &'b GpuRenderer,
155 buffer: &'b MapRenderer,
156 atlas: &'b AtlasSet,
157 buffer_layer: usize,
158 ) {
159 if let Some(Some(details)) = buffer.buffer.buffers.get(buffer_layer)
160 && buffer.buffer.count() > 0
161 {
162 self.set_buffers(renderer.buffer_object.as_buffer_pass());
163 self.set_bind_group(1, atlas.bind_group(), &[]);
164 self.set_bind_group(2, &buffer.map_bind_group, &[]);
165 self.set_vertex_buffer(1, buffer.buffer.instances(None));
166 self.set_pipeline(
167 renderer.get_pipelines(MapRenderPipeline).unwrap(),
168 );
169 self.draw_indexed(
170 0..StaticVertexBuffer::index_count(),
171 0,
172 details.start..details.end,
173 );
174 }
175 }
176}