Added fps counter

master
Mark 2024-01-10 18:53:19 -08:00
parent 08e9958f2d
commit be2cca79b0
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
26 changed files with 239 additions and 150 deletions

14
Cargo.lock generated
View File

@ -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"

View File

@ -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" }

View File

@ -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 }

View File

@ -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,
}
}
}

View File

@ -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},

View File

@ -21,7 +21,7 @@ readme = { workspace = true }
workspace = true
[dependencies]
galactica-constants = { workspace = true }
galactica-util = { workspace = true }
image = { workspace = true }
toml = { workspace = true }

View File

@ -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 }

View File

@ -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

View File

@ -1,5 +1,5 @@
use bytemuck::{Pod, Zeroable};
use galactica_constants::IMAGE_LIMIT;
use galactica_util::constants::IMAGE_LIMIT;
use std::mem;
use wgpu;

View File

@ -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};

View File

@ -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;

View File

@ -1,5 +1,5 @@
use bytemuck::{Pod, Zeroable};
use galactica_constants::SPRITE_LIMIT;
use galactica_util::constants::SPRITE_LIMIT;
use std::mem;
use wgpu;

View File

@ -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,
});
}
}

View File

@ -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();

View File

@ -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!")
}

View File

@ -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;

View File

@ -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;

View File

@ -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),
}
}
}

View File

@ -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())
}
}

View File

@ -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);
}

View File

@ -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!")
}

View File

@ -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!")
}

View File

@ -1,5 +1,5 @@
[package]
name = "galactica-constants"
name = "galactica-util"
description = "Compile-time parameters for Galactica"
categories = { workspace = true }
keywords = { workspace = true }

View File

@ -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

6
crates/util/src/lib.rs Normal file
View File

@ -0,0 +1,6 @@
#![warn(missing_docs)]
//! Various utilities
pub mod constants;
pub mod timing;

44
crates/util/src/timing.rs Normal file
View File

@ -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;
}
}