Fonts, glyphs, displaying fps
This commit is contained in:
+6
-4
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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())) }
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -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
@@ -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(())
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
use crate::renderer::buffers::Buffers;
|
||||
|
||||
pub struct UserInterfacePass {
|
||||
pub pipeline: wgpu::RenderPipeline
|
||||
}
|
||||
|
||||
impl UserInterfacePass {
|
||||
|
||||
}
|
||||
@@ -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.
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user