Minor cleanup
parent
744533c05c
commit
861c1ce8e6
|
@ -51,6 +51,10 @@ pub const OBJECT_SPRITE_INSTANCE_LIMIT: u64 = 500;
|
||||||
/// We can draw at most this many ui sprites on the screen.
|
/// We can draw at most this many ui sprites on the screen.
|
||||||
pub const UI_SPRITE_INSTANCE_LIMIT: u64 = 100;
|
pub const UI_SPRITE_INSTANCE_LIMIT: u64 = 100;
|
||||||
|
|
||||||
|
/// We can draw at most this many radual bars on the screen.
|
||||||
|
/// This is fairly small, since we know exactly how many of these we'll draw (for now)
|
||||||
|
pub const RADIALBAR_SPRITE_INSTANCE_LIMIT: u64 = 10;
|
||||||
|
|
||||||
/// The size of our circular particle buffer. When we create particles, the oldest ones are replaced.
|
/// The size of our circular particle buffer. When we create particles, the oldest ones are replaced.
|
||||||
pub const PARTICLE_SPRITE_INSTANCE_LIMIT: u64 = 1000;
|
pub const PARTICLE_SPRITE_INSTANCE_LIMIT: u64 = 1000;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
impl GPUState {
|
impl GPUState {
|
||||||
pub(super) fn hud_add_radar(&mut self, state: &RenderState, instances: &mut Vec<UiInstance>) {
|
pub(super) fn hud_add_radar(&mut self, state: &RenderState) {
|
||||||
let radar_range = 4000.0;
|
let radar_range = 4000.0;
|
||||||
let radar_size = 300.0;
|
let radar_size = 300.0;
|
||||||
let hide_range = 0.85;
|
let hide_range = 0.85;
|
||||||
|
@ -26,14 +26,26 @@ impl GPUState {
|
||||||
let ship_sprite = state.content.get_sprite_handle("ui::shipblip");
|
let ship_sprite = state.content.get_sprite_handle("ui::shipblip");
|
||||||
let arrow_sprite = state.content.get_sprite_handle("ui::centerarrow");
|
let arrow_sprite = state.content.get_sprite_handle("ui::centerarrow");
|
||||||
|
|
||||||
instances.push(UiInstance {
|
// Enforce buffer limit
|
||||||
|
if self.vertex_buffers.ui_counter as u64 > galactica_constants::UI_SPRITE_INSTANCE_LIMIT {
|
||||||
|
// TODO: no panic, handle this better.
|
||||||
|
panic!("UI limit exceeded!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push this object's instance
|
||||||
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.ui.instances,
|
||||||
|
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||||
|
bytemuck::cast_slice(&[UiInstance {
|
||||||
anchor: PositionAnchor::NwNw.to_int(),
|
anchor: PositionAnchor::NwNw.to_int(),
|
||||||
position: [10.0, -10.0],
|
position: [10.0, -10.0],
|
||||||
angle: 0.0,
|
angle: 0.0,
|
||||||
size: radar_size,
|
size: radar_size,
|
||||||
color: [1.0, 1.0, 1.0, 1.0],
|
color: [1.0, 1.0, 1.0, 1.0],
|
||||||
sprite_index: state.content.get_sprite_handle("ui::radar").get_index(),
|
sprite_index: state.content.get_sprite_handle("ui::radar").get_index(),
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.ui_counter += 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Draw system objects
|
// Draw system objects
|
||||||
|
@ -95,14 +107,28 @@ impl GPUState {
|
||||||
y: radar_size / -2.0 - 10.0,
|
y: radar_size / -2.0 - 10.0,
|
||||||
} + (d * (radar_size / 2.0));
|
} + (d * (radar_size / 2.0));
|
||||||
|
|
||||||
instances.push(UiInstance {
|
// Enforce buffer limit
|
||||||
|
if self.vertex_buffers.ui_counter as u64
|
||||||
|
> galactica_constants::UI_SPRITE_INSTANCE_LIMIT
|
||||||
|
{
|
||||||
|
// TODO: no panic, handle this better.
|
||||||
|
panic!("UI limit exceeded!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push this object's instance
|
||||||
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.ui.instances,
|
||||||
|
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||||
|
bytemuck::cast_slice(&[UiInstance {
|
||||||
anchor: PositionAnchor::NwC.to_int(),
|
anchor: PositionAnchor::NwC.to_int(),
|
||||||
position: position.into(),
|
position: position.into(),
|
||||||
angle: -Rad::from(angle).0, // TODO: consistent angles
|
angle: -Rad::from(angle).0, // TODO: consistent angles
|
||||||
size,
|
size,
|
||||||
color: f.into(),
|
color: f.into(),
|
||||||
sprite_index: ship_sprite.get_index(),
|
sprite_index: ship_sprite.get_index(),
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.ui_counter += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +144,18 @@ impl GPUState {
|
||||||
let sprite = state.content.get_sprite_handle("ui::radarframe");
|
let sprite = state.content.get_sprite_handle("ui::radarframe");
|
||||||
let size = 7.0f32.min((0.8 - m) * 70.0);
|
let size = 7.0f32.min((0.8 - m) * 70.0);
|
||||||
|
|
||||||
instances.push(UiInstance {
|
// Enforce buffer limit (this section adds four items)
|
||||||
|
if self.vertex_buffers.ui_counter as u64 + 4
|
||||||
|
> galactica_constants::UI_SPRITE_INSTANCE_LIMIT
|
||||||
|
{
|
||||||
|
// TODO: no panic, handle this better.
|
||||||
|
panic!("UI limit exceeded!")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.ui.instances,
|
||||||
|
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||||
|
bytemuck::cast_slice(&[UiInstance {
|
||||||
anchor: PositionAnchor::NwNw.to_int(),
|
anchor: PositionAnchor::NwNw.to_int(),
|
||||||
position: Point2 {
|
position: Point2 {
|
||||||
x: (radar_size / 2.0 + 10.0) - d.x,
|
x: (radar_size / 2.0 + 10.0) - d.x,
|
||||||
|
@ -129,9 +166,14 @@ impl GPUState {
|
||||||
size,
|
size,
|
||||||
color,
|
color,
|
||||||
sprite_index: sprite.get_index(),
|
sprite_index: sprite.get_index(),
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.ui_counter += 1;
|
||||||
|
|
||||||
instances.push(UiInstance {
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.ui.instances,
|
||||||
|
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||||
|
bytemuck::cast_slice(&[UiInstance {
|
||||||
anchor: PositionAnchor::NwSw.to_int(),
|
anchor: PositionAnchor::NwSw.to_int(),
|
||||||
position: Point2 {
|
position: Point2 {
|
||||||
x: (radar_size / 2.0 + 10.0) - d.x,
|
x: (radar_size / 2.0 + 10.0) - d.x,
|
||||||
|
@ -142,9 +184,14 @@ impl GPUState {
|
||||||
size,
|
size,
|
||||||
color,
|
color,
|
||||||
sprite_index: sprite.get_index(),
|
sprite_index: sprite.get_index(),
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.ui_counter += 1;
|
||||||
|
|
||||||
instances.push(UiInstance {
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.ui.instances,
|
||||||
|
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||||
|
bytemuck::cast_slice(&[UiInstance {
|
||||||
anchor: PositionAnchor::NwSe.to_int(),
|
anchor: PositionAnchor::NwSe.to_int(),
|
||||||
position: Point2 {
|
position: Point2 {
|
||||||
x: (radar_size / 2.0 + 10.0) + d.x,
|
x: (radar_size / 2.0 + 10.0) + d.x,
|
||||||
|
@ -155,9 +202,14 @@ impl GPUState {
|
||||||
size,
|
size,
|
||||||
color,
|
color,
|
||||||
sprite_index: sprite.get_index(),
|
sprite_index: sprite.get_index(),
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.ui_counter += 1;
|
||||||
|
|
||||||
instances.push(UiInstance {
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.ui.instances,
|
||||||
|
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||||
|
bytemuck::cast_slice(&[UiInstance {
|
||||||
anchor: PositionAnchor::NwNe.to_int(),
|
anchor: PositionAnchor::NwNe.to_int(),
|
||||||
position: Point2 {
|
position: Point2 {
|
||||||
x: (radar_size / 2.0 + 10.0) + d.x,
|
x: (radar_size / 2.0 + 10.0) + d.x,
|
||||||
|
@ -168,7 +220,9 @@ impl GPUState {
|
||||||
size,
|
size,
|
||||||
color,
|
color,
|
||||||
sprite_index: sprite.get_index(),
|
sprite_index: sprite.get_index(),
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.ui_counter += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arrow to center of system
|
// Arrow to center of system
|
||||||
|
@ -182,31 +236,60 @@ impl GPUState {
|
||||||
y: radar_size / -2.0 - 10.0,
|
y: radar_size / -2.0 - 10.0,
|
||||||
} + ((q.normalize() * 0.865) * (radar_size / 2.0));
|
} + ((q.normalize() * 0.865) * (radar_size / 2.0));
|
||||||
|
|
||||||
instances.push(UiInstance {
|
if self.vertex_buffers.ui_counter as u64 > galactica_constants::UI_SPRITE_INSTANCE_LIMIT
|
||||||
|
{
|
||||||
|
// TODO: no panic, handle this better.
|
||||||
|
panic!("UI limit exceeded!")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.ui.instances,
|
||||||
|
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||||
|
bytemuck::cast_slice(&[UiInstance {
|
||||||
anchor: PositionAnchor::NwC.to_int(),
|
anchor: PositionAnchor::NwC.to_int(),
|
||||||
position: position.into(),
|
position: position.into(),
|
||||||
angle: -player_angle.0,
|
angle: -player_angle.0,
|
||||||
size: 10.0,
|
size: 10.0,
|
||||||
color: [1.0, 1.0, 1.0, 1f32.min((m - 200.0) / 400.0)],
|
color: [1.0, 1.0, 1.0, 1f32.min((m - 200.0) / 400.0)],
|
||||||
sprite_index: arrow_sprite.get_index(),
|
sprite_index: arrow_sprite.get_index(),
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.ui_counter += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn hud_add_status(&mut self, state: &RenderState, instances: &mut Vec<UiInstance>) {
|
pub(super) fn hud_add_status(&mut self, state: &RenderState) {
|
||||||
instances.push(UiInstance {
|
if self.vertex_buffers.ui_counter as u64 > galactica_constants::UI_SPRITE_INSTANCE_LIMIT {
|
||||||
|
// TODO: no panic, handle this better.
|
||||||
|
panic!("UI limit exceeded!")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.ui.instances,
|
||||||
|
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||||
|
bytemuck::cast_slice(&[UiInstance {
|
||||||
anchor: PositionAnchor::NeNe.to_int(),
|
anchor: PositionAnchor::NeNe.to_int(),
|
||||||
position: [-10.0, -10.0],
|
position: [-10.0, -10.0],
|
||||||
angle: 0.0,
|
angle: 0.0,
|
||||||
size: 200.0,
|
size: 200.0,
|
||||||
color: [1.0, 1.0, 1.0, 1.0],
|
color: [1.0, 1.0, 1.0, 1.0],
|
||||||
sprite_index: state.content.get_sprite_handle("ui::status").get_index(),
|
sprite_index: state.content.get_sprite_handle("ui::status").get_index(),
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.ui_counter += 1;
|
||||||
|
|
||||||
|
// We add two items here, so +2
|
||||||
|
if self.vertex_buffers.radialbar_counter as u64 + 2
|
||||||
|
> galactica_constants::RADIALBAR_SPRITE_INSTANCE_LIMIT
|
||||||
|
{
|
||||||
|
// TODO: no panic, handle this better.
|
||||||
|
panic!("Radialbar limit exceeded!")
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: counters for each buffer, remove arrays
|
// TODO: counters for each buffer, remove arrays
|
||||||
self.queue.write_buffer(
|
self.queue.write_buffer(
|
||||||
&self.vertex_buffers.radialbar.instances,
|
&self.vertex_buffers.radialbar.instances,
|
||||||
RadialBarInstance::SIZE * 0,
|
RadialBarInstance::SIZE * self.vertex_buffers.radialbar_counter,
|
||||||
bytemuck::cast_slice(&[RadialBarInstance {
|
bytemuck::cast_slice(&[RadialBarInstance {
|
||||||
position: [-19.0, -19.0],
|
position: [-19.0, -19.0],
|
||||||
anchor: PositionAnchor::NeNe.to_int(),
|
anchor: PositionAnchor::NeNe.to_int(),
|
||||||
|
@ -216,10 +299,11 @@ impl GPUState {
|
||||||
angle: -state.current_time / 2.0,
|
angle: -state.current_time / 2.0,
|
||||||
}]),
|
}]),
|
||||||
);
|
);
|
||||||
|
self.vertex_buffers.radialbar_counter += 1;
|
||||||
|
|
||||||
self.queue.write_buffer(
|
self.queue.write_buffer(
|
||||||
&self.vertex_buffers.radialbar.instances,
|
&self.vertex_buffers.radialbar.instances,
|
||||||
RadialBarInstance::SIZE * 1,
|
RadialBarInstance::SIZE * self.vertex_buffers.radialbar_counter,
|
||||||
bytemuck::cast_slice(&[RadialBarInstance {
|
bytemuck::cast_slice(&[RadialBarInstance {
|
||||||
position: [-27.0, -27.0],
|
position: [-27.0, -27.0],
|
||||||
anchor: PositionAnchor::NeNe.to_int(),
|
anchor: PositionAnchor::NeNe.to_int(),
|
||||||
|
@ -229,5 +313,6 @@ impl GPUState {
|
||||||
angle: state.current_time / 5.0,
|
angle: state.current_time / 5.0,
|
||||||
}]),
|
}]),
|
||||||
);
|
);
|
||||||
|
self.vertex_buffers.radialbar_counter += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use galactica_constants;
|
||||||
|
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use std::{iter, rc::Rc};
|
use std::{iter, rc::Rc};
|
||||||
use wgpu;
|
use wgpu::{self, BufferAddress};
|
||||||
use winit::{self, window::Window};
|
use winit::{self, window::Window};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -58,16 +58,17 @@ pub struct GPUState {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VertexBuffers {
|
struct VertexBuffers {
|
||||||
|
// Keeps track of length of each buffer
|
||||||
|
pub object_counter: BufferAddress,
|
||||||
|
pub ui_counter: BufferAddress,
|
||||||
|
pub particle_counter: BufferAddress,
|
||||||
|
pub radialbar_counter: BufferAddress,
|
||||||
|
|
||||||
object: Rc<VertexBuffer>,
|
object: Rc<VertexBuffer>,
|
||||||
starfield: Rc<VertexBuffer>,
|
starfield: Rc<VertexBuffer>,
|
||||||
ui: Rc<VertexBuffer>,
|
ui: Rc<VertexBuffer>,
|
||||||
|
|
||||||
/// The index of the next particle slot we'll write to.
|
|
||||||
/// This must cycle to 0 whenever it exceeds the size
|
|
||||||
/// of the particle instance array.
|
|
||||||
particle_array_head: u64,
|
|
||||||
particle: Rc<VertexBuffer>,
|
particle: Rc<VertexBuffer>,
|
||||||
|
|
||||||
radialbar: Rc<VertexBuffer>,
|
radialbar: Rc<VertexBuffer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +172,11 @@ impl GPUState {
|
||||||
}
|
}
|
||||||
|
|
||||||
let vertex_buffers = VertexBuffers {
|
let vertex_buffers = VertexBuffers {
|
||||||
|
object_counter: 0,
|
||||||
|
ui_counter: 0,
|
||||||
|
particle_counter: 0,
|
||||||
|
radialbar_counter: 0,
|
||||||
|
|
||||||
object: Rc::new(VertexBuffer::new::<TexturedVertex, ObjectInstance>(
|
object: Rc::new(VertexBuffer::new::<TexturedVertex, ObjectInstance>(
|
||||||
"object",
|
"object",
|
||||||
&device,
|
&device,
|
||||||
|
@ -195,7 +201,6 @@ impl GPUState {
|
||||||
galactica_constants::UI_SPRITE_INSTANCE_LIMIT,
|
galactica_constants::UI_SPRITE_INSTANCE_LIMIT,
|
||||||
)),
|
)),
|
||||||
|
|
||||||
particle_array_head: 0,
|
|
||||||
particle: Rc::new(VertexBuffer::new::<TexturedVertex, ParticleInstance>(
|
particle: Rc::new(VertexBuffer::new::<TexturedVertex, ParticleInstance>(
|
||||||
"particle",
|
"particle",
|
||||||
&device,
|
&device,
|
||||||
|
@ -345,55 +350,30 @@ impl GPUState {
|
||||||
self.update_starfield_buffer()
|
self.update_starfield_buffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make an instance for all the game's sprites
|
/// Entrypoint for all vertex buffer builders
|
||||||
/// (Objects and UI)
|
pub(super) fn update_all_buffers(&mut self, state: &RenderState) {
|
||||||
/// This will Will panic if any X_SPRITE_INSTANCE_LIMIT is exceeded.
|
|
||||||
fn update_sprite_instances(&mut self, state: &RenderState) -> (usize, usize) {
|
|
||||||
let mut object_instances: Vec<ObjectInstance> = Vec::new();
|
|
||||||
|
|
||||||
// Game coordinates (relative to camera) of ne and sw corners of screen.
|
// Game coordinates (relative to camera) of ne and sw corners of screen.
|
||||||
// Used to skip off-screen sprites.
|
// Used to skip off-screen sprites.
|
||||||
let clip_ne = Point2::from((-self.window_aspect, 1.0)) * state.camera_zoom;
|
let clip_ne = Point2::from((-self.window_aspect, 1.0)) * state.camera_zoom;
|
||||||
let clip_sw = Point2::from((self.window_aspect, -1.0)) * state.camera_zoom;
|
let clip_sw = Point2::from((self.window_aspect, -1.0)) * state.camera_zoom;
|
||||||
|
|
||||||
// TODO:sort. Order matters.
|
// TODO: sorting. We don't need to sort ships, but we do need to sort system objects by z-level
|
||||||
|
// (which we don't yet draw)
|
||||||
|
// that should probably be done in iter_system().
|
||||||
|
|
||||||
|
// Order matters, it determines what is drawn on top.
|
||||||
|
// The order inside ships and projectiles doesn't matter,
|
||||||
|
// but ships should always be under projectiles.
|
||||||
for s in state.world.iter_ships() {
|
for s in state.world.iter_ships() {
|
||||||
self.world_push_ship(state, (clip_ne, clip_sw), &s, &mut object_instances);
|
self.world_push_ship(state, (clip_ne, clip_sw), &s);
|
||||||
}
|
}
|
||||||
|
|
||||||
for p in state.world.iter_projectiles() {
|
for p in state.world.iter_projectiles() {
|
||||||
self.world_push_projectile(state, (clip_ne, clip_sw), &p, &mut object_instances);
|
self.world_push_projectile(state, (clip_ne, clip_sw), &p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce sprite limit
|
self.hud_add_radar(state);
|
||||||
if object_instances.len() as u64 > galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT {
|
self.hud_add_status(state);
|
||||||
// TODO: no panic, handle this better.
|
|
||||||
panic!("Sprite limit exceeded!")
|
|
||||||
}
|
|
||||||
|
|
||||||
self.queue.write_buffer(
|
|
||||||
&self.vertex_buffers.object.instances,
|
|
||||||
0,
|
|
||||||
bytemuck::cast_slice(&object_instances),
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO: we don't need an array, just use a counter
|
|
||||||
let mut ui_instances: Vec<UiInstance> = Vec::new();
|
|
||||||
|
|
||||||
self.hud_add_radar(state, &mut ui_instances);
|
|
||||||
self.hud_add_status(state, &mut ui_instances);
|
|
||||||
|
|
||||||
if ui_instances.len() as u64 > galactica_constants::UI_SPRITE_INSTANCE_LIMIT {
|
|
||||||
panic!("Ui sprite limit exceeded!")
|
|
||||||
}
|
|
||||||
|
|
||||||
self.queue.write_buffer(
|
|
||||||
&self.vertex_buffers.ui.instances,
|
|
||||||
0,
|
|
||||||
bytemuck::cast_slice(&ui_instances),
|
|
||||||
);
|
|
||||||
|
|
||||||
return (object_instances.len(), ui_instances.len());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a StarfieldInstance for each star that needs to be drawn.
|
/// Make a StarfieldInstance for each star that needs to be drawn.
|
||||||
|
@ -457,6 +437,11 @@ impl GPUState {
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.vertex_buffers.object_counter = 0;
|
||||||
|
self.vertex_buffers.ui_counter = 0;
|
||||||
|
self.vertex_buffers.radialbar_counter = 0;
|
||||||
|
// Don't reset particle counter, it's special
|
||||||
|
|
||||||
let s = state.content.get_starfield_handle();
|
let s = state.content.get_starfield_handle();
|
||||||
|
|
||||||
// Update global values
|
// Update global values
|
||||||
|
@ -488,7 +473,7 @@ impl GPUState {
|
||||||
for i in state.particles.iter() {
|
for i in state.particles.iter() {
|
||||||
self.queue.write_buffer(
|
self.queue.write_buffer(
|
||||||
&self.vertex_buffers.particle.instances,
|
&self.vertex_buffers.particle.instances,
|
||||||
ParticleInstance::SIZE * self.vertex_buffers.particle_array_head,
|
ParticleInstance::SIZE * self.vertex_buffers.particle_counter,
|
||||||
bytemuck::cast_slice(&[ParticleInstance {
|
bytemuck::cast_slice(&[ParticleInstance {
|
||||||
position: [i.pos.x, i.pos.y],
|
position: [i.pos.x, i.pos.y],
|
||||||
velocity: i.velocity.into(),
|
velocity: i.velocity.into(),
|
||||||
|
@ -501,17 +486,17 @@ impl GPUState {
|
||||||
fade: i.fade,
|
fade: i.fade,
|
||||||
}]),
|
}]),
|
||||||
);
|
);
|
||||||
self.vertex_buffers.particle_array_head += 1;
|
self.vertex_buffers.particle_counter += 1;
|
||||||
if self.vertex_buffers.particle_array_head
|
if self.vertex_buffers.particle_counter
|
||||||
== galactica_constants::PARTICLE_SPRITE_INSTANCE_LIMIT
|
== galactica_constants::PARTICLE_SPRITE_INSTANCE_LIMIT
|
||||||
{
|
{
|
||||||
self.vertex_buffers.particle_array_head = 0;
|
self.vertex_buffers.particle_counter = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.particles.clear();
|
state.particles.clear();
|
||||||
|
|
||||||
// Create sprite instances
|
// Create sprite instances
|
||||||
let (n_object, n_ui) = self.update_sprite_instances(&state);
|
self.update_all_buffers(&state);
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -530,7 +515,11 @@ impl GPUState {
|
||||||
// Sprite pipeline
|
// Sprite pipeline
|
||||||
self.vertex_buffers.object.set_in_pass(&mut render_pass);
|
self.vertex_buffers.object.set_in_pass(&mut render_pass);
|
||||||
render_pass.set_pipeline(&self.object_pipeline);
|
render_pass.set_pipeline(&self.object_pipeline);
|
||||||
render_pass.draw_indexed(0..SPRITE_INDICES.len() as u32, 0, 0..n_object as _);
|
render_pass.draw_indexed(
|
||||||
|
0..SPRITE_INDICES.len() as u32,
|
||||||
|
0,
|
||||||
|
0..self.vertex_buffers.object_counter as _,
|
||||||
|
);
|
||||||
|
|
||||||
// Particle pipeline
|
// Particle pipeline
|
||||||
self.vertex_buffers.particle.set_in_pass(&mut render_pass);
|
self.vertex_buffers.particle.set_in_pass(&mut render_pass);
|
||||||
|
@ -544,13 +533,21 @@ impl GPUState {
|
||||||
// Ui pipeline
|
// Ui pipeline
|
||||||
self.vertex_buffers.ui.set_in_pass(&mut render_pass);
|
self.vertex_buffers.ui.set_in_pass(&mut render_pass);
|
||||||
render_pass.set_pipeline(&self.ui_pipeline);
|
render_pass.set_pipeline(&self.ui_pipeline);
|
||||||
render_pass.draw_indexed(0..SPRITE_INDICES.len() as u32, 0, 0..n_ui as _);
|
render_pass.draw_indexed(
|
||||||
|
0..SPRITE_INDICES.len() as u32,
|
||||||
|
0,
|
||||||
|
0..self.vertex_buffers.ui_counter as _,
|
||||||
|
);
|
||||||
|
|
||||||
// Radial progress bars
|
// Radial progress bars
|
||||||
// TODO: do we need to do this every time?
|
// TODO: do we need to do this every time?
|
||||||
self.vertex_buffers.radialbar.set_in_pass(&mut render_pass);
|
self.vertex_buffers.radialbar.set_in_pass(&mut render_pass);
|
||||||
render_pass.set_pipeline(&self.radialbar_pipeline);
|
render_pass.set_pipeline(&self.radialbar_pipeline);
|
||||||
render_pass.draw_indexed(0..SPRITE_INDICES.len() as u32, 0, 0..2);
|
render_pass.draw_indexed(
|
||||||
|
0..SPRITE_INDICES.len() as u32,
|
||||||
|
0,
|
||||||
|
0..self.vertex_buffers.radialbar_counter as _,
|
||||||
|
);
|
||||||
|
|
||||||
// begin_render_pass borrows encoder mutably, so we can't call finish()
|
// begin_render_pass borrows encoder mutably, so we can't call finish()
|
||||||
// without dropping this variable.
|
// without dropping this variable.
|
||||||
|
|
|
@ -8,17 +8,18 @@ use galactica_world::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
globaluniform::ObjectData, vertexbuffer::types::ObjectInstance, GPUState, RenderState,
|
globaluniform::ObjectData,
|
||||||
|
vertexbuffer::{types::ObjectInstance, BufferObject},
|
||||||
|
GPUState, RenderState,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl GPUState {
|
impl GPUState {
|
||||||
pub(super) fn world_push_ship(
|
pub(super) fn world_push_ship(
|
||||||
&self,
|
&mut self,
|
||||||
state: &RenderState,
|
state: &RenderState,
|
||||||
// NE and SW corners of screen
|
// NE and SW corners of screen
|
||||||
screen_clip: (Point2<f32>, Point2<f32>),
|
screen_clip: (Point2<f32>, Point2<f32>),
|
||||||
s: &ShipWorldObject,
|
s: &ShipWorldObject,
|
||||||
instances: &mut Vec<ObjectInstance>,
|
|
||||||
) {
|
) {
|
||||||
let (_, r) = state.world.get_ship_body(s.physics_handle).unwrap();
|
let (_, r) = state.world.get_ship_body(s.physics_handle).unwrap();
|
||||||
let ship_pos = util::rigidbody_position(&r);
|
let ship_pos = util::rigidbody_position(&r);
|
||||||
|
@ -47,7 +48,7 @@ impl GPUState {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let idx = instances.len();
|
let idx = self.vertex_buffers.object_counter;
|
||||||
// Write this object's location data
|
// Write this object's location data
|
||||||
self.queue.write_buffer(
|
self.queue.write_buffer(
|
||||||
&self.global_uniform.object_buffer,
|
&self.global_uniform.object_buffer,
|
||||||
|
@ -64,11 +65,24 @@ impl GPUState {
|
||||||
}]),
|
}]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Enforce buffer limit
|
||||||
|
if self.vertex_buffers.object_counter as u64
|
||||||
|
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
||||||
|
{
|
||||||
|
// TODO: no panic, handle this better.
|
||||||
|
panic!("Sprite limit exceeded!")
|
||||||
|
}
|
||||||
|
|
||||||
// Push this object's instance
|
// Push this object's instance
|
||||||
instances.push(ObjectInstance {
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.object.instances,
|
||||||
|
ObjectInstance::SIZE * self.vertex_buffers.object_counter,
|
||||||
|
bytemuck::cast_slice(&[ObjectInstance {
|
||||||
sprite_index: ship_cnt.sprite.get_index(),
|
sprite_index: ship_cnt.sprite.get_index(),
|
||||||
object_index: idx as u32,
|
object_index: idx as u32,
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.object_counter += 1;
|
||||||
|
|
||||||
// Draw engine flares if necessary
|
// Draw engine flares if necessary
|
||||||
if s.controls.thrust {
|
if s.controls.thrust {
|
||||||
|
@ -80,7 +94,7 @@ impl GPUState {
|
||||||
|
|
||||||
self.queue.write_buffer(
|
self.queue.write_buffer(
|
||||||
&self.global_uniform.object_buffer,
|
&self.global_uniform.object_buffer,
|
||||||
ObjectData::SIZE * instances.len() as u64,
|
ObjectData::SIZE * self.vertex_buffers.object_counter as u64,
|
||||||
bytemuck::cast_slice(&[ObjectData {
|
bytemuck::cast_slice(&[ObjectData {
|
||||||
xpos: f.pos.x,
|
xpos: f.pos.x,
|
||||||
ypos: f.pos.y - f.size / 2.0,
|
ypos: f.pos.y - f.size / 2.0,
|
||||||
|
@ -93,21 +107,33 @@ impl GPUState {
|
||||||
}]),
|
}]),
|
||||||
);
|
);
|
||||||
|
|
||||||
instances.push(ObjectInstance {
|
// Enforce buffer limit
|
||||||
|
if self.vertex_buffers.object_counter as u64
|
||||||
|
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
||||||
|
{
|
||||||
|
// TODO: no panic, handle this better.
|
||||||
|
panic!("Sprite limit exceeded!")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.object.instances,
|
||||||
|
ObjectInstance::SIZE * self.vertex_buffers.object_counter,
|
||||||
|
bytemuck::cast_slice(&[ObjectInstance {
|
||||||
sprite_index: flare.get_index(),
|
sprite_index: flare.get_index(),
|
||||||
object_index: instances.len() as u32,
|
object_index: self.vertex_buffers.object_counter as u32,
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.object_counter += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn world_push_projectile(
|
pub(super) fn world_push_projectile(
|
||||||
&self,
|
&mut self,
|
||||||
state: &RenderState,
|
state: &RenderState,
|
||||||
// NE and SW corners of screen
|
// NE and SW corners of screen
|
||||||
screen_clip: (Point2<f32>, Point2<f32>),
|
screen_clip: (Point2<f32>, Point2<f32>),
|
||||||
p: &ProjectileWorldObject,
|
p: &ProjectileWorldObject,
|
||||||
instances: &mut Vec<ObjectInstance>,
|
|
||||||
) {
|
) {
|
||||||
let r = state.world.get_rigid_body(p.rigid_body).unwrap();
|
let r = state.world.get_rigid_body(p.rigid_body).unwrap();
|
||||||
let proj_pos = util::rigidbody_position(&r);
|
let proj_pos = util::rigidbody_position(&r);
|
||||||
|
@ -136,7 +162,7 @@ impl GPUState {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let idx = instances.len();
|
let idx = self.vertex_buffers.object_counter;
|
||||||
// Write this object's location data
|
// Write this object's location data
|
||||||
self.queue.write_buffer(
|
self.queue.write_buffer(
|
||||||
&self.global_uniform.object_buffer,
|
&self.global_uniform.object_buffer,
|
||||||
|
@ -153,10 +179,23 @@ impl GPUState {
|
||||||
}]),
|
}]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Enforce buffer limit
|
||||||
|
if self.vertex_buffers.object_counter as u64
|
||||||
|
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
||||||
|
{
|
||||||
|
// TODO: no panic, handle this better.
|
||||||
|
panic!("Sprite limit exceeded!")
|
||||||
|
}
|
||||||
|
|
||||||
// Push this object's instance
|
// Push this object's instance
|
||||||
instances.push(ObjectInstance {
|
self.queue.write_buffer(
|
||||||
|
&self.vertex_buffers.object.instances,
|
||||||
|
ObjectInstance::SIZE * self.vertex_buffers.object_counter,
|
||||||
|
bytemuck::cast_slice(&[ObjectInstance {
|
||||||
sprite_index: proj_cnt.sprite.get_index(),
|
sprite_index: proj_cnt.sprite.get_index(),
|
||||||
object_index: idx as u32,
|
object_index: idx as u32,
|
||||||
});
|
}]),
|
||||||
|
);
|
||||||
|
self.vertex_buffers.object_counter += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue