Only generate starfield when necessary
parent
0b3f9fdd9e
commit
6ec95d17a9
|
@ -165,6 +165,8 @@ pub async fn run() -> Result<()> {
|
|||
let mut gpu = GPUState::new(window).await?;
|
||||
let mut game = Game::new();
|
||||
|
||||
gpu.on_new_system(&game);
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
match event {
|
||||
Event::RedrawRequested(window_id) if window_id == gpu.window().id() => {
|
||||
|
|
|
@ -30,6 +30,7 @@ pub struct GPUState {
|
|||
|
||||
sprite_pipeline: wgpu::RenderPipeline,
|
||||
starfield_pipeline: wgpu::RenderPipeline,
|
||||
starfield_count: u32,
|
||||
|
||||
texture_array: TextureArray,
|
||||
global_data: GlobalData,
|
||||
|
@ -179,6 +180,7 @@ impl GPUState {
|
|||
texture_array,
|
||||
global_data,
|
||||
vertex_buffers,
|
||||
starfield_count: 0,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -252,17 +254,28 @@ impl GPUState {
|
|||
/// Will panic if STARFIELD_INSTANCE_LIMIT is exceeded.
|
||||
///
|
||||
/// This is only called inside self.render()
|
||||
fn make_starfield_instances(&self, game: &Game) -> Vec<StarfieldInstance> {
|
||||
let instances: Vec<StarfieldInstance> = game
|
||||
.system
|
||||
.starfield
|
||||
.iter()
|
||||
.map(|s| StarfieldInstance {
|
||||
position: s.pos.into(),
|
||||
parallax: s.parallax,
|
||||
height: s.height,
|
||||
})
|
||||
.collect();
|
||||
fn make_starfield_instances(&mut self, game: &Game) -> Vec<StarfieldInstance> {
|
||||
let mut instances = Vec::new();
|
||||
let sz = STARFIELD_SIZE as f32;
|
||||
for offset in [
|
||||
Vector2 { x: 0.0, y: 0.0 },
|
||||
Vector2 { x: 0.0, y: sz },
|
||||
Vector2 { x: sz, y: sz },
|
||||
Vector2 { x: sz, y: 0.0 },
|
||||
Vector2 { x: sz, y: -sz },
|
||||
Vector2 { x: 0.0, y: -sz },
|
||||
Vector2 { x: -sz, y: -sz },
|
||||
Vector2 { x: -sz, y: 0.0 },
|
||||
Vector2 { x: -sz, y: sz },
|
||||
] {
|
||||
for s in &game.system.starfield {
|
||||
instances.push(StarfieldInstance {
|
||||
position: (s.pos + offset).into(),
|
||||
parallax: s.parallax,
|
||||
height: s.height,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce starfield limit
|
||||
if instances.len() as u64 > Self::STARFIELD_INSTANCE_LIMIT {
|
||||
|
@ -270,9 +283,20 @@ impl GPUState {
|
|||
unreachable!("Starfield limit exceeded!")
|
||||
}
|
||||
|
||||
self.starfield_count = instances.len() as u32;
|
||||
return instances;
|
||||
}
|
||||
|
||||
pub fn on_new_system(&mut self, game: &Game) {
|
||||
// Create starfield instances
|
||||
let starfield_instances = self.make_starfield_instances(game);
|
||||
self.queue.write_buffer(
|
||||
&self.vertex_buffers.starfield.instances,
|
||||
0,
|
||||
bytemuck::cast_slice(&starfield_instances),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn render(&mut self, game: &Game) -> Result<(), wgpu::SurfaceError> {
|
||||
let output = self.surface.get_current_texture()?;
|
||||
let view = output
|
||||
|
@ -328,14 +352,6 @@ impl GPUState {
|
|||
bytemuck::cast_slice(&sprite_instances),
|
||||
);
|
||||
|
||||
// Create starfield instances
|
||||
let starfield_instances = self.make_starfield_instances(game);
|
||||
self.queue.write_buffer(
|
||||
&self.vertex_buffers.starfield.instances,
|
||||
0,
|
||||
bytemuck::cast_slice(&starfield_instances),
|
||||
);
|
||||
|
||||
// These should match the indices in each shader,
|
||||
// and should each have a corresponding bind group layout.
|
||||
render_pass.set_bind_group(0, &self.texture_array.bind_group, &[]);
|
||||
|
@ -344,13 +360,7 @@ impl GPUState {
|
|||
// Starfield pipeline
|
||||
self.vertex_buffers.starfield.set_in_pass(&mut render_pass);
|
||||
render_pass.set_pipeline(&self.starfield_pipeline);
|
||||
|
||||
render_pass.draw(0..1, 0..starfield_instances.len() as _);
|
||||
render_pass.draw_indexed(
|
||||
0..SPRITE_INDICES.len() as u32,
|
||||
0,
|
||||
0..starfield_instances.len() as _,
|
||||
);
|
||||
render_pass.draw_indexed(0..SPRITE_INDICES.len() as u32, 0, 0..self.starfield_count);
|
||||
|
||||
// Sprite pipeline
|
||||
self.vertex_buffers.sprite.set_in_pass(&mut render_pass);
|
||||
|
|
Loading…
Reference in New Issue