summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicha White <botahamec@outlook.com>2022-09-20 10:50:08 -0400
committerMicha White <botahamec@outlook.com>2022-09-20 10:50:08 -0400
commit1b65982f87856af2b14ac2eefe666316b2d05c82 (patch)
tree7c72b4865286406d29aea496ee0a5fe3f54145ae
parent3fbde7b0807d1aff50fef058db6e73b090669875 (diff)
Added some runtime configuration methods
-rw-r--r--examples/black.rs2
-rw-r--r--examples/square.rs2
-rw-r--r--src/config.rs32
-rw-r--r--src/renderer.rs36
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) => {