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
+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 }
}
+17 -8
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,18 +33,21 @@ 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();
let swapchain_desc = wgpu::SwapChainDescriptor {
@@ -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);