diff options
| -rw-r--r-- | examples/black.rs | 2 | ||||
| -rw-r--r-- | examples/square.rs | 2 | ||||
| -rw-r--r-- | src/config.rs | 32 | ||||
| -rw-r--r-- | src/renderer.rs | 36 |
4 files changed, 52 insertions, 20 deletions
diff --git a/examples/black.rs b/examples/black.rs index 2c55e67..291fafb 100644 --- a/examples/black.rs +++ b/examples/black.rs @@ -9,7 +9,7 @@ fn main() { let config = RenderWindowConfig { //vsync: false, //mode: alligator_render::config::WindowMode::BorderlessFullscreen, - title: "Black Screen.exe".into(), + title: "Black Screen.exe", ..Default::default() }; diff --git a/examples/square.rs b/examples/square.rs index 394d3ca..078d90a 100644 --- a/examples/square.rs +++ b/examples/square.rs @@ -8,7 +8,7 @@ use winit::event_loop::EventLoop; fn main() { // configure the render window let config = RenderWindowConfig { - title: "Pokemon: Black and White (New Edition)".into(), + title: "Pokemon: Black and White (New Edition)", instance_capacity: 1, default_width: NonZeroU32::new(480).unwrap(), default_height: NonZeroU32::new(480).unwrap(), diff --git a/src/config.rs b/src/config.rs index c29a957..312cf91 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,3 @@ -use std::borrow::Cow; use std::num::NonZeroU32; use winit::dpi::{LogicalPosition, LogicalSize}; @@ -60,7 +59,7 @@ pub struct RenderWindowConfig<'a> { /// The window may be fullscreen pub mode: WindowMode, /// The title for the window - pub title: Cow<'a, str>, + pub title: &'a str, /// If true, a low-power device will be selected as the GPU, if possible pub low_power: bool, /// If true, Fifo mode is used to present frames. If false, then Mailbox or @@ -78,7 +77,7 @@ impl<'a> Default for RenderWindowConfig<'a> { default_width: NonZeroU32::new(640).unwrap(), default_height: NonZeroU32::new(480).unwrap(), mode: WindowMode::default(), - title: "Alligator Game".into(), + title: "Alligator Game", low_power: true, vsync: true, instance_capacity: 0, @@ -87,12 +86,27 @@ impl<'a> Default for RenderWindowConfig<'a> { } impl<'a> RenderWindowConfig<'a> { + pub(crate) fn present_mode( + vsync: bool, + supported_modes: &[wgpu::PresentMode], + ) -> wgpu::PresentMode { + if vsync { + wgpu::PresentMode::Fifo + } else if supported_modes.contains(&wgpu::PresentMode::Mailbox) { + wgpu::PresentMode::Mailbox + } else if supported_modes.contains(&wgpu::PresentMode::Immediate) { + wgpu::PresentMode::Immediate + } else { + wgpu::PresentMode::Fifo + } + } + /// Create a `WindowBuilder` from the configuration given. This window is /// initially invisible and must later be made visible. pub(crate) fn to_window(&self) -> WindowBuilder { // start building the window let mut builder = WindowBuilder::new() - .with_title(self.title.as_ref()) + .with_title(self.title) .with_visible(false) .with_inner_size(LogicalSize::new( self.default_width.get(), @@ -143,15 +157,7 @@ impl<'a> RenderWindowConfig<'a> { supported_modes: &[wgpu::PresentMode], texture_format: wgpu::TextureFormat, ) -> wgpu::SurfaceConfiguration { - let present_mode = if self.vsync { - wgpu::PresentMode::Fifo - } else if supported_modes.contains(&wgpu::PresentMode::Mailbox) { - wgpu::PresentMode::Mailbox - } else if supported_modes.contains(&wgpu::PresentMode::Immediate) { - wgpu::PresentMode::Immediate - } else { - wgpu::PresentMode::Fifo - }; + let present_mode = Self::present_mode(self.vsync, supported_modes); // configuration for the surface wgpu::SurfaceConfiguration { diff --git a/src/renderer.rs b/src/renderer.rs index ef2b6db..a15015b 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,4 +1,4 @@ -use std::convert::TryInto; +use std::{convert::TryInto, num::NonZeroU32}; use crate::{instance::InstanceId, vertex::SQUARE, Instance, RenderWindowConfig, Vertex}; use pollster::FutureExt; @@ -38,9 +38,10 @@ pub enum NewRendererError { #[derive(Debug)] pub struct Renderer { surface: wgpu::Surface, + surface_config: wgpu::SurfaceConfiguration, + supported_present_modes: Box<[wgpu::PresentMode]>, device: wgpu::Device, queue: wgpu::Queue, - surface_config: wgpu::SurfaceConfiguration, render_pipeline: wgpu::RenderPipeline, square_vertex_buffer: wgpu::Buffer, square_vertices: u32, @@ -158,6 +159,7 @@ impl Renderer { .expect("there was no device with the selected features"); // configuration for the surface + let supported_present_modes = surface.get_supported_modes(&adapter).into_boxed_slice(); let surface_config = config.to_surface_configuration( &surface.get_supported_modes(&adapter), surface.get_supported_formats(&adapter)[0], @@ -182,9 +184,10 @@ impl Renderer { Ok(Self { surface, + surface_config, + supported_present_modes, device, queue, - surface_config, render_pipeline, square_vertex_buffer, square_vertices, @@ -193,6 +196,10 @@ impl Renderer { }) } + fn reconfigure(&mut self) { + self.surface.configure(&self.device, &self.surface_config); + } + /// Resize just the renderer. The window will remain unchanged fn resize_renderer(&mut self, size: PhysicalSize<u32>) { if size.width == 0 || size.height == 0 { @@ -202,7 +209,26 @@ impl Renderer { self.surface_config.height = size.height; self.surface_config.width = size.width; - self.surface.configure(&self.device, &self.surface_config); + self.reconfigure(); + } + + /// Set the physical window and renderer size + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) { + let size = PhysicalSize::new(width.get(), height.get()); + self.window.set_inner_size(size); + self.resize_renderer(size); + } + + /// Set vsync on or off. See `[RenderWindowConfig::present_mode]` for more details. + pub fn set_vsync(&mut self, vsync: bool) { + self.surface_config.present_mode = + RenderWindowConfig::present_mode(vsync, &self.supported_present_modes); + self.reconfigure(); + } + + /// Set the window's title + pub fn set_title(&mut self, title: &str) { + self.window.set_title(title); } /// Add an instance to the renderer, and returns an `InstanceId` to the @@ -305,7 +331,7 @@ impl Renderer { Ok(_) => {} // reconfigure the surface if it's been lost Err(wgpu::SurfaceError::Lost) => { - self.resize_renderer(self.window.inner_size()); + self.reconfigure(); } // if we ran out of memory, then we'll die Err(wgpu::SurfaceError::OutOfMemory) => { |
