From 97b53bb2b7431f9a830b7624165912b808430d7d Mon Sep 17 00:00:00 2001 From: BreakingLead Date: Fri, 31 May 2024 01:51:34 +0800 Subject: [PATCH] add wireframe rendering mode (press F1) --- blockworld-client/io/input_helper.rs | 4 +- blockworld-client/render/draw.rs | 112 ++++++++++-------------- blockworld-client/render/mod.rs | 2 + blockworld-client/render/window_init.rs | 11 ++- 4 files changed, 57 insertions(+), 72 deletions(-) diff --git a/blockworld-client/io/input_helper.rs b/blockworld-client/io/input_helper.rs index 9ad55e5..53eb076 100644 --- a/blockworld-client/io/input_helper.rs +++ b/blockworld-client/io/input_helper.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use winit::{ event::{ElementState, KeyEvent}, - keyboard::Key, + keyboard::{Key, NamedKey}, }; /// Tracker for the pressing keys @@ -16,7 +16,7 @@ impl InputState { self.pressing_keys.contains(&key) } - pub fn handle_event(&mut self, event: &KeyEvent) { + pub fn handle_event<'a>(&mut self, event: &'a KeyEvent) { let key = &event.logical_key; match event.state { ElementState::Pressed => { diff --git a/blockworld-client/render/draw.rs b/blockworld-client/render/draw.rs index 834aa92..74e14dc 100644 --- a/blockworld-client/render/draw.rs +++ b/blockworld-client/render/draw.rs @@ -32,7 +32,10 @@ use crate::{ BootArgs, }; -use super::render_chunk::RenderChunk; +use super::{ + pipeline::{RegularPipeline, WireframePipeline}, + render_chunk::RenderChunk, +}; /// state contains all things the game needs pub struct State<'a> { @@ -43,7 +46,8 @@ pub struct State<'a> { pub queue: wgpu::Queue, pub config: wgpu::SurfaceConfiguration, pub size: winit::dpi::PhysicalSize, - pub render_pipeline: wgpu::RenderPipeline, + pub main_pipeline: RegularPipeline, + pub wireframe_pipeline: WireframePipeline, pub render_chunk: RenderChunk, @@ -76,6 +80,9 @@ pub struct State<'a> { pub settings: Settings<'a>, pub register_table: RegisterTable, + + // Debug + pub debug_mode: bool, } impl<'a> State<'a> { @@ -126,7 +133,7 @@ impl<'a> State<'a> { .request_device( &wgpu::DeviceDescriptor { label: None, - required_features: wgpu::Features::empty(), + required_features: wgpu::Features::POLYGON_MODE_LINE, required_limits: wgpu::Limits::default(), }, None, @@ -190,7 +197,7 @@ impl<'a> State<'a> { binding: 30, resource: matrix_buffer.as_entire_binding(), }], - label: Some("camera_bind_group"), + label: Some("Blockworld Prespective Matrix Bind Group"), }); // \------------------- @@ -247,58 +254,23 @@ impl<'a> State<'a> { // \------------------- let shader = device.create_shader_module(include_wgsl!("shaders/default_shader.wgsl")); + let wireframe_shader = + device.create_shader_module(include_wgsl!("shaders/debug_shader.wgsl")); - let render_pipeline_layout = - device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout, &matrix_bind_group_layout], - push_constant_ranges: &[], - }); + let main_pipeline = RegularPipeline::new( + &device, + &[&texture_bind_group_layout, &matrix_bind_group_layout], + &shader, + &config, + ); - let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: Some("Render Pipeline"), - layout: Some(&render_pipeline_layout), - vertex: wgpu::VertexState { - module: &shader, - entry_point: "vs_main", - buffers: &[Vertex::desc()], - compilation_options: Default::default(), - }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: "fs_main", - targets: &[Some(wgpu::ColorTargetState { - format: config.format, - blend: Some(wgpu::BlendState::REPLACE), - write_mask: wgpu::ColorWrites::ALL, - })], - compilation_options: Default::default(), - }), - primitive: wgpu::PrimitiveState { - topology: wgpu::PrimitiveTopology::TriangleList, - strip_index_format: None, - front_face: wgpu::FrontFace::Ccw, - cull_mode: Some(wgpu::Face::Back), - unclipped_depth: false, - polygon_mode: wgpu::PolygonMode::Fill, - conservative: false, - }, - depth_stencil: Some(wgpu::DepthStencilState { - format: wgpu::TextureFormat::Depth32Float, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, - stencil: wgpu::StencilState::default(), - bias: wgpu::DepthBiasState::default(), - }), - multisample: wgpu::MultisampleState { - count: 1, - mask: !0, - alpha_to_coverage_enabled: false, - }, - multiview: None, - }); + let wireframe_pipeline = WireframePipeline::new( + &device, + &[&texture_bind_group_layout, &matrix_bind_group_layout], + &wireframe_shader, + &config, + ); - dbg!("Help me!"); // ------------------- // | Game Initialize | // ------------------- @@ -356,7 +328,6 @@ impl<'a> State<'a> { .with_screen_position((50.0, config.height as f32 * 0.5)) .to_owned(); - dbg!("Help me!"); Ok(Self { window, @@ -365,7 +336,8 @@ impl<'a> State<'a> { queue, config, size, - render_pipeline, + main_pipeline, + wireframe_pipeline, texture, texture_bind_group, @@ -391,6 +363,7 @@ impl<'a> State<'a> { game, register_table, + debug_mode: false, }) } @@ -439,6 +412,7 @@ impl<'a> State<'a> { // Camera Update self.camera.update(&self.game.player_state); + self.matrix_uniform.update_matrix(&self.camera); self.queue.write_buffer( &self.matrix_buffer, @@ -457,21 +431,15 @@ impl<'a> State<'a> { let mut encoder = self .device .create_command_encoder(&wgpu::CommandEncoderDescriptor { - label: Some("Render Encoder"), + label: Some("Blockworld Render Encoder"), }); - // match self - // .brush - // .queue(&self.device, &self.queue, vec![self.fps_text_section]) - // { - // Ok(_) => (), - // Err(err) => { - // panic!("{err}"); - // } - // }; + // self.brush + // .queue(&self.device, &self.queue, vec![&self.fps_text_section]) + // .unwrap(); { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: Some("Render Pass"), + label: Some("Blockworld Render Pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { view: &view, resolve_target: None, @@ -496,14 +464,22 @@ impl<'a> State<'a> { timestamp_writes: None, occlusion_query_set: None, }); - render_pass.set_pipeline(&self.render_pipeline); + + // check debug mode + if self.debug_mode { + // render with wireframe + render_pass.set_pipeline(&self.wireframe_pipeline.pipeline); + } else { + // render with texture + render_pass.set_pipeline(&self.main_pipeline.pipeline); + } render_pass.set_bind_group(0, &self.texture_bind_group, &[]); render_pass.set_bind_group(1, &self.matrix_bind_group, &[]); render_pass.set_vertex_buffer(0, self.render_chunk.vertex_buffer.slice(..)); - self.brush.draw(&mut render_pass); render_pass.draw(0..self.render_chunk.vertex_count, 0..1); + self.brush.draw(&mut render_pass); } self.queue.submit(std::iter::once(encoder.finish())); diff --git a/blockworld-client/render/mod.rs b/blockworld-client/render/mod.rs index 6c0d1d6..4941db2 100644 --- a/blockworld-client/render/mod.rs +++ b/blockworld-client/render/mod.rs @@ -1,8 +1,10 @@ pub mod camera; pub mod draw; +pub mod pipeline; pub mod render_block; pub mod render_chunk; pub mod render_chunk_pool; pub mod texture; +pub mod uniform_utils; pub mod vertex; pub mod window_init; diff --git a/blockworld-client/render/window_init.rs b/blockworld-client/render/window_init.rs index c804ef7..8e0ad05 100644 --- a/blockworld-client/render/window_init.rs +++ b/blockworld-client/render/window_init.rs @@ -4,9 +4,9 @@ use anyhow::*; use clap::Parser; use log::*; use winit::application::ApplicationHandler; -use winit::event::{DeviceEvent, WindowEvent}; +use winit::event::{DeviceEvent, ElementState, WindowEvent}; use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop}; -use winit::keyboard::KeyCode; +use winit::keyboard::{Key, KeyCode, NamedKey}; use winit::window::WindowId; impl<'a> ApplicationHandler for State<'a> { @@ -64,6 +64,13 @@ impl<'a> ApplicationHandler for State<'a> { event_loop.exit(); } self.input_state.handle_event(&event); + let key = event.logical_key; + + // ! NOT IDEAL + // ! FIX LATER + if key == Key::Named(NamedKey::F1) && event.state == ElementState::Released { + self.debug_mode = !self.debug_mode; + } } _ => (), }