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