From 90a137167302df85c21066a19d2bca263f233101 Mon Sep 17 00:00:00 2001 From: Imbris Date: Mon, 30 Nov 2020 02:27:36 -0500 Subject: [PATCH] Color! --- voxygen/src/render/error.rs | 7 ++++- voxygen/src/render/renderer.rs | 57 ++++++++++++++++++++++++++++++++-- voxygen/src/run.rs | 3 +- voxygen/src/window.rs | 1 + 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/voxygen/src/render/error.rs b/voxygen/src/render/error.rs index 124335fc99..cfb3daa0e6 100644 --- a/voxygen/src/render/error.rs +++ b/voxygen/src/render/error.rs @@ -11,6 +11,7 @@ pub enum RenderError { } use std::fmt; +// TODO: just impl and use Display? impl fmt::Debug for RenderError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -18,7 +19,11 @@ impl fmt::Debug for RenderError { f.debug_tuple("RequestDeviceError").field(err).finish() }, Self::MappingError(err) => f.debug_tuple("MappingError").field(err).finish(), - Self::SwapChainError(err) => f.debug_tuple("SwapChainError").field(err).finish(), + Self::SwapChainError(err) => f + .debug_tuple("SwapChainError") + // Use Display formatting for this error since they have nice descriptions + .field(&format!("{}", err)) + .finish(), Self::CustomError(err) => f.debug_tuple("CustomError").field(err).finish(), Self::CouldNotFindAdapter => f.debug_tuple("CouldNotFindAdapter").finish(), Self::ErrorInitializingCompiler => f.debug_tuple("ErrorInitializingCompiler").finish(), diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index 2defab1924..c5cffa1e9b 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -151,6 +151,7 @@ pub struct Renderer { queue: wgpu::Queue, swap_chain: wgpu::SwapChain, sc_desc: wgpu::SwapChainDescriptor, + surface: wgpu::Surface, win_depth_view: wgpu::TextureView, @@ -372,6 +373,7 @@ impl Renderer { queue, swap_chain, sc_desc, + surface, win_depth_view, @@ -437,6 +439,13 @@ impl Renderer { pub fn on_resize(&mut self, dims: Vec2) -> Result<(), RenderError> { // Avoid panics when creating texture with w,h of 0,0. if dims.x != 0 && dims.y != 0 { + // Resize swap chain + self.resolution = dims; + self.sc_desc.width = dims.x; + self.sc_desc.height = dims.y; + self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); + + // Resize other render targets let (tgt_color_view, tgt_depth_stencil_view, tgt_color_pp_view, win_depth_view) = Self::create_rt_views(&mut self.device, (dims.x, dims.y), &self.mode)?; self.win_depth_view = win_depth_view; @@ -456,8 +465,6 @@ impl Renderer { }, } } - - self.resolution = dims; } Ok(()) @@ -797,14 +804,58 @@ impl Renderer { /// Perform all queued draw calls for this frame and clean up discarded /// items. - pub fn flush(&mut self) { + pub fn flush(&mut self) -> Result<(), RenderError> { span!(_guard, "flush", "Renderer::flush"); + let frame = match self.swap_chain.get_current_frame() { + Ok(frame) => frame.output, + // If lost recreate the swap chain + Err(err @ wgpu::SwapChainError::Lost) => { + warn!("{}. Recreating swap chain. A frame will be missed", err); + return self.on_resize(self.resolution); + }, + Err(err @ wgpu::SwapChainError::Timeout) => { + warn!("{}. This will probably be resolved on the next frame", err); + return Ok(()); + }, + Err(err @ wgpu::SwapChainError::Outdated) => { + warn!("{}. This will probably be resolved on the next frame", err); + return Ok(()); + }, + Err(err @ wgpu::SwapChainError::OutOfMemory) => return Err(err.into()), + }; + let mut encoder = self + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("A render encoder"), + }); + { + let _render_pas = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { + attachment: &frame.view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color { + r: 0.1, + g: 0.7, + b: 0.3, + a: 1.0, + }), + store: true, + }, + }], + depth_stencil_attachment: None, + }); + } + self.queue.submit(std::iter::once(encoder.finish())); + self.device.poll(wgpu::Maintain::Poll); // If the shaders files were changed attempt to recreate the shaders if self.shaders.reloaded() { self.recreate_pipelines(); } + + Ok(()) } /// Recreate the pipelines diff --git a/voxygen/src/run.rs b/voxygen/src/run.rs index b45de6fb00..6aaf5458c7 100644 --- a/voxygen/src/run.rs +++ b/voxygen/src/run.rs @@ -174,7 +174,8 @@ fn handle_main_events_cleared( // Render the screen using the global renderer last.render(renderer, &global_state.settings); // Finish the frame. - // global_state.window.renderer_mut().flush(); + // TODO: do this as part of dropping rendering thing + global_state.window.renderer_mut().flush().unwrap(); // // Display the frame on the window. // global_state // .window diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index b12e74af63..26475a9823 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -949,6 +949,7 @@ impl Window { .push(Event::Resize(Vec2::new(width as u32, height as u32))); }, WindowEvent::ScaleFactorChanged { scale_factor, .. } => { + // TODO: is window resized event emitted? or do we need to handle that here? self.scale_factor = scale_factor; self.events.push(Event::ScaleFactorChanged(scale_factor)); },