Added fps counter
parent
08e9958f2d
commit
be2cca79b0
|
@ -642,20 +642,16 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"cgmath",
|
||||
"galactica-constants",
|
||||
"galactica-content",
|
||||
"galactica-galaxy",
|
||||
"galactica-render",
|
||||
"galactica-systemsim",
|
||||
"galactica-util",
|
||||
"pollster",
|
||||
"wgpu",
|
||||
"winit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "galactica-constants"
|
||||
version = "0.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "galactica-content"
|
||||
version = "0.0.0"
|
||||
|
@ -684,7 +680,7 @@ name = "galactica-packer"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"galactica-constants",
|
||||
"galactica-util",
|
||||
"image",
|
||||
"serde",
|
||||
"toml",
|
||||
|
@ -698,11 +694,11 @@ dependencies = [
|
|||
"anyhow",
|
||||
"bytemuck",
|
||||
"cgmath",
|
||||
"galactica-constants",
|
||||
"galactica-content",
|
||||
"galactica-galaxy",
|
||||
"galactica-packer",
|
||||
"galactica-systemsim",
|
||||
"galactica-util",
|
||||
"glyphon",
|
||||
"image",
|
||||
"rand",
|
||||
|
@ -723,6 +719,10 @@ dependencies = [
|
|||
"rapier2d",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "galactica-util"
|
||||
version = "0.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.11"
|
||||
|
|
|
@ -42,7 +42,7 @@ readme = ""
|
|||
[workspace.lints]
|
||||
|
||||
[workspace.dependencies]
|
||||
galactica-constants = { path = "crates/constants" }
|
||||
galactica-util = { path = "crates/util" }
|
||||
galactica-content = { path = "crates/content" }
|
||||
galactica-render = { path = "crates/render" }
|
||||
galactica-systemsim = { path = "crates/systemsim" }
|
||||
|
|
|
@ -23,7 +23,7 @@ workspace = true
|
|||
[dependencies]
|
||||
galactica-content = { workspace = true }
|
||||
galactica-render = { workspace = true }
|
||||
galactica-constants = { workspace = true }
|
||||
galactica-util = { workspace = true }
|
||||
galactica-systemsim = { workspace = true }
|
||||
galactica-galaxy = { workspace = true }
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use galactica_content::{Content, FactionHandle, OutfitHandle, ShipHandle, SystemHandle};
|
||||
use galactica_galaxy::{ship::ShipPersonality, Galaxy, GxShipHandle};
|
||||
use galactica_util::{
|
||||
constants::{ZOOM_MAX, ZOOM_MIN},
|
||||
timing::Timing,
|
||||
};
|
||||
use std::time::Instant;
|
||||
use winit::event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode};
|
||||
|
||||
use crate::camera::Camera;
|
||||
use crate::inputstatus::InputStatus;
|
||||
|
||||
use galactica_constants;
|
||||
use galactica_render::RenderInput;
|
||||
use galactica_systemsim::{objects::ShipControls, util, ParticleBuilder, StepResources, SystemSim};
|
||||
|
||||
|
@ -24,6 +26,7 @@ pub struct Game {
|
|||
systemsim: SystemSim,
|
||||
|
||||
new_particles: Vec<ParticleBuilder>,
|
||||
timing: Timing,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
|
@ -86,6 +89,7 @@ impl Game {
|
|||
galaxy,
|
||||
content: ct,
|
||||
new_particles: Vec::new(),
|
||||
timing: Timing::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,8 +121,11 @@ impl Game {
|
|||
pub fn update(&mut self) {
|
||||
let t: f32 = self.last_update.elapsed().as_secs_f32() * self.time_scale;
|
||||
|
||||
self.timing.start();
|
||||
self.galaxy.step(t);
|
||||
self.timing.mark_galaxy();
|
||||
|
||||
self.timing.start();
|
||||
self.systemsim.step(StepResources {
|
||||
player: self.player,
|
||||
player_controls: ShipControls {
|
||||
|
@ -132,10 +139,10 @@ impl Game {
|
|||
particles: &mut self.new_particles,
|
||||
t,
|
||||
});
|
||||
self.timing.mark_physics();
|
||||
|
||||
if self.input.v_scroll != 0.0 {
|
||||
self.camera.zoom = (self.camera.zoom + self.input.v_scroll)
|
||||
.clamp(galactica_constants::ZOOM_MIN, galactica_constants::ZOOM_MAX);
|
||||
self.camera.zoom = (self.camera.zoom + self.input.v_scroll).clamp(ZOOM_MIN, ZOOM_MAX);
|
||||
self.input.v_scroll = 0.0;
|
||||
}
|
||||
|
||||
|
@ -159,6 +166,7 @@ impl Game {
|
|||
player_data: self.player,
|
||||
data: &self.galaxy,
|
||||
current_system: SystemHandle { index: 0 },
|
||||
timing: &self.timing,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ mod game;
|
|||
mod inputstatus;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use galactica_constants::{ASSET_CACHE, CONTENT_ROOT, IMAGE_ROOT, STARFIELD_SPRITE_NAME};
|
||||
use galactica_content::Content;
|
||||
use galactica_util::constants::{ASSET_CACHE, CONTENT_ROOT, IMAGE_ROOT, STARFIELD_SPRITE_NAME};
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
|
|
|
@ -21,7 +21,7 @@ readme = { workspace = true }
|
|||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
galactica-constants = { workspace = true }
|
||||
galactica-util = { workspace = true }
|
||||
|
||||
image = { workspace = true }
|
||||
toml = { workspace = true }
|
||||
|
|
|
@ -18,7 +18,7 @@ workspace = true
|
|||
|
||||
[dependencies]
|
||||
galactica-content = { workspace = true }
|
||||
galactica-constants = { workspace = true }
|
||||
galactica-util = { workspace = true }
|
||||
galactica-packer = { workspace = true }
|
||||
galactica-systemsim = { workspace = true }
|
||||
galactica-galaxy = { workspace = true }
|
||||
|
|
|
@ -2,7 +2,8 @@ use cgmath::Point2;
|
|||
use galactica_content::{Content, SystemHandle};
|
||||
use galactica_galaxy::{Galaxy, GxShipHandle};
|
||||
use galactica_systemsim::{ParticleBuilder, SystemSim};
|
||||
use glyphon::{Buffer, FontSystem, SwashCache, TextAtlas, TextRenderer};
|
||||
use galactica_util::timing::Timing;
|
||||
use glyphon::{FontSystem, SwashCache, TextAtlas, TextRenderer};
|
||||
use std::rc::Rc;
|
||||
use wgpu::BufferAddress;
|
||||
use winit::window::Window;
|
||||
|
@ -38,6 +39,9 @@ pub struct RenderInput<'a> {
|
|||
|
||||
/// Particles to spawn during this frame
|
||||
pub particles: &'a mut Vec<ParticleBuilder>,
|
||||
|
||||
/// Time we spent in each part of the game loop
|
||||
pub timing: &'a Timing,
|
||||
}
|
||||
|
||||
/// Renderer state. A reference to this struct is often passed to helper functions.
|
||||
|
@ -54,7 +58,6 @@ pub(crate) struct RenderState {
|
|||
pub text_cache: SwashCache,
|
||||
pub text_atlas: TextAtlas,
|
||||
pub text_renderer: TextRenderer,
|
||||
pub text_buffer: Buffer,
|
||||
}
|
||||
|
||||
/// Vertex buffers
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use bytemuck::{Pod, Zeroable};
|
||||
use galactica_constants::IMAGE_LIMIT;
|
||||
use galactica_util::constants::IMAGE_LIMIT;
|
||||
use std::mem;
|
||||
use wgpu;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use galactica_constants::{IMAGE_LIMIT, OBJECT_SPRITE_INSTANCE_LIMIT, SPRITE_LIMIT};
|
||||
use galactica_util::constants::{IMAGE_LIMIT, OBJECT_SPRITE_INSTANCE_LIMIT, SPRITE_LIMIT};
|
||||
use wgpu;
|
||||
|
||||
use super::{object::ObjectLocationArray, AtlasArray, GlobalDataContent, SpriteDataArray};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use bytemuck::{Pod, Zeroable};
|
||||
use galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT;
|
||||
use galactica_util::constants::OBJECT_SPRITE_INSTANCE_LIMIT;
|
||||
use std::mem;
|
||||
use wgpu;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use bytemuck::{Pod, Zeroable};
|
||||
use galactica_constants::SPRITE_LIMIT;
|
||||
use galactica_util::constants::SPRITE_LIMIT;
|
||||
use std::mem;
|
||||
use wgpu;
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use anyhow::Result;
|
||||
use galactica_content::Content;
|
||||
use glyphon::{
|
||||
Attrs, Buffer, Family, FontSystem, Metrics, Shaping, SwashCache, TextAtlas, TextRenderer,
|
||||
use galactica_util::constants::{
|
||||
OBJECT_SPRITE_INSTANCE_LIMIT, PARTICLE_SPRITE_INSTANCE_LIMIT, STARFIELD_SPRITE_INSTANCE_LIMIT,
|
||||
UI_SPRITE_INSTANCE_LIMIT,
|
||||
};
|
||||
use glyphon::{FontSystem, SwashCache, TextAtlas, TextRenderer};
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{
|
||||
|
@ -100,7 +102,7 @@ impl GPUState {
|
|||
&device,
|
||||
Some(SPRITE_VERTICES),
|
||||
Some(SPRITE_INDICES),
|
||||
galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT,
|
||||
OBJECT_SPRITE_INSTANCE_LIMIT,
|
||||
)),
|
||||
|
||||
starfield: Rc::new(VertexBuffer::new::<TexturedVertex, StarfieldInstance>(
|
||||
|
@ -108,7 +110,7 @@ impl GPUState {
|
|||
&device,
|
||||
Some(SPRITE_VERTICES),
|
||||
Some(SPRITE_INDICES),
|
||||
galactica_constants::STARFIELD_SPRITE_INSTANCE_LIMIT,
|
||||
STARFIELD_SPRITE_INSTANCE_LIMIT,
|
||||
)),
|
||||
|
||||
ui: Rc::new(VertexBuffer::new::<TexturedVertex, UiInstance>(
|
||||
|
@ -116,7 +118,7 @@ impl GPUState {
|
|||
&device,
|
||||
Some(SPRITE_VERTICES),
|
||||
Some(SPRITE_INDICES),
|
||||
galactica_constants::UI_SPRITE_INSTANCE_LIMIT,
|
||||
UI_SPRITE_INSTANCE_LIMIT,
|
||||
)),
|
||||
|
||||
particle: Rc::new(VertexBuffer::new::<TexturedVertex, ParticleInstance>(
|
||||
|
@ -124,7 +126,7 @@ impl GPUState {
|
|||
&device,
|
||||
Some(SPRITE_VERTICES),
|
||||
Some(SPRITE_INDICES),
|
||||
galactica_constants::PARTICLE_SPRITE_INSTANCE_LIMIT,
|
||||
PARTICLE_SPRITE_INSTANCE_LIMIT,
|
||||
)),
|
||||
|
||||
radialbar: Rc::new(VertexBuffer::new::<TexturedVertex, RadialBarInstance>(
|
||||
|
@ -148,7 +150,7 @@ impl GPUState {
|
|||
|
||||
// Text renderer
|
||||
let mut text_atlas = TextAtlas::new(&device, &queue, wgpu::TextureFormat::Bgra8UnormSrgb);
|
||||
let mut text_font_system = FontSystem::new();
|
||||
let text_font_system = FontSystem::new();
|
||||
|
||||
let text_cache = SwashCache::new();
|
||||
let text_renderer = TextRenderer::new(
|
||||
|
@ -157,18 +159,6 @@ impl GPUState {
|
|||
wgpu::MultisampleState::default(),
|
||||
None,
|
||||
);
|
||||
let text_buffer = {
|
||||
let mut buffer = Buffer::new(&mut text_font_system, Metrics::new(30.0, 42.0));
|
||||
|
||||
buffer.set_size(
|
||||
&mut text_font_system,
|
||||
window_size.width as f32,
|
||||
window_size.height as f32,
|
||||
);
|
||||
buffer.set_text(&mut text_font_system, "Hello world! 👋\nThis is rendered with 🦅 glyphon 🦁\nThe text below should be partially clipped.\na b c d e f g h i j k l m n o p q r s t u v w x y z", Attrs::new().family(Family::SansSerif), Shaping::Advanced);
|
||||
buffer.shape_until_scroll(&mut text_font_system);
|
||||
buffer
|
||||
};
|
||||
|
||||
// Create render pipelines
|
||||
let object_pipeline = PipelineBuilder::new("object", &device)
|
||||
|
@ -250,8 +240,7 @@ impl GPUState {
|
|||
let mut starfield = Starfield::new();
|
||||
starfield.regenerate();
|
||||
|
||||
return Ok(Self {
|
||||
state: RenderState {
|
||||
let mut state = RenderState {
|
||||
queue,
|
||||
|
||||
window,
|
||||
|
@ -262,13 +251,13 @@ impl GPUState {
|
|||
vertex_buffers,
|
||||
|
||||
text_atlas,
|
||||
text_buffer,
|
||||
text_cache,
|
||||
text_font_system,
|
||||
text_renderer,
|
||||
},
|
||||
};
|
||||
|
||||
ui: UiManager::new(),
|
||||
return Ok(Self {
|
||||
ui: UiManager::new(&mut state),
|
||||
device,
|
||||
config,
|
||||
surface,
|
||||
|
@ -279,6 +268,8 @@ impl GPUState {
|
|||
ui_pipeline,
|
||||
particle_pipeline,
|
||||
radialbar_pipeline,
|
||||
|
||||
state,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use anyhow::Result;
|
||||
use bytemuck;
|
||||
use cgmath::Point2;
|
||||
use galactica_constants;
|
||||
|
||||
use glyphon::{Color, Resolution, TextArea, TextBounds};
|
||||
use galactica_util::constants::{
|
||||
PARTICLE_SPRITE_INSTANCE_LIMIT, STARFIELD_SIZE, STARFIELD_SIZE_MAX, STARFIELD_SIZE_MIN,
|
||||
ZOOM_MAX, ZOOM_MIN,
|
||||
};
|
||||
use glyphon::Resolution;
|
||||
use rand::seq::SliceRandom;
|
||||
use std::iter;
|
||||
use wgpu;
|
||||
|
@ -63,7 +65,7 @@ impl super::GPUState {
|
|||
bytemuck::cast_slice(&[GlobalDataContent {
|
||||
camera_position: input.camera_pos.into(),
|
||||
camera_zoom: [input.camera_zoom, 0.0],
|
||||
camera_zoom_limits: [galactica_constants::ZOOM_MIN, galactica_constants::ZOOM_MAX],
|
||||
camera_zoom_limits: [ZOOM_MIN, ZOOM_MAX],
|
||||
window_size: [
|
||||
self.state.window_size.width as f32,
|
||||
self.state.window_size.height as f32,
|
||||
|
@ -71,11 +73,8 @@ impl super::GPUState {
|
|||
window_scale: [self.state.window.scale_factor() as f32, 0.0],
|
||||
window_aspect: [self.state.window_aspect, 0.0],
|
||||
starfield_sprite: [s.get_index(), 0],
|
||||
starfield_tile_size: [galactica_constants::STARFIELD_SIZE as f32, 0.0],
|
||||
starfield_size_limits: [
|
||||
galactica_constants::STARFIELD_SIZE_MIN,
|
||||
galactica_constants::STARFIELD_SIZE_MAX,
|
||||
],
|
||||
starfield_tile_size: [STARFIELD_SIZE as f32, 0.0],
|
||||
starfield_size_limits: [STARFIELD_SIZE_MIN, STARFIELD_SIZE_MAX],
|
||||
current_time: [input.current_time, 0.0],
|
||||
}]),
|
||||
);
|
||||
|
@ -99,9 +98,7 @@ impl super::GPUState {
|
|||
}]),
|
||||
);
|
||||
self.state.vertex_buffers.particle_counter += 1;
|
||||
if self.state.vertex_buffers.particle_counter
|
||||
== galactica_constants::PARTICLE_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
if self.state.vertex_buffers.particle_counter == PARTICLE_SPRITE_INSTANCE_LIMIT {
|
||||
self.state.vertex_buffers.particle_counter = 0;
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +161,7 @@ impl super::GPUState {
|
|||
render_pass.draw_indexed(
|
||||
0..SPRITE_INDICES.len() as u32,
|
||||
0,
|
||||
0..galactica_constants::PARTICLE_SPRITE_INSTANCE_LIMIT as _,
|
||||
0..PARTICLE_SPRITE_INSTANCE_LIMIT as _,
|
||||
);
|
||||
|
||||
// Ui pipeline
|
||||
|
@ -200,19 +197,7 @@ impl super::GPUState {
|
|||
width: self.state.window_size.width,
|
||||
height: self.state.window_size.height,
|
||||
},
|
||||
[TextArea {
|
||||
buffer: &self.state.text_buffer,
|
||||
left: 10.0,
|
||||
top: 10.0,
|
||||
scale: 1.0,
|
||||
bounds: TextBounds {
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 600,
|
||||
bottom: 160,
|
||||
},
|
||||
default_color: Color::rgb(255, 255, 255),
|
||||
}],
|
||||
self.ui.get_textareas(),
|
||||
&mut self.state.text_cache,
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use bytemuck;
|
||||
use cgmath::{EuclideanSpace, InnerSpace, Point2, Vector2};
|
||||
use galactica_systemsim::util;
|
||||
use galactica_util::constants::OBJECT_SPRITE_INSTANCE_LIMIT;
|
||||
|
||||
use crate::{
|
||||
globaluniform::ObjectData,
|
||||
|
@ -63,9 +64,7 @@ impl GPUState {
|
|||
);
|
||||
|
||||
// Enforce buffer limit
|
||||
if self.state.vertex_buffers.object_counter as u64
|
||||
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
if self.state.vertex_buffers.object_counter as u64 > OBJECT_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("Sprite limit exceeded!")
|
||||
}
|
||||
|
@ -109,7 +108,7 @@ impl GPUState {
|
|||
|
||||
// Enforce buffer limit
|
||||
if self.state.vertex_buffers.object_counter as u64
|
||||
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
||||
> OBJECT_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("Sprite limit exceeded!")
|
||||
|
@ -181,9 +180,7 @@ impl GPUState {
|
|||
);
|
||||
|
||||
// Enforce buffer limit
|
||||
if self.state.vertex_buffers.object_counter as u64
|
||||
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
if self.state.vertex_buffers.object_counter as u64 > OBJECT_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("Sprite limit exceeded!")
|
||||
}
|
||||
|
@ -251,9 +248,7 @@ impl GPUState {
|
|||
);
|
||||
|
||||
// Enforce buffer limit
|
||||
if self.state.vertex_buffers.object_counter as u64
|
||||
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
if self.state.vertex_buffers.object_counter as u64 > OBJECT_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("Sprite limit exceeded!")
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use cgmath::{Point2, Point3, Vector2, Vector3};
|
||||
use galactica_constants;
|
||||
use galactica_util::constants::{
|
||||
STARFIELD_COUNT, STARFIELD_SIZE, STARFIELD_SIZE_MAX, STARFIELD_SIZE_MIN,
|
||||
STARFIELD_SPRITE_INSTANCE_LIMIT, STARFIELD_Z_MAX, STARFIELD_Z_MIN, ZOOM_MAX,
|
||||
};
|
||||
use rand::{self, Rng};
|
||||
|
||||
use crate::vertexbuffer::types::StarfieldInstance;
|
||||
|
@ -34,20 +37,15 @@ impl Starfield {
|
|||
pub fn regenerate(&mut self) {
|
||||
// TODO: save seed in system, regenerate on jump
|
||||
let mut rng = rand::thread_rng();
|
||||
let sz = galactica_constants::STARFIELD_SIZE as f32 / 2.0;
|
||||
self.stars = (0..galactica_constants::STARFIELD_COUNT)
|
||||
let sz = STARFIELD_SIZE as f32 / 2.0;
|
||||
self.stars = (0..STARFIELD_COUNT)
|
||||
.map(|_| StarfieldStar {
|
||||
pos: Point3 {
|
||||
x: rng.gen_range(-sz..=sz),
|
||||
y: rng.gen_range(-sz..=sz),
|
||||
z: rng.gen_range(
|
||||
galactica_constants::STARFIELD_Z_MIN..galactica_constants::STARFIELD_Z_MAX,
|
||||
),
|
||||
z: rng.gen_range(STARFIELD_Z_MIN..STARFIELD_Z_MAX),
|
||||
},
|
||||
size: rng.gen_range(
|
||||
galactica_constants::STARFIELD_SIZE_MIN
|
||||
..galactica_constants::STARFIELD_SIZE_MAX,
|
||||
),
|
||||
size: rng.gen_range(STARFIELD_SIZE_MIN..STARFIELD_SIZE_MAX),
|
||||
tint: Vector2 {
|
||||
x: rng.gen_range(0.0..=1.0),
|
||||
y: rng.gen_range(0.0..=1.0),
|
||||
|
@ -57,17 +55,17 @@ impl Starfield {
|
|||
}
|
||||
|
||||
pub fn make_instances(&mut self, aspect: f32) -> Vec<StarfieldInstance> {
|
||||
let sz = galactica_constants::STARFIELD_SIZE as f32;
|
||||
let sz = STARFIELD_SIZE as f32;
|
||||
|
||||
// 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((aspect, 1.0)) * galactica_constants::ZOOM_MAX;
|
||||
let clip_nw = Point2::from((aspect, 1.0)) * ZOOM_MAX;
|
||||
|
||||
// Parallax correction.
|
||||
// Also, adjust v for mod to work properly
|
||||
// (v is centered at 0)
|
||||
let v: Point2<f32> = clip_nw * galactica_constants::STARFIELD_Z_MIN;
|
||||
let v: Point2<f32> = clip_nw * STARFIELD_Z_MIN;
|
||||
let v_adj: Point2<f32> = (v.x + (sz / 2.0), v.y + (sz / 2.0)).into();
|
||||
|
||||
#[rustfmt::skip]
|
||||
|
@ -91,10 +89,8 @@ impl Starfield {
|
|||
|
||||
// Truncate tile grid to buffer size
|
||||
// (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)
|
||||
* galactica_constants::STARFIELD_COUNT as i32)
|
||||
> galactica_constants::STARFIELD_SPRITE_INSTANCE_LIMIT as i32
|
||||
while ((nw_tile.x * 2 + 1) * (nw_tile.y * 2 + 1) * STARFIELD_COUNT as i32)
|
||||
> STARFIELD_SPRITE_INSTANCE_LIMIT as i32
|
||||
{
|
||||
nw_tile -= Vector2::from((1, 1));
|
||||
}
|
||||
|
@ -119,7 +115,7 @@ impl Starfield {
|
|||
}
|
||||
|
||||
// Enforce starfield limit
|
||||
if instances.len() as u64 > galactica_constants::STARFIELD_SPRITE_INSTANCE_LIMIT {
|
||||
if instances.len() as u64 > STARFIELD_SPRITE_INSTANCE_LIMIT {
|
||||
unreachable!("Starfield limit exceeded!")
|
||||
}
|
||||
self.instance_count = instances.len() as u32;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::globaluniform::{AtlasArray, AtlasImageLocation, SpriteData, SpriteDataArray};
|
||||
use anyhow::Result;
|
||||
use bytemuck::Zeroable;
|
||||
use galactica_constants::ASSET_CACHE;
|
||||
use galactica_content::Content;
|
||||
use galactica_packer::SpriteAtlasImage;
|
||||
use galactica_util::constants::ASSET_CACHE;
|
||||
use image::GenericImageView;
|
||||
use std::{fs::File, io::Read, num::NonZeroU32, path::Path};
|
||||
use wgpu::BindGroupLayout;
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
use glyphon::{Attrs, Buffer, Color, Family, Metrics, Shaping, TextArea, TextBounds};
|
||||
use std::time::Instant;
|
||||
|
||||
use crate::{datastructs::RenderState, RenderInput};
|
||||
|
||||
pub(super) struct FpsIndicator {
|
||||
buffer: Buffer,
|
||||
last_update: Instant,
|
||||
update_counter: u32,
|
||||
}
|
||||
|
||||
impl FpsIndicator {
|
||||
pub fn new(state: &mut RenderState) -> Self {
|
||||
let mut buffer = Buffer::new(&mut state.text_font_system, Metrics::new(12.0, 20.0));
|
||||
buffer.set_size(
|
||||
&mut state.text_font_system,
|
||||
state.window_size.width as f32,
|
||||
state.window_size.height as f32,
|
||||
);
|
||||
buffer.shape_until_scroll(&mut state.text_font_system);
|
||||
|
||||
Self {
|
||||
buffer,
|
||||
last_update: Instant::now(),
|
||||
update_counter: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FpsIndicator {
|
||||
pub fn update(&mut self, input: &RenderInput, state: &mut RenderState) {
|
||||
// Update once every n frames
|
||||
if self.update_counter > 0 {
|
||||
self.update_counter -= 1;
|
||||
return;
|
||||
}
|
||||
self.update_counter = 100;
|
||||
|
||||
self.buffer.set_text(
|
||||
&mut state.text_font_system,
|
||||
&format!(
|
||||
"Game: {:.02?}\nPhys: {:.02?}\nRender: {:.02?}",
|
||||
1.0 / input.timing.galaxy,
|
||||
1.0 / input.timing.physics,
|
||||
1.0 / (self.last_update.elapsed().as_secs_f32() / 100.0)
|
||||
),
|
||||
Attrs::new().family(Family::SansSerif),
|
||||
Shaping::Basic,
|
||||
);
|
||||
self.last_update = Instant::now();
|
||||
}
|
||||
|
||||
pub fn get_textarea(&self) -> TextArea {
|
||||
TextArea {
|
||||
buffer: &self.buffer,
|
||||
left: 10.0,
|
||||
top: 400.0,
|
||||
scale: 1.0,
|
||||
bounds: TextBounds {
|
||||
left: 10,
|
||||
top: 400,
|
||||
right: 300,
|
||||
bottom: 800,
|
||||
},
|
||||
default_color: Color::rgb(255, 255, 255),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,21 @@
|
|||
use glyphon::TextArea;
|
||||
|
||||
use crate::{datastructs::RenderState, RenderInput};
|
||||
|
||||
use super::{radar::Radar, status::Status, UiElement};
|
||||
use super::{fpsindicator::FpsIndicator, radar::Radar, status::Status};
|
||||
|
||||
pub struct UiManager {
|
||||
radar: Radar,
|
||||
status: Status,
|
||||
fps: FpsIndicator,
|
||||
}
|
||||
|
||||
impl UiManager {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(state: &mut RenderState) -> Self {
|
||||
Self {
|
||||
radar: Radar::new(),
|
||||
status: Status::new(),
|
||||
fps: FpsIndicator::new(state),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,5 +23,10 @@ impl UiManager {
|
|||
pub fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
||||
self.radar.draw(input, state);
|
||||
self.status.draw(input, state);
|
||||
self.fps.update(input, state);
|
||||
}
|
||||
|
||||
pub fn get_textareas(&self) -> impl Iterator<Item = TextArea> {
|
||||
(0..1).map(|_| self.fps.get_textarea())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
use crate::{datastructs::RenderState, RenderInput};
|
||||
|
||||
mod fpsindicator;
|
||||
mod manager;
|
||||
mod radar;
|
||||
mod status;
|
||||
|
||||
pub use manager::UiManager;
|
||||
|
||||
trait UiElement {
|
||||
fn draw(&mut self, input: &RenderInput, state: &mut RenderState);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use cgmath::{Deg, InnerSpace, Point2, Rad, Vector2};
|
||||
use galactica_systemsim::util;
|
||||
use galactica_util::constants::UI_SPRITE_INSTANCE_LIMIT;
|
||||
|
||||
use crate::{
|
||||
datastructs::RenderState,
|
||||
vertexbuffer::{types::UiInstance, BufferObject},
|
||||
PositionAnchor, RenderInput,
|
||||
};
|
||||
|
||||
use super::RenderState;
|
||||
|
||||
pub(super) struct Radar {}
|
||||
|
||||
impl Radar {
|
||||
|
@ -16,8 +16,8 @@ impl Radar {
|
|||
}
|
||||
}
|
||||
|
||||
impl super::UiElement for Radar {
|
||||
fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
||||
impl Radar {
|
||||
pub fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
||||
let radar_range = 4000.0;
|
||||
let radar_size = 300.0;
|
||||
let hide_range = 0.85;
|
||||
|
@ -37,7 +37,7 @@ impl super::UiElement for Radar {
|
|||
let arrow_sprite = input.content.get_sprite_handle("ui::centerarrow");
|
||||
|
||||
// Enforce buffer limit
|
||||
if state.vertex_buffers.ui_counter as u64 > galactica_constants::UI_SPRITE_INSTANCE_LIMIT {
|
||||
if state.vertex_buffers.ui_counter as u64 > UI_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("UI limit exceeded!")
|
||||
}
|
||||
|
@ -77,9 +77,7 @@ impl super::UiElement for Radar {
|
|||
}
|
||||
|
||||
// Enforce buffer limit
|
||||
if state.vertex_buffers.ui_counter as u64
|
||||
> galactica_constants::UI_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
if state.vertex_buffers.ui_counter as u64 > UI_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("UI limit exceeded!")
|
||||
}
|
||||
|
@ -138,9 +136,7 @@ impl super::UiElement for Radar {
|
|||
|
||||
// Enforce buffer limit
|
||||
// TODO: cleaner solution. don't do this everywhere.
|
||||
if state.vertex_buffers.ui_counter as u64
|
||||
> galactica_constants::UI_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
if state.vertex_buffers.ui_counter as u64 > UI_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("UI limit exceeded!")
|
||||
}
|
||||
|
@ -175,9 +171,7 @@ impl super::UiElement for Radar {
|
|||
let size = 7.0f32.min((0.8 - m) * 70.0);
|
||||
|
||||
// Enforce buffer limit (this section adds four items)
|
||||
if state.vertex_buffers.ui_counter as u64 + 4
|
||||
> galactica_constants::UI_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
if state.vertex_buffers.ui_counter as u64 + 4 > UI_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("UI limit exceeded!")
|
||||
}
|
||||
|
@ -266,9 +260,7 @@ impl super::UiElement for Radar {
|
|||
y: radar_size / -2.0 - 10.0,
|
||||
} + ((q.normalize() * 0.865) * (radar_size / 2.0));
|
||||
|
||||
if state.vertex_buffers.ui_counter as u64
|
||||
> galactica_constants::UI_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
if state.vertex_buffers.ui_counter as u64 > UI_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("UI limit exceeded!")
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::f32::consts::TAU;
|
||||
|
||||
use galactica_util::constants::{RADIALBAR_SPRITE_INSTANCE_LIMIT, UI_SPRITE_INSTANCE_LIMIT};
|
||||
|
||||
use crate::{
|
||||
datastructs::RenderState,
|
||||
vertexbuffer::{
|
||||
|
@ -9,8 +11,6 @@ use crate::{
|
|||
PositionAnchor, RenderInput,
|
||||
};
|
||||
|
||||
use super::UiElement;
|
||||
|
||||
pub(super) struct Status {}
|
||||
impl Status {
|
||||
pub fn new() -> Self {
|
||||
|
@ -18,9 +18,9 @@ impl Status {
|
|||
}
|
||||
}
|
||||
|
||||
impl UiElement for Status {
|
||||
fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
||||
if state.vertex_buffers.ui_counter as u64 > galactica_constants::UI_SPRITE_INSTANCE_LIMIT {
|
||||
impl Status {
|
||||
pub fn draw(&mut self, input: &RenderInput, state: &mut RenderState) {
|
||||
if state.vertex_buffers.ui_counter as u64 > UI_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("UI limit exceeded!")
|
||||
}
|
||||
|
@ -51,9 +51,7 @@ impl UiElement for Status {
|
|||
state.vertex_buffers.ui_counter += 1;
|
||||
|
||||
// We add two items here, so +2
|
||||
if state.vertex_buffers.radialbar_counter as u64 + 2
|
||||
> galactica_constants::RADIALBAR_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
if state.vertex_buffers.radialbar_counter as u64 + 2 > RADIALBAR_SPRITE_INSTANCE_LIMIT {
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("Radialbar limit exceeded!")
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "galactica-constants"
|
||||
name = "galactica-util"
|
||||
description = "Compile-time parameters for Galactica"
|
||||
categories = { workspace = true }
|
||||
keywords = { workspace = true }
|
|
@ -1,6 +1,5 @@
|
|||
#![warn(missing_docs)]
|
||||
|
||||
//! Compile-time parameters
|
||||
|
||||
// TODO: many of these should be moved to a config file or cli option
|
||||
|
||||
/// Minimum zoom level
|
|
@ -0,0 +1,6 @@
|
|||
#![warn(missing_docs)]
|
||||
|
||||
//! Various utilities
|
||||
|
||||
pub mod constants;
|
||||
pub mod timing;
|
|
@ -0,0 +1,44 @@
|
|||
//! Keep track of the time we spent in each part of the game loop.
|
||||
use std::time::Instant;
|
||||
|
||||
/// Utility struct.
|
||||
/// Keeps track of the time we spent in each part of the game loop.
|
||||
pub struct Timing {
|
||||
timer: Option<Instant>,
|
||||
|
||||
/// The time we spent simulating game state
|
||||
pub galaxy: f32,
|
||||
|
||||
/// The time we spent simulating physics
|
||||
pub physics: f32,
|
||||
}
|
||||
|
||||
impl Timing {
|
||||
/// Create a new timing struct
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
timer: None,
|
||||
galaxy: f32::NAN,
|
||||
physics: f32::NAN,
|
||||
}
|
||||
}
|
||||
|
||||
/// Start the timer
|
||||
pub fn start(&mut self) {
|
||||
self.timer = Some(Instant::now());
|
||||
}
|
||||
|
||||
/// Clear timer and record galaxy simulation time.
|
||||
/// Assumes timer has been started
|
||||
pub fn mark_galaxy(&mut self) {
|
||||
self.galaxy = self.timer.unwrap().elapsed().as_secs_f32();
|
||||
self.timer = None;
|
||||
}
|
||||
|
||||
/// Clear timer and record physics simulation time
|
||||
/// Asumes timer has been started
|
||||
pub fn mark_physics(&mut self) {
|
||||
self.physics = self.timer.unwrap().elapsed().as_secs_f32();
|
||||
self.timer = None;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue