Pausing rendering, warnings cleanup, more statistics
This commit is contained in:
Generated
+25
-25
@@ -1,30 +1,5 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# 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]]
|
[[package]]
|
||||||
name = "ab_glyph"
|
name = "ab_glyph"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
@@ -2058,6 +2033,31 @@ version = "0.9.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
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]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.3.2"
|
version = "2.3.2"
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "VoxelGame"
|
name = "voxel_game"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Piotrek <hello@pbaja.me>"]
|
authors = ["Piotrek <hello@pbaja.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|||||||
+10
-3
@@ -3,7 +3,7 @@ mod player;
|
|||||||
pub mod world;
|
pub mod world;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use crate::renderer::content_view::ContentView;
|
use crate::renderer::content_view::ContentView;
|
||||||
use cgmath::{SquareMatrix, Point3, InnerSpace};
|
use cgmath::Point3;
|
||||||
use winit::event::Event;
|
use winit::event::Event;
|
||||||
use crate::renderer::{camera::CameraTransform};
|
use crate::renderer::{camera::CameraTransform};
|
||||||
use player::Player;
|
use player::Player;
|
||||||
@@ -16,6 +16,7 @@ pub enum GameState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
|
state: GameState,
|
||||||
player: Player,
|
player: Player,
|
||||||
world: World
|
world: World
|
||||||
}
|
}
|
||||||
@@ -23,6 +24,7 @@ pub struct Game {
|
|||||||
impl Game {
|
impl Game {
|
||||||
pub fn new(content: &mut dyn ContentView) -> Self {
|
pub fn new(content: &mut dyn ContentView) -> Self {
|
||||||
let mut app = Self {
|
let mut app = Self {
|
||||||
|
state: GameState::Paused,
|
||||||
player: Player::new(),
|
player: Player::new(),
|
||||||
world: World::new("default".to_string())
|
world: World::new("default".to_string())
|
||||||
};
|
};
|
||||||
@@ -62,7 +64,7 @@ impl Game {
|
|||||||
self.player.camera_controller.handle_input(event);
|
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 {
|
match requested_state {
|
||||||
GameState::Paused => {
|
GameState::Paused => {
|
||||||
self.player.camera_controller.set_enabled(false);
|
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
|
// 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) {
|
pub fn update_camera(&mut self, delta: f32, camera_transform: &mut dyn CameraTransform) {
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
use cgmath::Point3;
|
use cgmath::Point3;
|
||||||
use std::iter::FromIterator;
|
|
||||||
use std::io::Write;
|
|
||||||
use flate2::{write::DeflateEncoder, Compression};
|
|
||||||
|
|
||||||
pub const SIZE: usize = 32;
|
pub const SIZE: usize = 32;
|
||||||
pub const SIZE_QB: usize = SIZE*SIZE*SIZE;
|
pub const SIZE_QB: usize = SIZE*SIZE*SIZE;
|
||||||
|
|||||||
+9
-15
@@ -1,20 +1,20 @@
|
|||||||
use std::time::Instant;
|
|
||||||
use flate2::Compression;
|
|
||||||
use flate2::write::DeflateEncoder;
|
|
||||||
use flate2::read::DeflateDecoder;
|
|
||||||
use byteorder::LittleEndian;
|
use byteorder::LittleEndian;
|
||||||
use byteorder::ByteOrder;
|
use byteorder::ByteOrder;
|
||||||
use cgmath::Point3;
|
use cgmath::Point3;
|
||||||
use std::io::Write;
|
|
||||||
use std::convert::TryInto;
|
|
||||||
use lzzzz::lz4;
|
use lzzzz::lz4;
|
||||||
use std::io::Read;
|
|
||||||
use crate::game::world::{WorldBlock, block};
|
use crate::game::world::{WorldBlock, block};
|
||||||
|
|
||||||
pub const SIZE: usize = 32;
|
pub const SIZE: usize = 32;
|
||||||
const SIZE_SQ: usize = SIZE*SIZE;
|
const SIZE_SQ: usize = SIZE*SIZE;
|
||||||
const SIZE_QB: usize = SIZE*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 {
|
pub struct WorldChunk {
|
||||||
nodes: Box<[u32]>,
|
nodes: Box<[u32]>,
|
||||||
blocks: Vec<WorldBlock>
|
blocks: Vec<WorldBlock>
|
||||||
@@ -30,15 +30,15 @@ impl WorldChunk {
|
|||||||
|
|
||||||
pub fn from_bytes(bytes: Vec<u8>) -> Self {
|
pub fn from_bytes(bytes: Vec<u8>) -> Self {
|
||||||
let mut instance = Self::new();
|
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
|
// Header
|
||||||
|
let (header_bytes, bytes) = bytes.split_at(128);
|
||||||
let file_ver = header_bytes[0];
|
let file_ver = header_bytes[0];
|
||||||
let num_blocks = LittleEndian::read_u32(&header_bytes[1..5]) as usize;
|
let num_blocks = LittleEndian::read_u32(&header_bytes[1..5]) as usize;
|
||||||
assert_eq!(file_ver, 1);
|
assert_eq!(file_ver, 1);
|
||||||
|
|
||||||
// Nodes
|
// Nodes
|
||||||
|
let (node_bytes, block_bytes_compressed) = bytes.split_at((SIZE_QB*4) as usize);
|
||||||
for i in 0..SIZE_QB {
|
for i in 0..SIZE_QB {
|
||||||
let idx = (i*4) as usize;
|
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]]);
|
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();
|
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
|
bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ impl WorldGen {
|
|||||||
let noise = Perlin::new();
|
let noise = Perlin::new();
|
||||||
|
|
||||||
// Generate height map
|
// 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
|
// Fill
|
||||||
for x in 0..block::SIZE {
|
for x in 0..block::SIZE {
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
mod generator;
|
mod generator;
|
||||||
pub mod chunk;
|
pub mod chunk;
|
||||||
pub mod block;
|
pub mod block;
|
||||||
use std::time::Instant;
|
|
||||||
use linked_hash_map::LinkedHashMap;
|
use linked_hash_map::LinkedHashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::path::Path;
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use cgmath::{Point3, InnerSpace};
|
use cgmath::Point3;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use generator::WorldGen;
|
use generator::WorldGen;
|
||||||
use chunk::WorldChunk;
|
use chunk::WorldChunk;
|
||||||
use block::WorldBlock;
|
use block::WorldBlock;
|
||||||
use yaml_rust::{Yaml, YamlLoader, YamlEmitter};
|
use yaml_rust::{Yaml, YamlEmitter};
|
||||||
|
|
||||||
|
|
||||||
pub struct World {
|
pub struct World {
|
||||||
@@ -101,7 +99,7 @@ impl World {
|
|||||||
file.read_to_end(&mut bytes).expect("Failed to read file");
|
file.read_to_end(&mut bytes).expect("Failed to read file");
|
||||||
let chunk = WorldChunk::from_bytes(bytes);
|
let chunk = WorldChunk::from_bytes(bytes);
|
||||||
|
|
||||||
println!("loaded {:?}", pos);
|
println!("Load: Chunk {}, {}, {}", pos.x, pos.y, pos.z);
|
||||||
self.chunks.insert(pos, chunk);
|
self.chunks.insert(pos, chunk);
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
@@ -117,7 +115,7 @@ impl World {
|
|||||||
// Create chunk if does not exist
|
// Create chunk if does not exist
|
||||||
if let None = self.chunks.get(&ch_pos) {
|
if let None = self.chunks.get(&ch_pos) {
|
||||||
self.chunks.insert(ch_pos.clone(), WorldChunk::new());
|
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
|
// Generate block for chunk
|
||||||
let chunk = self.chunks.get_mut(&ch_pos).unwrap();
|
let chunk = self.chunks.get_mut(&ch_pos).unwrap();
|
||||||
|
|||||||
+10
-8
@@ -24,7 +24,7 @@ fn main() {
|
|||||||
.expect("Failed to create window");
|
.expect("Failed to create window");
|
||||||
|
|
||||||
let mut renderer = Renderer::new(&window);
|
let mut renderer = Renderer::new(&window);
|
||||||
let mut app = Game::new(&mut renderer);
|
let mut game = Game::new(&mut renderer);
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
let mut fps_timer = std::time::Instant::now();
|
let mut fps_timer = std::time::Instant::now();
|
||||||
@@ -34,7 +34,7 @@ fn main() {
|
|||||||
// Run event loop
|
// Run event loop
|
||||||
events.run(move |ev, _, c| {
|
events.run(move |ev, _, c| {
|
||||||
// App input
|
// App input
|
||||||
app.input(&ev);
|
game.input(&ev);
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
match ev {
|
match ev {
|
||||||
@@ -46,7 +46,7 @@ fn main() {
|
|||||||
// Escape key
|
// Escape key
|
||||||
WindowEvent::KeyboardInput { input: KeyboardInput { state: ElementState::Pressed, virtual_keycode: Some(VirtualKeyCode::Escape), .. }, .. } => {
|
WindowEvent::KeyboardInput { input: KeyboardInput { state: ElementState::Pressed, virtual_keycode: Some(VirtualKeyCode::Escape), .. }, .. } => {
|
||||||
// Request pause
|
// 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_grab(false).unwrap();
|
||||||
window.set_cursor_visible(true);
|
window.set_cursor_visible(true);
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ fn main() {
|
|||||||
// Window clicked
|
// Window clicked
|
||||||
WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, .. } => {
|
WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, .. } => {
|
||||||
// Request unpause
|
// 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_grab(true).unwrap();
|
||||||
window.set_cursor_visible(false);
|
window.set_cursor_visible(false);
|
||||||
}
|
}
|
||||||
@@ -73,11 +73,13 @@ fn main() {
|
|||||||
Event::MainEventsCleared => {
|
Event::MainEventsCleared => {
|
||||||
// Update
|
// Update
|
||||||
let delta = delta_timer.elapsed().as_secs_f32();
|
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();
|
delta_timer = std::time::Instant::now();
|
||||||
|
|
||||||
// Redraw
|
// Redraw if running
|
||||||
window.request_redraw();
|
if let GameState::Running = game.get_state() {
|
||||||
|
window.request_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Draw
|
// Draw
|
||||||
Event::RedrawRequested(_) => {
|
Event::RedrawRequested(_) => {
|
||||||
@@ -87,7 +89,7 @@ fn main() {
|
|||||||
if elapsed >= 0.5 {
|
if elapsed >= 0.5 {
|
||||||
let mut fps = (fps_counter as f64) / elapsed;
|
let mut fps = (fps_counter as f64) / elapsed;
|
||||||
fps = (fps*100.0_f64).floor() / 100.0;
|
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_timer = std::time::Instant::now();
|
||||||
fps_counter = 0;
|
fps_counter = 0;
|
||||||
|
|||||||
+8
-1
@@ -1,4 +1,4 @@
|
|||||||
use wgpu_glyph::Text;
|
use std::time::Instant;
|
||||||
use winit::{window::Window, dpi::PhysicalSize};
|
use winit::{window::Window, dpi::PhysicalSize};
|
||||||
pub mod buffers;
|
pub mod buffers;
|
||||||
use buffers::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]));
|
self.queue.write_buffer(&self.buffers.uniforms.buffer, 0, bytemuck::cast_slice(&[self.buffers.uniforms.values]));
|
||||||
|
|
||||||
// Update content
|
// Update content
|
||||||
|
let timer = Instant::now();
|
||||||
self.buffers.content.update(&self.queue);
|
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
|
// Get next frame to render to
|
||||||
|
let timer = Instant::now();
|
||||||
let frame = self.swapchain.get_current_frame()?.output;
|
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
|
// Create encoder that will build command buffer for us
|
||||||
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Render Encoder"),});
|
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);
|
self.ui.render(&self.device, &mut encoder, &frame.view, 1280, 720);
|
||||||
|
|
||||||
// Submit encoder (command buffer)
|
// Submit encoder (command buffer)
|
||||||
|
let timer = Instant::now();
|
||||||
self.queue.submit(std::iter::once(encoder.finish()));
|
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();
|
self.ui.recall();
|
||||||
|
|
||||||
// Return ok
|
// Return ok
|
||||||
|
|||||||
+16
-16
@@ -1,3 +1,4 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
use wgpu_glyph::{GlyphBrush, ab_glyph::FontArc, GlyphBrushBuilder, Section, Text};
|
use wgpu_glyph::{GlyphBrush, ab_glyph::FontArc, GlyphBrushBuilder, Section, Text};
|
||||||
use wgpu::util::StagingBelt;
|
use wgpu::util::StagingBelt;
|
||||||
use futures::executor::LocalPool;
|
use futures::executor::LocalPool;
|
||||||
@@ -11,7 +12,7 @@ pub struct UserInterface {
|
|||||||
local_pool: LocalPool,
|
local_pool: LocalPool,
|
||||||
brush: GlyphBrush<()>,
|
brush: GlyphBrush<()>,
|
||||||
// Texts
|
// Texts
|
||||||
fps_text: String
|
texts: HashMap<u32, String>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserInterface {
|
impl UserInterface {
|
||||||
@@ -22,27 +23,26 @@ impl UserInterface {
|
|||||||
staging_belt: StagingBelt::new(1024),
|
staging_belt: StagingBelt::new(1024),
|
||||||
local_pool: LocalPool::new(),
|
local_pool: LocalPool::new(),
|
||||||
brush: GlyphBrushBuilder::using_font(font).build(device, render_format),
|
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) {
|
pub fn set_text(&mut self, index: u32, text: String) {
|
||||||
let text = Text::new(msg).with_color(WHITE);
|
self.texts.insert(index, text);
|
||||||
self.brush.queue(Section {
|
|
||||||
screen_position: (x as f32, y 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) {
|
pub fn render(&mut self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, target: &wgpu::TextureView, width: u32, height: u32) {
|
||||||
// Print texts
|
for (id, text) in self.texts.iter() {
|
||||||
self.print(5, 5, &self.fps_text.clone());
|
|
||||||
|
let text = Text::new(text).with_color(WHITE);
|
||||||
|
self.brush.queue(Section {
|
||||||
|
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()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
self.brush.draw_queued(&device, &mut self.staging_belt, encoder, target, width, height).expect("Draw queued");
|
self.brush.draw_queued(&device, &mut self.staging_belt, encoder, target, width, height).expect("Draw queued");
|
||||||
self.staging_belt.finish();
|
self.staging_belt.finish();
|
||||||
|
|||||||
Reference in New Issue
Block a user