Pausing rendering, warnings cleanup, more statistics

This commit is contained in:
Piotrek
2021-05-10 15:36:11 +02:00
parent 4eaa0fab56
commit a09f446ecd
10 changed files with 84 additions and 79 deletions
Generated
+25 -25
View File
@@ -1,30 +1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "VoxelGame"
version = "0.1.0"
dependencies = [
"anyhow",
"bytemuck",
"byteorder",
"cgmath",
"dirs",
"flate2",
"fs_extra",
"futures",
"glob",
"image",
"linked-hash-map",
"lzzzz",
"noise",
"rand 0.8.3",
"shaderc",
"wgpu",
"wgpu_glyph",
"winit",
"yaml-rust",
]
[[package]]
name = "ab_glyph"
version = "0.2.10"
@@ -2058,6 +2033,31 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "voxel_game"
version = "0.1.0"
dependencies = [
"anyhow",
"bytemuck",
"byteorder",
"cgmath",
"dirs",
"flate2",
"fs_extra",
"futures",
"glob",
"image",
"linked-hash-map",
"lzzzz",
"noise",
"rand 0.8.3",
"shaderc",
"wgpu",
"wgpu_glyph",
"winit",
"yaml-rust",
]
[[package]]
name = "walkdir"
version = "2.3.2"
+1 -1
View File
@@ -1,5 +1,5 @@
[package]
name = "VoxelGame"
name = "voxel_game"
version = "0.1.0"
authors = ["Piotrek <hello@pbaja.me>"]
edition = "2018"
+10 -3
View File
@@ -3,7 +3,7 @@ mod player;
pub mod world;
use std::time::Instant;
use crate::renderer::content_view::ContentView;
use cgmath::{SquareMatrix, Point3, InnerSpace};
use cgmath::Point3;
use winit::event::Event;
use crate::renderer::{camera::CameraTransform};
use player::Player;
@@ -16,6 +16,7 @@ pub enum GameState {
}
pub struct Game {
state: GameState,
player: Player,
world: World
}
@@ -23,6 +24,7 @@ pub struct Game {
impl Game {
pub fn new(content: &mut dyn ContentView) -> Self {
let mut app = Self {
state: GameState::Paused,
player: Player::new(),
world: World::new("default".to_string())
};
@@ -62,7 +64,7 @@ impl Game {
self.player.camera_controller.handle_input(event);
}
pub fn update_state(&mut self, requested_state: GameState) -> GameState {
pub fn update_state(&mut self, requested_state: GameState) -> &GameState {
match requested_state {
GameState::Paused => {
self.player.camera_controller.set_enabled(false);
@@ -73,7 +75,12 @@ impl Game {
};
// Currently we are not preventing any state changes, just return requested state
requested_state
self.state = requested_state;
&self.state
}
pub fn get_state(&self) -> &GameState {
&self.state
}
pub fn update_camera(&mut self, delta: f32, camera_transform: &mut dyn CameraTransform) {
-3
View File
@@ -1,7 +1,4 @@
use cgmath::Point3;
use std::iter::FromIterator;
use std::io::Write;
use flate2::{write::DeflateEncoder, Compression};
pub const SIZE: usize = 32;
pub const SIZE_QB: usize = SIZE*SIZE*SIZE;
+9 -15
View File
@@ -1,20 +1,20 @@
use std::time::Instant;
use flate2::Compression;
use flate2::write::DeflateEncoder;
use flate2::read::DeflateDecoder;
use byteorder::LittleEndian;
use byteorder::ByteOrder;
use cgmath::Point3;
use std::io::Write;
use std::convert::TryInto;
use lzzzz::lz4;
use std::io::Read;
use crate::game::world::{WorldBlock, block};
pub const SIZE: usize = 32;
const SIZE_SQ: usize = SIZE*SIZE;
const SIZE_QB: usize = SIZE*SIZE*SIZE;
// 1 chunk times on i7-5930K
// alg | size | compr | decom
// raw 32.89kB 0.06s 1.19s
// deflate fast 1.23kB 1.22s 5.46s
// lz4 1.6kB 0.07s 1.23s
pub struct WorldChunk {
nodes: Box<[u32]>,
blocks: Vec<WorldBlock>
@@ -30,15 +30,15 @@ impl WorldChunk {
pub fn from_bytes(bytes: Vec<u8>) -> Self {
let mut instance = Self::new();
let (header_bytes, bytes) = bytes.split_at(128);
let (node_bytes, block_bytes_compressed) = bytes.split_at((SIZE_QB*4) as usize);
// Header
let (header_bytes, bytes) = bytes.split_at(128);
let file_ver = header_bytes[0];
let num_blocks = LittleEndian::read_u32(&header_bytes[1..5]) as usize;
assert_eq!(file_ver, 1);
// Nodes
let (node_bytes, block_bytes_compressed) = bytes.split_at((SIZE_QB*4) as usize);
for i in 0..SIZE_QB {
let idx = (i*4) as usize;
let val = u32::from_le_bytes([node_bytes[idx], node_bytes[idx+1], node_bytes[idx+2], node_bytes[idx+3]]);
@@ -79,12 +79,6 @@ impl WorldChunk {
}
lz4::compress_to_vec(&buf, &mut bytes, lz4::ACC_LEVEL_DEFAULT).unwrap();
// alg | size | compr | decom
// raw 32.89kB 0.06s 1.19s
// deflate fast 1.23kB 1.22s 5.46s
// lz4 1.6kB 0.07s 1.23s
bytes
}
+1 -1
View File
@@ -44,7 +44,7 @@ impl WorldGen {
let noise = Perlin::new();
// Generate height map
let (map, max) = WorldGen::gen_height_map(block_pos.x as usize, block_pos.z as usize, &mut rng, &noise);
let (map, _max) = WorldGen::gen_height_map(block_pos.x as usize, block_pos.z as usize, &mut rng, &noise);
// Fill
for x in 0..block::SIZE {
+4 -6
View File
@@ -1,19 +1,17 @@
mod generator;
pub mod chunk;
pub mod block;
use std::time::Instant;
use linked_hash_map::LinkedHashMap;
use std::path::PathBuf;
use std::path::Path;
use std::io::Write;
use std::io::Read;
use std::fs;
use cgmath::{Point3, InnerSpace};
use cgmath::Point3;
use std::collections::HashMap;
use generator::WorldGen;
use chunk::WorldChunk;
use block::WorldBlock;
use yaml_rust::{Yaml, YamlLoader, YamlEmitter};
use yaml_rust::{Yaml, YamlEmitter};
pub struct World {
@@ -101,7 +99,7 @@ impl World {
file.read_to_end(&mut bytes).expect("Failed to read file");
let chunk = WorldChunk::from_bytes(bytes);
println!("loaded {:?}", pos);
println!("Load: Chunk {}, {}, {}", pos.x, pos.y, pos.z);
self.chunks.insert(pos, chunk);
count += 1;
}
@@ -117,7 +115,7 @@ impl World {
// Create chunk if does not exist
if let None = self.chunks.get(&ch_pos) {
self.chunks.insert(ch_pos.clone(), WorldChunk::new());
println!("Alloc chunk [{}, {}, {}]", ch_pos.x, ch_pos.y, ch_pos.z);
println!("Alloc: Chunk [{}, {}, {}]", ch_pos.x, ch_pos.y, ch_pos.z);
}
// Generate block for chunk
let chunk = self.chunks.get_mut(&ch_pos).unwrap();
+9 -7
View File
@@ -24,7 +24,7 @@ fn main() {
.expect("Failed to create window");
let mut renderer = Renderer::new(&window);
let mut app = Game::new(&mut renderer);
let mut game = Game::new(&mut renderer);
// Stats
let mut fps_timer = std::time::Instant::now();
@@ -34,7 +34,7 @@ fn main() {
// Run event loop
events.run(move |ev, _, c| {
// App input
app.input(&ev);
game.input(&ev);
// Other
match ev {
@@ -46,7 +46,7 @@ fn main() {
// Escape key
WindowEvent::KeyboardInput { input: KeyboardInput { state: ElementState::Pressed, virtual_keycode: Some(VirtualKeyCode::Escape), .. }, .. } => {
// Request pause
if let GameState::Paused = app.update_state(GameState::Paused) {
if let GameState::Paused = game.update_state(GameState::Paused) {
window.set_cursor_grab(false).unwrap();
window.set_cursor_visible(true);
}
@@ -54,7 +54,7 @@ fn main() {
// Window clicked
WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, .. } => {
// Request unpause
if let GameState::Running = app.update_state(GameState::Running) {
if let GameState::Running = game.update_state(GameState::Running) {
window.set_cursor_grab(true).unwrap();
window.set_cursor_visible(false);
}
@@ -73,12 +73,14 @@ fn main() {
Event::MainEventsCleared => {
// Update
let delta = delta_timer.elapsed().as_secs_f32();
app.update_camera(delta, &mut renderer.camera);
game.update_camera(delta, &mut renderer.camera);
delta_timer = std::time::Instant::now();
// Redraw
// Redraw if running
if let GameState::Running = game.get_state() {
window.request_redraw();
}
}
// Draw
Event::RedrawRequested(_) => {
@@ -87,7 +89,7 @@ fn main() {
if elapsed >= 0.5 {
let mut fps = (fps_counter as f64) / elapsed;
fps = (fps*100.0_f64).floor() / 100.0;
renderer.ui.set_fps(fps as f32);
renderer.ui.set_text(0, format!("FPS: {}", fps));
fps_timer = std::time::Instant::now();
fps_counter = 0;
+8 -1
View File
@@ -1,4 +1,4 @@
use wgpu_glyph::Text;
use std::time::Instant;
use winit::{window::Window, dpi::PhysicalSize};
pub mod buffers;
use buffers::Buffers;
@@ -118,10 +118,14 @@ impl Renderer {
self.queue.write_buffer(&self.buffers.uniforms.buffer, 0, bytemuck::cast_slice(&[self.buffers.uniforms.values]));
// Update content
let timer = Instant::now();
self.buffers.content.update(&self.queue);
self.ui.set_text(2, format!("Update content: {}ms", timer.elapsed().as_micros() as f64 / 1000.0));
// Get next frame to render to
let timer = Instant::now();
let frame = self.swapchain.get_current_frame()?.output;
self.ui.set_text(3, format!("Swapchain get frame: {}ms", timer.elapsed().as_micros() as f64 / 1000.0));
// Create encoder that will build command buffer for us
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Render Encoder"),});
@@ -130,7 +134,10 @@ impl Renderer {
self.ui.render(&self.device, &mut encoder, &frame.view, 1280, 720);
// Submit encoder (command buffer)
let timer = Instant::now();
self.queue.submit(std::iter::once(encoder.finish()));
self.ui.set_text(4, format!("Submit queue: {}ms", timer.elapsed().as_micros() as f64 / 1000.0));
self.ui.recall();
// Return ok
+12 -12
View File
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use wgpu_glyph::{GlyphBrush, ab_glyph::FontArc, GlyphBrushBuilder, Section, Text};
use wgpu::util::StagingBelt;
use futures::executor::LocalPool;
@@ -11,7 +12,7 @@ pub struct UserInterface {
local_pool: LocalPool,
brush: GlyphBrush<()>,
// Texts
fps_text: String
texts: HashMap<u32, String>
}
impl UserInterface {
@@ -22,27 +23,26 @@ impl UserInterface {
staging_belt: StagingBelt::new(1024),
local_pool: LocalPool::new(),
brush: GlyphBrushBuilder::using_font(font).build(device, render_format),
fps_text: "-".to_string()
texts: HashMap::new()
}
}
fn print(&mut self, x: u32, y: u32, msg: &str) {
let text = Text::new(msg).with_color(WHITE);
pub fn set_text(&mut self, index: u32, text: String) {
self.texts.insert(index, text);
}
pub fn render(&mut self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, target: &wgpu::TextureView, width: u32, height: u32) {
for (id, text) in self.texts.iter() {
let text = Text::new(text).with_color(WHITE);
self.brush.queue(Section {
screen_position: (x as f32, y as f32),
screen_position: (5 as f32, (5 + id*15) as f32),
bounds: (text.scale.x * text.text.len() as f32, text.scale.y),
text: vec![text],
..Section::default()
});
}
pub fn set_fps(&mut self, fps: f32) {
self.fps_text = format!("FPS: {}", fps);
}
pub fn render(&mut self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, target: &wgpu::TextureView, width: u32, height: u32) {
// Print texts
self.print(5, 5, &self.fps_text.clone());
// Draw
self.brush.draw_queued(&device, &mut self.staging_belt, encoder, target, width, height).expect("Draw queued");
self.staging_belt.finish();