Fonts, glyphs, displaying fps

This commit is contained in:
Piotrek
2021-05-07 15:41:08 +02:00
parent c089afbcbe
commit 989b75f54d
12 changed files with 252 additions and 75 deletions
Generated
+123 -2
View File
@@ -1,5 +1,15 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "ab_glyph"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a933731feda8b460bdad9a9e43bb386baba6ec593d2bc19716ef3c75c09085c"
dependencies = [
"ab_glyph_rasterizer",
"owned_ttf_parser 0.12.0",
]
[[package]]
name = "ab_glyph_rasterizer"
version = "0.1.4"
@@ -816,6 +826,45 @@ dependencies = [
"web-sys",
]
[[package]]
name = "glyph_brush"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e3f00b8574a76fb6c50890c48da03946ca50e4372a2778737922666a2238221"
dependencies = [
"glyph_brush_draw_cache",
"glyph_brush_layout",
"log",
"ordered-float",
"rustc-hash",
"twox-hash",
]
[[package]]
name = "glyph_brush_draw_cache"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac2c82074cafb68b9e459c50c655f7eedcb92d6ee7166813802934bc6fc29fa3"
dependencies = [
"ab_glyph",
"crossbeam-channel",
"crossbeam-deque",
"linked-hash-map",
"rayon",
"rustc-hash",
]
[[package]]
name = "glyph_brush_layout"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10bc06d530bf20c1902f1b02799ab7372ff43f6119770c49b0bc3f21bd148820"
dependencies = [
"ab_glyph",
"approx",
"xi-unicode",
]
[[package]]
name = "gpu-alloc"
version = "0.3.0"
@@ -1025,6 +1074,12 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "lock_api"
version = "0.4.3"
@@ -1373,13 +1428,31 @@ version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]]
name = "ordered-float"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b50b8919aecb97e5ee9aceef27e24f39c46b11831130f4a6b7b091ec5de0de12"
dependencies = [
"num-traits",
]
[[package]]
name = "owned_ttf_parser"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3"
dependencies = [
"ttf-parser",
"ttf-parser 0.6.2",
]
[[package]]
name = "owned_ttf_parser"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a3c7a20e3f122223e68eef6ca58e39bc1ea8a1d83418ba4c2c1ba189d2ee355"
dependencies = [
"ttf-parser 0.12.0",
]
[[package]]
@@ -1637,6 +1710,12 @@ dependencies = [
"bitflags",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rusttype"
version = "0.9.2"
@@ -1644,7 +1723,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59"
dependencies = [
"ab_glyph_rasterizer",
"owned_ttf_parser",
"owned_ttf_parser 0.6.0",
]
[[package]]
@@ -1758,6 +1837,12 @@ dependencies = [
"num-traits",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "storage-map"
version = "0.3.0"
@@ -1868,6 +1953,23 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc"
[[package]]
name = "ttf-parser"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e00391c1f3d171490a3f8bd79999b0002ae38d3da0d6a3a306c754b053d71b"
[[package]]
name = "twox-hash"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
dependencies = [
"cfg-if 0.1.10",
"rand 0.7.3",
"static_assertions",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
@@ -2117,6 +2219,18 @@ dependencies = [
"bitflags",
]
[[package]]
name = "wgpu_glyph"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "354c1f79e09923724a6006a6953c3946522b84f7a9ec202b7e8001f274fd4bd5"
dependencies = [
"bytemuck",
"glyph_brush",
"log",
"wgpu",
]
[[package]]
name = "wgpufun"
version = "0.1.0"
@@ -2133,6 +2247,7 @@ dependencies = [
"rand 0.8.3",
"shaderc",
"wgpu",
"wgpu_glyph",
"winit",
]
@@ -2256,6 +2371,12 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
[[package]]
name = "xi-unicode"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a"
[[package]]
name = "xml-rs"
version = "0.8.3"
+2
View File
@@ -9,6 +9,7 @@ edition = "2018"
[dependencies]
winit = "0.24"
wgpu = "0.7"
wgpu_glyph = "0.11"
futures = "0.3"
bytemuck = { version = "1.5", features = [ "derive" ] }
byteorder = "1.4"
@@ -17,6 +18,7 @@ cgmath = "0.18"
rand = "0.8"
noise = "0.7"
[build-dependencies]
anyhow = "1.0"
fs_extra = "1.1"
BIN
View File
Binary file not shown.
+6 -4
View File
@@ -23,7 +23,7 @@ fn main() {
.build(&events)
.expect("Failed to create window");
let mut renderer = futures::executor::block_on(Renderer::new(&window));
let mut renderer = Renderer::new(&window);
let mut app = App::new(&mut renderer);
// Stats
@@ -84,9 +84,11 @@ fn main() {
// Display FPS
let elapsed = fps_timer.elapsed().as_secs_f64();
if elapsed >= 1.5 {
let fps = (fps_counter as f64) / elapsed;
println!("FPS: {}", (fps*100.0_f64).floor()/100.0);
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);
fps_timer = std::time::Instant::now();
fps_counter = 0;
}
-9
View File
@@ -20,7 +20,6 @@ pub struct Content {
impl Content {
pub fn new(device: &wgpu::Device) -> Self {
// Create node buffer
let node_buffer = vec![0_u32; (NODE_TEX_SIZE*NODE_TEX_SIZE*NODE_TEX_SIZE) as usize].into_boxed_slice();
@@ -43,10 +42,6 @@ impl Content {
);
// Bind layout
// let sampler_entry = wgpu::BindGroupLayoutEntry {
// binding: 0,visibility: wgpu::ShaderStage::FRAGMENT, count: None,
// ty: wgpu::BindingType::Sampler { comparison: false, filtering: false },
// };
let texture_entry = wgpu::BindGroupLayoutEntry {
binding: 0, visibility: wgpu::ShaderStage::FRAGMENT, count: None,
ty: wgpu::BindingType::Texture { multisampled: false, view_dimension: wgpu::TextureViewDimension::D3, sample_type: wgpu::TextureSampleType::Uint },
@@ -56,8 +51,6 @@ impl Content {
label: None, entries: &[
wgpu::BindGroupLayoutEntry { binding: 0, ..texture_entry },
wgpu::BindGroupLayoutEntry { binding: 1, ..texture_entry },
//wgpu::BindGroupLayoutEntry { binding: 2, ..sampler_entry },
//wgpu::BindGroupLayoutEntry { binding: 3, ..sampler_entry },
],
}
);
@@ -69,8 +62,6 @@ impl Content {
entries: &[
wgpu::BindGroupEntry { binding: 0, resource: wgpu::BindingResource::TextureView(&node_texture.create_view(&wgpu::TextureViewDescriptor::default())) },
wgpu::BindGroupEntry { binding: 1, resource: wgpu::BindingResource::TextureView(&block_texture.create_view(&wgpu::TextureViewDescriptor::default())) },
//wgpu::BindGroupEntry { binding: 2, resource: wgpu::BindingResource::Sampler(&device.create_sampler(&Default::default())) },
//wgpu::BindGroupEntry { binding: 3, resource: wgpu::BindingResource::Sampler(&device.create_sampler(&Default::default())) }
],
}
);
+20 -26
View File
@@ -37,39 +37,33 @@ impl Materials {
// Create buffer
let buffer = device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("Materials buffer"),
contents: bytemuck::cast_slice(&materials),
label: Some("Materials buffer"), contents: bytemuck::cast_slice(&materials),
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
}
);
// Create bind group
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}
// Bind layout
let buffer_entry = wgpu::BindGroupLayoutEntry {
binding: 0, visibility: wgpu::ShaderStage::FRAGMENT, count: None,
ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, min_binding_size: None },
};
let bind_layout = device.create_bind_group_layout(
&wgpu::BindGroupLayoutDescriptor {
label: None, entries: &[
wgpu::BindGroupLayoutEntry { binding: 0, ..buffer_entry },
],
label: Some("Materials buffer layout"),
});
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: buffer.as_entire_binding(),
}
],
label: Some("Materials buffer group"),
});
// Bind group
let bind_group = device.create_bind_group(
&wgpu::BindGroupDescriptor {
label: Some("Materials buffer group"),layout: &bind_layout,
entries: &[
wgpu::BindGroupEntry { binding: 0, resource: buffer.as_entire_binding() }
],
}
);
// Done
Materials { buffer, materials, bind_layout, bind_group }
}
+18 -25
View File
@@ -47,39 +47,32 @@ impl Uniform {
// Create buffer
let buffer = device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("Uniform buffer"),
contents: bytemuck::cast_slice(&[values]),
label: Some("Uniform buffer"), contents: bytemuck::cast_slice(&[values]),
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
}
);
// Create bind group
// Bind layout
let buffer_entry = wgpu::BindGroupLayoutEntry {
binding: 0, visibility: wgpu::ShaderStage::FRAGMENT, count: None,
ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, min_binding_size: None },
};
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}
label: None, entries: &[
wgpu::BindGroupLayoutEntry { binding: 0, ..buffer_entry }
],
label: Some("Uniform buffer layout"),
});
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: buffer.as_entire_binding(),
}
],
label: Some("Uniform buffer group"),
});
// Bind group
let bind_group = device.create_bind_group(
&wgpu::BindGroupDescriptor {
label: None, layout: &bind_layout,
entries: &[
wgpu::BindGroupEntry { binding: 0, resource: buffer.as_entire_binding(), }
],
}
);
// Done
Uniform { buffer, values, bind_layout, bind_group }
}
+16 -7
View File
@@ -1,3 +1,4 @@
use wgpu_glyph::Text;
use winit::{window::Window, dpi::PhysicalSize};
pub mod buffers;
use buffers::Buffers;
@@ -6,6 +7,8 @@ use passes::{RaytracePass, PostprocessPass};
pub mod camera;
use camera::Camera;
pub mod content_view;
mod ui;
use ui::UserInterface;
pub struct Renderer {
surface: wgpu::Surface,
@@ -17,6 +20,7 @@ pub struct Renderer {
texture: wgpu::TextureView,
raytrace_pass: RaytracePass,
postprocess_pass: PostprocessPass,
pub ui: UserInterface,
// Buffers
buffers: Buffers,
// Other
@@ -29,17 +33,20 @@ impl Renderer {
/*
* Initializes renderer and all buffers
*/
pub async fn new(window: &Window) -> Self {
pub fn new(window: &Window) -> Self {
// Create surface
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
let surface = unsafe { instance.create_surface(window) };
// Pick and initialize device
let adapter_options = wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::HighPerformance, compatible_surface: Some(&surface) };
let adapter = instance.request_adapter(&adapter_options).await.unwrap();
let device_desc = wgpu::DeviceDescriptor { features: wgpu::Features::empty(), limits: wgpu::Limits::default(), label: None };
let (device, queue) = adapter.request_device(&device_desc, None).await.unwrap();
let (adapter, mut device, queue) = futures::executor::block_on(async {
let adapter_options = wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::HighPerformance, compatible_surface: Some(&surface) };
let adapter = instance.request_adapter(&adapter_options).await.unwrap();
let device_desc = wgpu::DeviceDescriptor { features: wgpu::Features::empty(), limits: wgpu::Limits::default(), label: None };
let (device, queue) = adapter.request_device(&device_desc, None).await.unwrap();
(adapter, device, queue)
});
// Create swapchain
let window_size = window.inner_size();
@@ -75,12 +82,13 @@ impl Renderer {
let buffers = Buffers::new(&device);
let raytrace_pass = RaytracePass::new(&device, &swapchain_desc, &buffers);
let postprocess_pass = PostprocessPass::new(&device, &swapchain_desc, &texture);
let ui = UserInterface::new(&mut device, swapchain_desc.format);
// Other
let start = std::time::Instant::now();
println!("Renderer initialized");
Self { surface, device, queue, swapchain_desc, swapchain, texture, raytrace_pass, postprocess_pass, buffers, camera, start }
Self { surface, device, queue, swapchain_desc, swapchain, texture, raytrace_pass, postprocess_pass, ui, buffers, camera, start }
}
/*
@@ -114,12 +122,13 @@ impl Renderer {
// Create encoder that will build command buffer for us
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Render Encoder"),});
self.raytrace_pass.render(&mut encoder, &mut self.buffers, &self.texture);//&frame.view);
self.postprocess_pass.render(&mut encoder, &frame.view);
self.ui.render(&self.device, &mut encoder, &frame.view, 1280, 720);
// Submit encoder (command buffer)
self.queue.submit(std::iter::once(encoder.finish()));
self.ui.recall();
// Return ok
Ok(())
+9
View File
@@ -0,0 +1,9 @@
use crate::renderer::buffers::Buffers;
pub struct UserInterfacePass {
pub pipeline: wgpu::RenderPipeline
}
impl UserInterfacePass {
}
+56
View File
@@ -0,0 +1,56 @@
use wgpu_glyph::{GlyphBrush, ab_glyph::FontArc, GlyphBrushBuilder, Section, Text};
use wgpu::util::StagingBelt;
use futures::executor::LocalPool;
use futures::task::SpawnExt;
const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
pub struct UserInterface {
// Glyph drawing
staging_belt: StagingBelt,
local_pool: LocalPool,
brush: GlyphBrush<()>,
// Texts
fps_text: String
}
impl UserInterface {
pub fn new(device: &mut wgpu::Device, render_format: wgpu::TextureFormat) -> Self {
let font = FontArc::try_from_slice(include_bytes!("../../assets/font.ttf")).unwrap();
Self {
staging_belt: StagingBelt::new(1024),
local_pool: LocalPool::new(),
brush: GlyphBrushBuilder::using_font(font).build(device, render_format),
fps_text: "-".to_string()
}
}
fn print(&mut self, x: u32, y: u32, msg: &str) {
let text = Text::new(msg).with_color(WHITE);
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) {
// 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();
}
pub fn recall(&mut self) {
// Reset staging belt after drawing
self.local_pool.spawner().spawn(self.staging_belt.recall()).expect("Recall staging belt");
self.local_pool.run_until_stalled();
}
}
Binary file not shown.
+1 -1
View File
@@ -36,7 +36,7 @@ vec3 solve()
// Calculate ray direction
vec3 view_dir = (_ProjMatrixInv * vec4(_InUV, 0, 1)).xyz;
vec3 rayDir = normalize(_ViewMatrix * vec4(view_dir,0)).xyz;
Ray primaryRay = Ray((_CamPos + vec3(16, 0, 16)) / SCALE, rayDir);
Ray primaryRay = Ray(_CamPos / SCALE, rayDir);
// Raycast
HitResult primary = castNodes(primaryRay, 100);