forked from nonsensical-dev/zenyx-engine
formatting
This commit is contained in:
parent
75a855bb9f
commit
e106242d41
15 changed files with 540 additions and 626 deletions
|
@ -6,9 +6,12 @@ use std::time::Instant;
|
|||
use cgmath::{Deg, Matrix4, Point3, Rad, SquareMatrix, Vector3, perspective};
|
||||
use futures::executor::block_on;
|
||||
use thiserror::Error;
|
||||
use tracing::{error, trace};
|
||||
use tracing::{error, info, trace};
|
||||
use wgpu::TextureUsages;
|
||||
use wgpu::{Backends, InstanceDescriptor, util::DeviceExt};
|
||||
use wgpu_text::glyph_brush::ab_glyph::FontRef;
|
||||
use wgpu_text::glyph_brush::{HorizontalAlign, Layout, OwnedSection, OwnedText, VerticalAlign};
|
||||
use wgpu_text::{BrushBuilder, TextBrush};
|
||||
use winit::window::Window;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
@ -129,50 +132,7 @@ impl From<wgpu::RequestDeviceError> for RenderContextError {
|
|||
}
|
||||
}
|
||||
|
||||
const SHADER_SRC: &str = r#"
|
||||
struct CameraUniform {
|
||||
view: mat4x4<f32>,
|
||||
proj: mat4x4<f32>,
|
||||
};
|
||||
|
||||
struct ModelUniform {
|
||||
model: mat4x4<f32>,
|
||||
};
|
||||
|
||||
@group(0) @binding(0)
|
||||
var<uniform> camera: CameraUniform;
|
||||
|
||||
@group(1) @binding(0)
|
||||
var<uniform> model: ModelUniform;
|
||||
|
||||
struct VertexInput {
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) normal: vec3<f32>,
|
||||
};
|
||||
|
||||
@vertex
|
||||
fn vs_main(input: VertexInput) -> VertexOutput {
|
||||
var output: VertexOutput;
|
||||
let model_pos = model.model * vec4<f32>(input.position, 1.0);
|
||||
output.clip_position = camera.proj * camera.view * model_pos;
|
||||
output.normal = input.normal;
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let ambient: f32 = 0.2;
|
||||
let light_dir = normalize(vec3<f32>(0.5, 1.0, 0.5));
|
||||
let diffuse = clamp(dot(normalize(input.normal), light_dir), 0.0, 1.0);
|
||||
let brightness = ambient + (1.0 - ambient) * diffuse;
|
||||
return vec4<f32>(0.7 * brightness, 0.7 * brightness, 0.9 * brightness, 1.0);
|
||||
}
|
||||
"#;
|
||||
const SHADER_SRC: &str = include_str!("shader.wgsl");
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
|
@ -284,7 +244,7 @@ struct Model {
|
|||
index_buffer: wgpu::Buffer,
|
||||
uniform_buffer: wgpu::Buffer,
|
||||
bind_group: wgpu::BindGroup,
|
||||
index_count: u32, // Changed from vertex_count to index_count
|
||||
index_count: u32,
|
||||
transform: Matrix4<f32>,
|
||||
}
|
||||
|
||||
|
@ -359,6 +319,15 @@ pub struct Renderer<'window> {
|
|||
start_time: Instant,
|
||||
last_frame_instant: Instant,
|
||||
frame_count: u32,
|
||||
fps: f32,
|
||||
font_state: FontState,
|
||||
}
|
||||
|
||||
struct FontState {
|
||||
brush: TextBrush<FontRef<'static>>,
|
||||
section: OwnedSection,
|
||||
scale: f32,
|
||||
color: wgpu::Color,
|
||||
}
|
||||
|
||||
impl<'window> Renderer<'window> {
|
||||
|
@ -485,7 +454,6 @@ impl<'window> Renderer<'window> {
|
|||
multiview: None,
|
||||
cache: None,
|
||||
});
|
||||
|
||||
|
||||
let camera = Camera::new(&device, &camera_bind_group_layout, width, height);
|
||||
|
||||
|
@ -508,6 +476,36 @@ impl<'window> Renderer<'window> {
|
|||
// surface_config.format,
|
||||
);
|
||||
|
||||
let font_bytes = include_bytes!("DejaVuSans.ttf");
|
||||
let font = FontRef::try_from_slice(font_bytes).map_err(|e| {
|
||||
RenderContextError::new(
|
||||
ContextErrorKind::DeviceRequest,
|
||||
Some("Font loading".into()),
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
|
||||
let brush =
|
||||
BrushBuilder::using_font(font).build(&device, width, height, surface_config.format);
|
||||
let base_width = 1280.0;
|
||||
let base_scale = 30.0;
|
||||
let scale = base_scale * (surface_config.width as f32 / base_width as f32).clamp(0.5, 2.0);
|
||||
let color = wgpu::Color::WHITE;
|
||||
|
||||
let section = OwnedSection::default()
|
||||
.add_text(OwnedText::new("FPS: 0.00").with_scale(scale).with_color([
|
||||
color.r as f32,
|
||||
color.g as f32,
|
||||
color.b as f32,
|
||||
color.a as f32,
|
||||
]))
|
||||
.with_screen_position((10.0, 10.0))
|
||||
.with_bounds((base_scale * 200.0, base_scale * 2.0))
|
||||
.with_layout(
|
||||
Layout::default()
|
||||
.h_align(HorizontalAlign::Left)
|
||||
.v_align(VerticalAlign::Top),
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
device,
|
||||
|
@ -530,6 +528,13 @@ impl<'window> Renderer<'window> {
|
|||
frame_count: 0,
|
||||
depth_texture,
|
||||
depth_texture_view,
|
||||
fps: 0f32,
|
||||
font_state: FontState {
|
||||
brush,
|
||||
section,
|
||||
scale,
|
||||
color,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -549,12 +554,19 @@ impl<'window> Renderer<'window> {
|
|||
|
||||
pub fn resize(&mut self, new_size: (u32, u32)) {
|
||||
let (width, height) = new_size;
|
||||
let (depth_texture,depth_view) = create_depth_texture(&self.device, width, height);
|
||||
let (depth_texture, depth_view) = create_depth_texture(&self.device, width, height);
|
||||
self.surface_config.width = width.max(1);
|
||||
self.surface_config.height = height.max(1);
|
||||
self.surface.configure(&self.device, &self.surface_config);
|
||||
self.depth_texture = depth_texture;
|
||||
self.depth_texture_view = depth_view;
|
||||
self.font_state
|
||||
.brush
|
||||
.resize_view(width as f32, height as f32, &self.queue);
|
||||
let base_width = 1280.0;
|
||||
let base_scale = 30.0;
|
||||
let scale = base_scale * (width as f32 / base_width as f32).clamp(0.5, 2.0);
|
||||
self.font_state.scale = scale;
|
||||
self.camera.resize(width, height);
|
||||
}
|
||||
|
||||
|
@ -565,7 +577,8 @@ impl<'window> Renderer<'window> {
|
|||
|
||||
for (i, model) in self.models.iter_mut().enumerate() {
|
||||
let angle = Rad(elapsed * 0.8 + i as f32 * 0.3);
|
||||
model.set_transform(Matrix4::from_angle_x(angle) * Matrix4::from_angle_y(angle));
|
||||
model.set_transform(Matrix4::from_angle_y(angle));
|
||||
// model.set_transform(Matrix4::from_angle_x(angle) * Matrix4::from_angle_y(angle));
|
||||
model.update(&self.queue);
|
||||
}
|
||||
|
||||
|
@ -587,6 +600,25 @@ impl<'window> Renderer<'window> {
|
|||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("Render Encoder"),
|
||||
});
|
||||
let fps_text = format!("FPS: {:.2}", self.fps);
|
||||
self.font_state.section.text.clear();
|
||||
self.font_state.section.text.push(
|
||||
OwnedText::new(fps_text)
|
||||
.with_scale(self.font_state.scale)
|
||||
.with_color([
|
||||
self.font_state.color.r as f32,
|
||||
self.font_state.color.g as f32,
|
||||
self.font_state.color.b as f32,
|
||||
self.font_state.color.a as f32,
|
||||
]),
|
||||
);
|
||||
if let Err(e) = self.font_state.brush.queue(
|
||||
&self.device,
|
||||
&self.queue,
|
||||
&[self.font_state.section.clone()],
|
||||
) {
|
||||
error!("Failed to queue text: {}", e);
|
||||
}
|
||||
|
||||
{
|
||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
|
@ -622,15 +654,35 @@ impl<'window> Renderer<'window> {
|
|||
render_pass.draw_indexed(0..model.index_count, 0, 0..1);
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut text_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("Text Render Pass"),
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
occlusion_query_set: None,
|
||||
timestamp_writes: None,
|
||||
});
|
||||
|
||||
self.font_state.brush.draw(&mut text_pass);
|
||||
}
|
||||
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
surface_texture.present();
|
||||
|
||||
self.frame_count += 1;
|
||||
|
||||
let elapsed_secs = self.last_frame_instant.elapsed().as_secs_f32();
|
||||
if elapsed_secs >= 1.0 {
|
||||
let fps = self.frame_count as f32 / elapsed_secs;
|
||||
trace!("FPS: {:.2}", fps);
|
||||
// trace!("Renderer FPS: {:.2}", fps);
|
||||
self.fps = fps;
|
||||
self.frame_count = 0;
|
||||
self.last_frame_instant = Instant::now();
|
||||
}
|
||||
|
@ -640,8 +692,14 @@ impl<'window> Renderer<'window> {
|
|||
self.bg_color = color;
|
||||
}
|
||||
|
||||
pub fn bg_color(&self) -> wgpu::Color {
|
||||
self.bg_color
|
||||
pub fn bg_color(&self) -> &wgpu::Color {
|
||||
&self.bg_color
|
||||
}
|
||||
pub fn text_color(&self) -> &wgpu::Color {
|
||||
&self.font_state.color
|
||||
}
|
||||
pub fn set_text_color(&mut self, color: wgpu::Color) {
|
||||
self.font_state.color = color;
|
||||
}
|
||||
}
|
||||
fn create_depth_texture(
|
||||
|
@ -670,4 +728,4 @@ fn create_depth_texture(
|
|||
let texture = device.create_texture(&desc);
|
||||
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
(texture, view)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue