Fixed starfield tiling

master
Mark 2023-12-24 12:01:38 -08:00
parent babd410182
commit 6f01e7d3bd
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
1 changed files with 16 additions and 10 deletions

View File

@ -48,7 +48,7 @@ impl GPUState {
pub const SPRITE_INSTANCE_LIMIT: u64 = 100;
// Must be small enough to fit in an i32
pub const STARFIELD_INSTANCE_LIMIT: u64 = STARFIELD_COUNT * 9;
pub const STARFIELD_INSTANCE_LIMIT: u64 = STARFIELD_COUNT * 24;
pub async fn new(window: Window) -> Result<Self> {
let window_size = window.inner_size();
@ -264,18 +264,19 @@ impl GPUState {
// Compute window size in starfield tiles
let mut nw_tile: Point2<i32> = {
// Game coordinates (relative to camera) of nw corner of screen.
let clip_nw = Point2::from((self.window_aspect, 1.0)) * ZOOM_MAX / 2.0;
let clip_nw = Point2::from((self.window_aspect, 1.0)) * ZOOM_MAX;
// Adjust for parallax
// Parallax correction.
// Also, adjust v for mod to work properly
// (v is centered at 0)
let v: Point2<f32> = clip_nw * STARFIELD_PARALLAX_MIN;
// We don't need to adjust coordinates here, since clip_nw is always positive.
let v_adj: Point2<f32> = (v.x + (sz / 2.0), v.y + (sz / 2.0)).into();
#[rustfmt::skip]
// Compute m = fmod(x, sz)
let m: Vector2<f32> = (
(v.x - (v.x / sz).floor() * sz),
(v.y - (v.y / sz).floor() * sz)
(v_adj.x - (v_adj.x / sz).floor() * sz) - (sz / 2.0),
(v_adj.y - (v_adj.y / sz).floor() * sz) - (sz / 2.0)
).into();
// Now, remainder and convert to "relative tile" coordinates
@ -286,9 +287,15 @@ impl GPUState {
(rel.x.round() as i32, rel.y.round() as i32).into()
};
// We need to cover the window with stars,
// but we also need a one-wide buffer to account for motion.
nw_tile += Vector2::from((1, 1));
// Truncate tile grid to buffer size
// (The window won't be full of stars if we don't have a large enough instance limit)
while (nw_tile.x * 2 + 1) * (nw_tile.y * 2 + 1) > Self::STARFIELD_INSTANCE_LIMIT as i32 {
// (The window won't be full of stars if our instance limit is too small)
while ((nw_tile.x * 2 + 1) * (nw_tile.y * 2 + 1) * STARFIELD_COUNT as i32)
> Self::STARFIELD_INSTANCE_LIMIT as i32
{
nw_tile -= Vector2::from((1, 1));
}
@ -313,7 +320,6 @@ impl GPUState {
// Enforce starfield limit
if instances.len() as u64 > Self::STARFIELD_INSTANCE_LIMIT {
// TODO: no panic, handle this better.
unreachable!("Starfield limit exceeded!")
}