treewide: bump dependencies (#60)
This commit is contained in:
parent
db8f6bb356
commit
246375f0e9
|
@ -1,7 +1,7 @@
|
||||||
language: rust
|
language: rust
|
||||||
rust:
|
rust:
|
||||||
# MSRV
|
# MSRV
|
||||||
- 1.36.0
|
- 1.40.0
|
||||||
|
|
||||||
# Stable release channel
|
# Stable release channel
|
||||||
- stable
|
- stable
|
||||||
|
|
27
Cargo.toml
27
Cargo.toml
|
@ -23,26 +23,27 @@ travis-ci = { repository = "parasyte/pixels" }
|
||||||
maintenance = { status = "actively-developed" }
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
thiserror = "1.0"
|
thiserror = "1.0.15"
|
||||||
wgpu = "0.4"
|
wgpu = "0.5.0"
|
||||||
|
futures = "0.3"
|
||||||
|
|
||||||
# These are only used by the examples, and enabled with features
|
# These are only used by the examples, and enabled with features
|
||||||
# See: https://github.com/rust-lang/cargo/issues/1982
|
# See: https://github.com/rust-lang/cargo/issues/1982
|
||||||
beryllium = { version = " 0.1", optional = true }
|
beryllium = { version = "0.2.1", features = [ "extern_crate_raw_window_handle" ], optional = true }
|
||||||
byteorder = { version = "1.3", optional = true }
|
byteorder = { version = "1.3.4", optional = true }
|
||||||
env_logger = { version = "0.7", optional = true }
|
env_logger = { version = "0.7.1", optional = true }
|
||||||
getrandom = { version = "0.1", optional = true }
|
getrandom = { version = "0.1.14", optional = true }
|
||||||
gilrs = { version = "0.7", optional = true }
|
gilrs = { version = "0.7.4", optional = true }
|
||||||
line_drawing = { version = "0.8", optional = true }
|
line_drawing = { version = "0.8.0", optional = true }
|
||||||
log = { version = "0.4", features = ["release_max_level_warn"], optional = true }
|
log = { version = "0.4.8", features = [ "release_max_level_warn" ], optional = true }
|
||||||
randomize = { version = "3.0", optional = true }
|
randomize = { version = "3.0.1", optional = true }
|
||||||
simple-invaders = { path = "simple-invaders", optional = true }
|
simple-invaders = { path = "simple-invaders", optional = true }
|
||||||
winit = { version = "=0.20.0-alpha4", optional = true }
|
winit = { version = "0.22.0", optional = true }
|
||||||
winit_input_helper = { version = "=0.4.0-alpha4", optional = true }
|
winit_input_helper = { version = "0.6.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pixels-mocks = { path = "pixels-mocks" }
|
pixels-mocks = { path = "pixels-mocks" }
|
||||||
winit = "=0.20.0-alpha4"
|
winit = "0.22.0"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "conway"
|
name = "conway"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use pixels::{Error, Pixels, SurfaceTexture};
|
use pixels::{Error, Pixels, SurfaceTexture};
|
||||||
use winit::dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
use winit::dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||||
use winit::event::{Event, VirtualKeyCode, WindowEvent};
|
use winit::event::{Event, VirtualKeyCode};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop};
|
use winit::event_loop::{ControlFlow, EventLoop};
|
||||||
use winit_input_helper::WinitInputHelper;
|
use winit_input_helper::WinitInputHelper;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ fn main() -> Result<(), Error> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let mut input = WinitInputHelper::new();
|
let mut input = WinitInputHelper::new();
|
||||||
let (window, surface, mut p_width, mut p_height, mut hidpi_factor) =
|
let (window, surface, p_width, p_height, mut hidpi_factor) =
|
||||||
create_window("Conway's Game of Life", &event_loop);
|
create_window("Conway's Game of Life", &event_loop);
|
||||||
|
|
||||||
let surface_texture = SurfaceTexture::new(p_width, p_height, surface);
|
let surface_texture = SurfaceTexture::new(p_width, p_height, surface);
|
||||||
|
@ -28,13 +28,9 @@ fn main() -> Result<(), Error> {
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
// The one and only event that winit_input_helper doesn't have for us...
|
// The one and only event that winit_input_helper doesn't have for us...
|
||||||
if let Event::WindowEvent {
|
if let Event::RedrawRequested(_) = event {
|
||||||
event: WindowEvent::RedrawRequested,
|
|
||||||
..
|
|
||||||
} = event
|
|
||||||
{
|
|
||||||
life.draw(pixels.get_frame());
|
life.draw(pixels.get_frame());
|
||||||
pixels.render();
|
pixels.render().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// For everything else, for let winit_input_helper collect events to build its state.
|
// For everything else, for let winit_input_helper collect events to build its state.
|
||||||
|
@ -100,15 +96,12 @@ fn main() -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Adjust high DPI factor
|
// Adjust high DPI factor
|
||||||
if let Some(factor) = input.hidpi_changed() {
|
if let Some(factor) = input.scale_factor_changed() {
|
||||||
hidpi_factor = factor;
|
hidpi_factor = factor;
|
||||||
}
|
}
|
||||||
// Resize the window
|
// Resize the window
|
||||||
if let Some(size) = input.window_resized() {
|
if let Some(size) = input.window_resized() {
|
||||||
let size = size.to_physical(hidpi_factor);
|
pixels.resize(size.width, size.height);
|
||||||
p_width = size.width.round() as u32;
|
|
||||||
p_height = size.height.round() as u32;
|
|
||||||
pixels.resize(p_width, p_height);
|
|
||||||
}
|
}
|
||||||
if !paused || input.key_pressed(VirtualKeyCode::Space) {
|
if !paused || input.key_pressed(VirtualKeyCode::Space) {
|
||||||
life.update();
|
life.update();
|
||||||
|
@ -138,19 +131,23 @@ fn create_window(
|
||||||
.with_title(title)
|
.with_title(title)
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let hidpi_factor = window.hidpi_factor();
|
let hidpi_factor = window.scale_factor();
|
||||||
|
|
||||||
// Get dimensions
|
// Get dimensions
|
||||||
let width = SCREEN_WIDTH as f64;
|
let width = SCREEN_WIDTH as f64;
|
||||||
let height = SCREEN_HEIGHT as f64;
|
let height = SCREEN_HEIGHT as f64;
|
||||||
let (monitor_width, monitor_height) = {
|
let (monitor_width, monitor_height) = {
|
||||||
let size = window.current_monitor().size();
|
let size = window.current_monitor().size();
|
||||||
(size.width / hidpi_factor, size.height / hidpi_factor)
|
(
|
||||||
|
size.width as f64 / hidpi_factor,
|
||||||
|
size.height as f64 / hidpi_factor,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
let scale = (monitor_height / height * 2.0 / 3.0).round();
|
let scale = (monitor_height / height * 2.0 / 3.0).round();
|
||||||
|
|
||||||
// Resize, center, and display the window
|
// Resize, center, and display the window
|
||||||
let min_size = PhysicalSize::new(width, height).to_logical(hidpi_factor);
|
let min_size: winit::dpi::LogicalSize<f64> =
|
||||||
|
PhysicalSize::new(width, height).to_logical(hidpi_factor);
|
||||||
let default_size = LogicalSize::new(width * scale, height * scale);
|
let default_size = LogicalSize::new(width * scale, height * scale);
|
||||||
let center = LogicalPosition::new(
|
let center = LogicalPosition::new(
|
||||||
(monitor_width - width * scale) / 2.0,
|
(monitor_width - width * scale) / 2.0,
|
||||||
|
@ -162,7 +159,7 @@ fn create_window(
|
||||||
window.set_visible(true);
|
window.set_visible(true);
|
||||||
|
|
||||||
let surface = pixels::wgpu::Surface::create(&window);
|
let surface = pixels::wgpu::Surface::create(&window);
|
||||||
let size = default_size.to_physical(hidpi_factor);
|
let size = default_size.to_physical::<f64>(hidpi_factor);
|
||||||
|
|
||||||
(
|
(
|
||||||
window,
|
window,
|
||||||
|
@ -302,14 +299,14 @@ impl ConwayGrid {
|
||||||
} else {
|
} else {
|
||||||
(y - 1, y + 1)
|
(y - 1, y + 1)
|
||||||
};
|
};
|
||||||
(self.cells[xm1 + ym1 * self.width].alive as usize
|
self.cells[xm1 + ym1 * self.width].alive as usize
|
||||||
+ self.cells[x + ym1 * self.width].alive as usize
|
+ self.cells[x + ym1 * self.width].alive as usize
|
||||||
+ self.cells[xp1 + ym1 * self.width].alive as usize
|
+ self.cells[xp1 + ym1 * self.width].alive as usize
|
||||||
+ self.cells[xm1 + y * self.width].alive as usize
|
+ self.cells[xm1 + y * self.width].alive as usize
|
||||||
+ self.cells[xp1 + y * self.width].alive as usize
|
+ self.cells[xp1 + y * self.width].alive as usize
|
||||||
+ self.cells[xm1 + yp1 * self.width].alive as usize
|
+ self.cells[xm1 + yp1 * self.width].alive as usize
|
||||||
+ self.cells[x + yp1 * self.width].alive as usize
|
+ self.cells[x + yp1 * self.width].alive as usize
|
||||||
+ self.cells[xp1 + yp1 * self.width].alive as usize)
|
+ self.cells[xp1 + yp1 * self.width].alive as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self) {
|
fn update(&mut self) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use log::debug;
|
||||||
use pixels::{Error, Pixels, SurfaceTexture};
|
use pixels::{Error, Pixels, SurfaceTexture};
|
||||||
use simple_invaders::{Controls, Direction, World, SCREEN_HEIGHT, SCREEN_WIDTH};
|
use simple_invaders::{Controls, Direction, World, SCREEN_HEIGHT, SCREEN_WIDTH};
|
||||||
use winit::dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
use winit::dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||||
use winit::event::{Event, VirtualKeyCode, WindowEvent};
|
use winit::event::{Event, VirtualKeyCode};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop};
|
use winit::event_loop::{ControlFlow, EventLoop};
|
||||||
use winit_input_helper::WinitInputHelper;
|
use winit_input_helper::WinitInputHelper;
|
||||||
|
|
||||||
|
@ -35,13 +35,9 @@ fn main() -> Result<(), Error> {
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
// The one and only event that winit_input_helper doesn't have for us...
|
// The one and only event that winit_input_helper doesn't have for us...
|
||||||
if let Event::WindowEvent {
|
if let Event::RedrawRequested(_) = event {
|
||||||
event: WindowEvent::RedrawRequested,
|
|
||||||
..
|
|
||||||
} = event
|
|
||||||
{
|
|
||||||
invaders.draw(pixels.get_frame());
|
invaders.draw(pixels.get_frame());
|
||||||
pixels.render();
|
pixels.render().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pump the gilrs event loop and find an active gamepad
|
// Pump the gilrs event loop and find an active gamepad
|
||||||
|
@ -95,17 +91,13 @@ fn main() -> Result<(), Error> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Adjust high DPI factor
|
// Adjust high DPI factor
|
||||||
if let Some(factor) = input.hidpi_changed() {
|
if let Some(factor) = input.scale_factor_changed() {
|
||||||
hidpi_factor = factor;
|
hidpi_factor = factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize the window
|
// Resize the window
|
||||||
if let Some(size) = input.window_resized() {
|
if let Some(size) = input.window_resized() {
|
||||||
let size = size.to_physical(hidpi_factor);
|
pixels.resize(size.width, size.height);
|
||||||
let width = size.width.round() as u32;
|
|
||||||
let height = size.height.round() as u32;
|
|
||||||
|
|
||||||
pixels.resize(width, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a new delta time.
|
// Get a new delta time.
|
||||||
|
@ -138,19 +130,22 @@ fn create_window(
|
||||||
.with_title(title)
|
.with_title(title)
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let hidpi_factor = window.hidpi_factor();
|
let hidpi_factor = window.scale_factor();
|
||||||
|
|
||||||
// Get dimensions
|
// Get dimensions
|
||||||
let width = SCREEN_WIDTH as f64;
|
let width = SCREEN_WIDTH as f64;
|
||||||
let height = SCREEN_HEIGHT as f64;
|
let height = SCREEN_HEIGHT as f64;
|
||||||
let (monitor_width, monitor_height) = {
|
let (monitor_width, monitor_height) = {
|
||||||
let size = window.current_monitor().size();
|
let size = window.current_monitor().size();
|
||||||
(size.width / hidpi_factor, size.height / hidpi_factor)
|
(
|
||||||
|
size.width as f64 / hidpi_factor,
|
||||||
|
size.height as f64 / hidpi_factor,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
let scale = (monitor_height / height * 2.0 / 3.0).round();
|
let scale = (monitor_height / height * 2.0 / 3.0).round();
|
||||||
|
|
||||||
// Resize, center, and display the window
|
// Resize, center, and display the window
|
||||||
let min_size = PhysicalSize::new(width, height).to_logical(hidpi_factor);
|
let min_size = PhysicalSize::new(width, height).to_logical::<f64>(hidpi_factor);
|
||||||
let default_size = LogicalSize::new(width * scale, height * scale);
|
let default_size = LogicalSize::new(width * scale, height * scale);
|
||||||
let center = LogicalPosition::new(
|
let center = LogicalPosition::new(
|
||||||
(monitor_width - width * scale) / 2.0,
|
(monitor_width - width * scale) / 2.0,
|
||||||
|
@ -162,7 +157,7 @@ fn create_window(
|
||||||
window.set_visible(true);
|
window.set_visible(true);
|
||||||
|
|
||||||
let surface = pixels::wgpu::Surface::create(&window);
|
let surface = pixels::wgpu::Surface::create(&window);
|
||||||
let size = default_size.to_physical(hidpi_factor);
|
let size = default_size.to_physical::<f64>(hidpi_factor);
|
||||||
|
|
||||||
(
|
(
|
||||||
window,
|
window,
|
||||||
|
|
|
@ -17,55 +17,43 @@ struct World {
|
||||||
velocity_y: i16,
|
velocity_y: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), String> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let sdl = beryllium::init()?;
|
let sdl = SDL::init(InitFlags::default())?;
|
||||||
let window = sdl.create_window(
|
let window =
|
||||||
"Hello Pixels",
|
sdl.create_raw_window("Hello Pixels", WindowPosition::Centered, WIDTH, HEIGHT, 0)?;
|
||||||
WINDOW_POSITION_CENTERED,
|
|
||||||
WINDOW_POSITION_CENTERED,
|
|
||||||
WIDTH as i32,
|
|
||||||
HEIGHT as i32,
|
|
||||||
WindowFlags::default(),
|
|
||||||
)?;
|
|
||||||
window.set_minimum_size(WIDTH as i32, HEIGHT as i32);
|
|
||||||
window.set_resizable(true);
|
|
||||||
|
|
||||||
let mut pixels = {
|
let mut pixels = {
|
||||||
let surface = Surface::create(&window);
|
let surface = Surface::create(&window);
|
||||||
let surface_texture = SurfaceTexture::new(WIDTH, HEIGHT, surface);
|
let surface_texture = SurfaceTexture::new(WIDTH, HEIGHT, surface);
|
||||||
Pixels::new(WIDTH, HEIGHT, surface_texture).map_err(|e| format!("{:?}", e))?
|
Pixels::new(WIDTH, HEIGHT, surface_texture)?
|
||||||
};
|
};
|
||||||
let mut world = World::new();
|
let mut world = World::new();
|
||||||
|
|
||||||
'game_loop: loop {
|
'game_loop: loop {
|
||||||
while let Some(event) = sdl.poll_event() {
|
match sdl.poll_events().and_then(Result::ok) {
|
||||||
match event {
|
|
||||||
// Close events
|
// Close events
|
||||||
Event::Quit { .. } => break 'game_loop,
|
Some(Event::Quit { .. }) => break 'game_loop,
|
||||||
Event::Keyboard {
|
Some(Event::Keyboard(KeyboardEvent {
|
||||||
key_info:
|
key: KeyInfo { keycode: key, .. },
|
||||||
KeyInfo {
|
|
||||||
keycode: Some(key), ..
|
|
||||||
},
|
|
||||||
..
|
..
|
||||||
} if key == Keycode::Escape => break 'game_loop,
|
})) if key == Keycode::ESCAPE => break 'game_loop,
|
||||||
|
|
||||||
// Resize the window
|
// Resize the window
|
||||||
Event::WindowSizeChanged { width, height, .. } => {
|
Some(Event::Window(WindowEvent {
|
||||||
pixels.resize(width as u32, height as u32)
|
event: WindowEventEnum::Resized { w, h },
|
||||||
}
|
..
|
||||||
|
})) => pixels.resize(w as u32, h as u32),
|
||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Update internal state
|
// Update internal state
|
||||||
world.update();
|
world.update();
|
||||||
|
|
||||||
// Draw the current frame
|
// Draw the current frame
|
||||||
world.draw(pixels.get_frame());
|
world.draw(pixels.get_frame());
|
||||||
pixels.render();
|
pixels.render()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
use pixels::{wgpu::Surface, Error, Pixels, SurfaceTexture};
|
use pixels::{wgpu::Surface, Error, Pixels, SurfaceTexture};
|
||||||
use winit::dpi::LogicalSize;
|
use winit::dpi::LogicalSize;
|
||||||
use winit::event::{Event, VirtualKeyCode, WindowEvent};
|
use winit::event::{Event, VirtualKeyCode};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop};
|
use winit::event_loop::{ControlFlow, EventLoop};
|
||||||
use winit::window::WindowBuilder;
|
use winit::window::WindowBuilder;
|
||||||
use winit_input_helper::WinitInputHelper;
|
use winit_input_helper::WinitInputHelper;
|
||||||
|
@ -33,7 +33,7 @@ fn main() -> Result<(), Error> {
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
let mut hidpi_factor = window.hidpi_factor();
|
let mut hidpi_factor = window.scale_factor();
|
||||||
|
|
||||||
let mut pixels = {
|
let mut pixels = {
|
||||||
let surface = Surface::create(&window);
|
let surface = Surface::create(&window);
|
||||||
|
@ -44,13 +44,9 @@ fn main() -> Result<(), Error> {
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
// Draw the current frame
|
// Draw the current frame
|
||||||
if let Event::WindowEvent {
|
if let Event::RedrawRequested(_) = event {
|
||||||
event: WindowEvent::RedrawRequested,
|
|
||||||
..
|
|
||||||
} = event
|
|
||||||
{
|
|
||||||
world.draw(pixels.get_frame());
|
world.draw(pixels.get_frame());
|
||||||
pixels.render();
|
pixels.render().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle input events
|
// Handle input events
|
||||||
|
@ -62,17 +58,13 @@ fn main() -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust high DPI factor
|
// Adjust high DPI factor
|
||||||
if let Some(factor) = input.hidpi_changed() {
|
if let Some(factor) = input.scale_factor_changed() {
|
||||||
hidpi_factor = factor;
|
hidpi_factor = factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize the window
|
// Resize the window
|
||||||
if let Some(size) = input.window_resized() {
|
if let Some(size) = input.window_resized() {
|
||||||
let size = size.to_physical(hidpi_factor);
|
pixels.resize(size.width, size.height);
|
||||||
let width = size.width.round() as u32;
|
|
||||||
let height = size.height.round() as u32;
|
|
||||||
|
|
||||||
pixels.resize(width, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update internal state and request a redraw
|
// Update internal state and request a redraw
|
||||||
|
|
97
src/lib.rs
97
src/lib.rs
|
@ -58,8 +58,8 @@ pub struct Pixels {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A builder to help create customized pixel buffers.
|
/// A builder to help create customized pixel buffers.
|
||||||
pub struct PixelsBuilder {
|
pub struct PixelsBuilder<'req> {
|
||||||
request_adapter_options: wgpu::RequestAdapterOptions,
|
request_adapter_options: wgpu::RequestAdapterOptions<'req>,
|
||||||
device_descriptor: wgpu::DeviceDescriptor,
|
device_descriptor: wgpu::DeviceDescriptor,
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
|
@ -75,6 +75,9 @@ pub enum Error {
|
||||||
/// No suitable [`wgpu::Adapter`] found
|
/// No suitable [`wgpu::Adapter`] found
|
||||||
#[error("No suitable `wgpu::Adapter` found")]
|
#[error("No suitable `wgpu::Adapter` found")]
|
||||||
AdapterNotFound,
|
AdapterNotFound,
|
||||||
|
/// Equivalent to [`wgpu::TimeOut`]
|
||||||
|
#[error("The GPU timed out when attempting to acquire the next texture or if a previous output is still alive.")]
|
||||||
|
Timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SurfaceTexture {
|
impl SurfaceTexture {
|
||||||
|
@ -93,10 +96,10 @@ impl SurfaceTexture {
|
||||||
/// let event_loop = EventLoop::new();
|
/// let event_loop = EventLoop::new();
|
||||||
/// let window = Window::new(&event_loop).unwrap();
|
/// let window = Window::new(&event_loop).unwrap();
|
||||||
/// let surface = Surface::create(&window);
|
/// let surface = Surface::create(&window);
|
||||||
/// let size = window.inner_size().to_physical(window.hidpi_factor());
|
/// let size = window.inner_size();
|
||||||
///
|
///
|
||||||
/// let width = size.width.round() as u32;
|
/// let width = size.width;
|
||||||
/// let height = size.height.round() as u32;
|
/// let height = size.height;
|
||||||
///
|
///
|
||||||
/// let surface_texture = SurfaceTexture::new(width, height, surface);
|
/// let surface_texture = SurfaceTexture::new(width, height, surface);
|
||||||
/// # Ok::<(), pixels::Error>(())
|
/// # Ok::<(), pixels::Error>(())
|
||||||
|
@ -163,14 +166,14 @@ impl Pixels {
|
||||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||||
width: self.surface_texture.width,
|
width: self.surface_texture.width,
|
||||||
height: self.surface_texture.height,
|
height: self.surface_texture.height,
|
||||||
present_mode: wgpu::PresentMode::Vsync,
|
present_mode: wgpu::PresentMode::Mailbox,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update state for all render passes
|
// Update state for all render passes
|
||||||
let mut encoder = self
|
let mut encoder = self
|
||||||
.device
|
.device
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||||
for renderer in self.renderers.iter_mut() {
|
for renderer in self.renderers.iter_mut() {
|
||||||
renderer.resize(&mut encoder, width, height);
|
renderer.resize(&mut encoder, width, height);
|
||||||
}
|
}
|
||||||
|
@ -181,34 +184,41 @@ impl Pixels {
|
||||||
/// Draw this pixel buffer to the configured [`SurfaceTexture`].
|
/// Draw this pixel buffer to the configured [`SurfaceTexture`].
|
||||||
///
|
///
|
||||||
/// This executes all render passes in sequence. See [`RenderPass`].
|
/// This executes all render passes in sequence. See [`RenderPass`].
|
||||||
pub fn render(&mut self) {
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an error when [`wgpu::SwapChain::get_next_texture`] times out.
|
||||||
|
pub fn render(&mut self) -> Result<(), Error> {
|
||||||
// TODO: Center frame buffer in surface
|
// TODO: Center frame buffer in surface
|
||||||
let frame = self.swap_chain.get_next_texture();
|
let frame = self
|
||||||
|
.swap_chain
|
||||||
|
.get_next_texture()
|
||||||
|
.map_err(|_| Error::Timeout)?;
|
||||||
let mut encoder = self
|
let mut encoder = self
|
||||||
.device
|
.device
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||||
|
|
||||||
// Update the pixel buffer texture view
|
// Update the pixel buffer texture view
|
||||||
let buffer = self
|
let mapped = self.device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||||
.device
|
label: None,
|
||||||
.create_buffer_mapped(self.pixels.len(), wgpu::BufferUsage::COPY_SRC)
|
size: self.pixels.len() as u64,
|
||||||
.fill_from_slice(&self.pixels);
|
usage: wgpu::BufferUsage::COPY_SRC,
|
||||||
|
});
|
||||||
|
mapped.data.copy_from_slice(&self.pixels);
|
||||||
|
let buffer = mapped.finish();
|
||||||
|
|
||||||
encoder.copy_buffer_to_texture(
|
encoder.copy_buffer_to_texture(
|
||||||
wgpu::BufferCopyView {
|
wgpu::BufferCopyView {
|
||||||
buffer: &buffer,
|
buffer: &buffer,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
row_pitch: self.texture_extent.width * self.texture_format_size,
|
bytes_per_row: self.texture_extent.width * self.texture_format_size,
|
||||||
image_height: self.texture_extent.height,
|
rows_per_image: self.texture_extent.height,
|
||||||
},
|
},
|
||||||
wgpu::TextureCopyView {
|
wgpu::TextureCopyView {
|
||||||
texture: &self.texture,
|
texture: &self.texture,
|
||||||
mip_level: 0,
|
mip_level: 0,
|
||||||
array_layer: 0,
|
array_layer: 0,
|
||||||
origin: wgpu::Origin3d {
|
origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
|
||||||
x: 0.0,
|
|
||||||
y: 0.0,
|
|
||||||
z: 0.0,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
self.texture_extent,
|
self.texture_extent,
|
||||||
);
|
);
|
||||||
|
@ -220,6 +230,7 @@ impl Pixels {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.queue.borrow_mut().submit(&[encoder.finish()]);
|
self.queue.borrow_mut().submit(&[encoder.finish()]);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a mutable byte slice for the pixel buffer. The buffer is _not_ cleared for you; it will
|
/// Get a mutable byte slice for the pixel buffer. The buffer is _not_ cleared for you; it will
|
||||||
|
@ -251,7 +262,7 @@ impl Pixels {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PixelsBuilder {
|
impl<'req> PixelsBuilder<'req> {
|
||||||
/// Create a builder that can be finalized into a [`Pixels`] pixel buffer.
|
/// Create a builder that can be finalized into a [`Pixels`] pixel buffer.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -285,12 +296,15 @@ impl PixelsBuilder {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics when `width` or `height` are 0.
|
/// Panics when `width` or `height` are 0.
|
||||||
pub fn new(width: u32, height: u32, surface_texture: SurfaceTexture) -> PixelsBuilder {
|
pub fn new(width: u32, height: u32, surface_texture: SurfaceTexture) -> PixelsBuilder<'req> {
|
||||||
assert!(width > 0);
|
assert!(width > 0);
|
||||||
assert!(height > 0);
|
assert!(height > 0);
|
||||||
|
|
||||||
PixelsBuilder {
|
PixelsBuilder {
|
||||||
request_adapter_options: wgpu::RequestAdapterOptions::default(),
|
request_adapter_options: wgpu::RequestAdapterOptions {
|
||||||
|
compatible_surface: None,
|
||||||
|
power_preference: wgpu::PowerPreference::Default,
|
||||||
|
},
|
||||||
device_descriptor: wgpu::DeviceDescriptor::default(),
|
device_descriptor: wgpu::DeviceDescriptor::default(),
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
@ -304,7 +318,7 @@ impl PixelsBuilder {
|
||||||
/// Add options for requesting a [`wgpu::Adapter`].
|
/// Add options for requesting a [`wgpu::Adapter`].
|
||||||
pub const fn request_adapter_options(
|
pub const fn request_adapter_options(
|
||||||
mut self,
|
mut self,
|
||||||
request_adapter_options: wgpu::RequestAdapterOptions,
|
request_adapter_options: wgpu::RequestAdapterOptions<'req>,
|
||||||
) -> PixelsBuilder {
|
) -> PixelsBuilder {
|
||||||
self.request_adapter_options = request_adapter_options;
|
self.request_adapter_options = request_adapter_options;
|
||||||
self
|
self
|
||||||
|
@ -314,7 +328,7 @@ impl PixelsBuilder {
|
||||||
pub const fn device_descriptor(
|
pub const fn device_descriptor(
|
||||||
mut self,
|
mut self,
|
||||||
device_descriptor: wgpu::DeviceDescriptor,
|
device_descriptor: wgpu::DeviceDescriptor,
|
||||||
) -> PixelsBuilder {
|
) -> PixelsBuilder<'req> {
|
||||||
self.device_descriptor = device_descriptor;
|
self.device_descriptor = device_descriptor;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -329,7 +343,7 @@ impl PixelsBuilder {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// The aspect ratio must be > 0.
|
/// The aspect ratio must be > 0.
|
||||||
pub fn pixel_aspect_ratio(mut self, pixel_aspect_ratio: f64) -> PixelsBuilder {
|
pub fn pixel_aspect_ratio(mut self, pixel_aspect_ratio: f64) -> PixelsBuilder<'req> {
|
||||||
assert!(pixel_aspect_ratio > 0.0);
|
assert!(pixel_aspect_ratio > 0.0);
|
||||||
|
|
||||||
self.pixel_aspect_ratio = pixel_aspect_ratio;
|
self.pixel_aspect_ratio = pixel_aspect_ratio;
|
||||||
|
@ -341,7 +355,10 @@ impl PixelsBuilder {
|
||||||
/// The default value is [`wgpu::TextureFormat::Rgba8UnormSrgb`], which is 4 unsigned bytes in
|
/// The default value is [`wgpu::TextureFormat::Rgba8UnormSrgb`], which is 4 unsigned bytes in
|
||||||
/// `RGBA` order using the SRGB color space. This is typically what you want when you are
|
/// `RGBA` order using the SRGB color space. This is typically what you want when you are
|
||||||
/// working with color values from popular image editing tools or web apps.
|
/// working with color values from popular image editing tools or web apps.
|
||||||
pub const fn texture_format(mut self, texture_format: wgpu::TextureFormat) -> PixelsBuilder {
|
pub const fn texture_format(
|
||||||
|
mut self,
|
||||||
|
texture_format: wgpu::TextureFormat,
|
||||||
|
) -> PixelsBuilder<'req> {
|
||||||
self.texture_format = texture_format;
|
self.texture_format = texture_format;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -397,7 +414,7 @@ impl PixelsBuilder {
|
||||||
pub fn add_render_pass(
|
pub fn add_render_pass(
|
||||||
mut self,
|
mut self,
|
||||||
factory: impl Fn(Device, Queue, &TextureView, &Extent3d) -> BoxedRenderPass + 'static,
|
factory: impl Fn(Device, Queue, &TextureView, &Extent3d) -> BoxedRenderPass + 'static,
|
||||||
) -> PixelsBuilder {
|
) -> PixelsBuilder<'req> {
|
||||||
self.renderer_factories.push(Box::new(factory));
|
self.renderer_factories.push(Box::new(factory));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -409,10 +426,13 @@ impl PixelsBuilder {
|
||||||
/// Returns an error when a [`wgpu::Adapter`] cannot be found.
|
/// Returns an error when a [`wgpu::Adapter`] cannot be found.
|
||||||
pub fn build(self) -> Result<Pixels, Error> {
|
pub fn build(self) -> Result<Pixels, Error> {
|
||||||
// TODO: Use `options.pixel_aspect_ratio` to stretch the scaled texture
|
// TODO: Use `options.pixel_aspect_ratio` to stretch the scaled texture
|
||||||
|
let adapter = futures::executor::block_on(wgpu::Adapter::request(
|
||||||
let adapter =
|
&self.request_adapter_options,
|
||||||
wgpu::Adapter::request(&self.request_adapter_options).ok_or(Error::AdapterNotFound)?;
|
wgpu::BackendBit::PRIMARY,
|
||||||
let (device, queue) = adapter.request_device(&self.device_descriptor);
|
))
|
||||||
|
.ok_or(Error::AdapterNotFound)?;
|
||||||
|
let (device, queue) =
|
||||||
|
futures::executor::block_on(adapter.request_device(&self.device_descriptor));
|
||||||
let device = Rc::new(device);
|
let device = Rc::new(device);
|
||||||
let queue = Rc::new(RefCell::new(queue));
|
let queue = Rc::new(RefCell::new(queue));
|
||||||
|
|
||||||
|
@ -427,6 +447,7 @@ impl PixelsBuilder {
|
||||||
depth: 1,
|
depth: 1,
|
||||||
};
|
};
|
||||||
let texture = device.create_texture(&wgpu::TextureDescriptor {
|
let texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
|
label: None,
|
||||||
size: texture_extent,
|
size: texture_extent,
|
||||||
array_layer_count: 1,
|
array_layer_count: 1,
|
||||||
mip_level_count: 1,
|
mip_level_count: 1,
|
||||||
|
@ -452,7 +473,7 @@ impl PixelsBuilder {
|
||||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||||
width: surface_texture.width,
|
width: surface_texture.width,
|
||||||
height: surface_texture.height,
|
height: surface_texture.height,
|
||||||
present_mode: wgpu::PresentMode::Vsync,
|
present_mode: wgpu::PresentMode::Mailbox,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -498,9 +519,7 @@ fn get_texture_format_size(texture_format: wgpu::TextureFormat) -> u32 {
|
||||||
| wgpu::TextureFormat::R8Sint => 1,
|
| wgpu::TextureFormat::R8Sint => 1,
|
||||||
|
|
||||||
// 16-bit formats
|
// 16-bit formats
|
||||||
wgpu::TextureFormat::R16Unorm
|
wgpu::TextureFormat::R16Uint
|
||||||
| wgpu::TextureFormat::R16Snorm
|
|
||||||
| wgpu::TextureFormat::R16Uint
|
|
||||||
| wgpu::TextureFormat::R16Sint
|
| wgpu::TextureFormat::R16Sint
|
||||||
| wgpu::TextureFormat::R16Float
|
| wgpu::TextureFormat::R16Float
|
||||||
| wgpu::TextureFormat::Rg8Unorm
|
| wgpu::TextureFormat::Rg8Unorm
|
||||||
|
@ -512,8 +531,6 @@ fn get_texture_format_size(texture_format: wgpu::TextureFormat) -> u32 {
|
||||||
wgpu::TextureFormat::R32Uint
|
wgpu::TextureFormat::R32Uint
|
||||||
| wgpu::TextureFormat::R32Sint
|
| wgpu::TextureFormat::R32Sint
|
||||||
| wgpu::TextureFormat::R32Float
|
| wgpu::TextureFormat::R32Float
|
||||||
| wgpu::TextureFormat::Rg16Unorm
|
|
||||||
| wgpu::TextureFormat::Rg16Snorm
|
|
||||||
| wgpu::TextureFormat::Rg16Uint
|
| wgpu::TextureFormat::Rg16Uint
|
||||||
| wgpu::TextureFormat::Rg16Sint
|
| wgpu::TextureFormat::Rg16Sint
|
||||||
| wgpu::TextureFormat::Rg16Float
|
| wgpu::TextureFormat::Rg16Float
|
||||||
|
@ -534,8 +551,6 @@ fn get_texture_format_size(texture_format: wgpu::TextureFormat) -> u32 {
|
||||||
wgpu::TextureFormat::Rg32Uint
|
wgpu::TextureFormat::Rg32Uint
|
||||||
| wgpu::TextureFormat::Rg32Sint
|
| wgpu::TextureFormat::Rg32Sint
|
||||||
| wgpu::TextureFormat::Rg32Float
|
| wgpu::TextureFormat::Rg32Float
|
||||||
| wgpu::TextureFormat::Rgba16Unorm
|
|
||||||
| wgpu::TextureFormat::Rgba16Snorm
|
|
||||||
| wgpu::TextureFormat::Rgba16Uint
|
| wgpu::TextureFormat::Rgba16Uint
|
||||||
| wgpu::TextureFormat::Rgba16Sint
|
| wgpu::TextureFormat::Rgba16Sint
|
||||||
| wgpu::TextureFormat::Rgba16Float => 8,
|
| wgpu::TextureFormat::Rgba16Float => 8,
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl Renderer {
|
||||||
mipmap_filter: wgpu::FilterMode::Nearest,
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
lod_min_clamp: 0.0,
|
lod_min_clamp: 0.0,
|
||||||
lod_max_clamp: 1.0,
|
lod_max_clamp: 1.0,
|
||||||
compare_function: wgpu::CompareFunction::Always,
|
compare: wgpu::CompareFunction::Always,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create uniform buffer
|
// Create uniform buffer
|
||||||
|
@ -48,27 +48,38 @@ impl Renderer {
|
||||||
0.0, 0.0, 1.0, 0.0,
|
0.0, 0.0, 1.0, 0.0,
|
||||||
0.0, 0.0, 0.0, 1.0,
|
0.0, 0.0, 0.0, 1.0,
|
||||||
];
|
];
|
||||||
let uniform_buffer = device
|
let mut tranform_bytes: Vec<u8> = Vec::with_capacity(4 * transform.len());
|
||||||
.create_buffer_mapped(16, wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST)
|
transform
|
||||||
.fill_from_slice(&transform);
|
.iter()
|
||||||
|
.map(|e| e.to_bits().to_ne_bytes())
|
||||||
|
.for_each(|b| tranform_bytes.extend(b.iter()));
|
||||||
|
let mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||||
|
label: None,
|
||||||
|
size: tranform_bytes.len() as u64,
|
||||||
|
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||||
|
});
|
||||||
|
mapped.data.copy_from_slice(&tranform_bytes);
|
||||||
|
let uniform_buffer = mapped.finish();
|
||||||
|
|
||||||
// Create bind group
|
// Create bind group
|
||||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: None,
|
||||||
bindings: &[
|
bindings: &[
|
||||||
wgpu::BindGroupLayoutBinding {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
ty: wgpu::BindingType::SampledTexture {
|
ty: wgpu::BindingType::SampledTexture {
|
||||||
|
component_type: wgpu::TextureComponentType::Uint,
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
dimension: wgpu::TextureViewDimension::D2,
|
dimension: wgpu::TextureViewDimension::D2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wgpu::BindGroupLayoutBinding {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
ty: wgpu::BindingType::Sampler,
|
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||||
},
|
},
|
||||||
wgpu::BindGroupLayoutBinding {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 2,
|
binding: 2,
|
||||||
visibility: wgpu::ShaderStage::VERTEX,
|
visibility: wgpu::ShaderStage::VERTEX,
|
||||||
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
|
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
|
||||||
|
@ -76,6 +87,7 @@ impl Renderer {
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: None,
|
||||||
layout: &bind_group_layout,
|
layout: &bind_group_layout,
|
||||||
bindings: &[
|
bindings: &[
|
||||||
wgpu::Binding {
|
wgpu::Binding {
|
||||||
|
@ -125,8 +137,10 @@ impl Renderer {
|
||||||
write_mask: wgpu::ColorWrite::ALL,
|
write_mask: wgpu::ColorWrite::ALL,
|
||||||
}],
|
}],
|
||||||
depth_stencil_state: None,
|
depth_stencil_state: None,
|
||||||
|
vertex_state: wgpu::VertexStateDescriptor {
|
||||||
index_format: wgpu::IndexFormat::Uint16,
|
index_format: wgpu::IndexFormat::Uint16,
|
||||||
vertex_buffers: &[],
|
vertex_buffers: &[],
|
||||||
|
},
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
sample_mask: !0,
|
sample_mask: !0,
|
||||||
alpha_to_coverage_enabled: false,
|
alpha_to_coverage_enabled: false,
|
||||||
|
@ -181,11 +195,19 @@ impl RenderPass for Renderer {
|
||||||
0.0, 0.0, 1.0, 0.0,
|
0.0, 0.0, 1.0, 0.0,
|
||||||
0.0, 0.0, 0.0, 1.0,
|
0.0, 0.0, 0.0, 1.0,
|
||||||
];
|
];
|
||||||
|
let mut tranform_bytes: Vec<u8> = Vec::with_capacity(4 * transform.len());
|
||||||
let temp_buf = self
|
transform
|
||||||
.device
|
.iter()
|
||||||
.create_buffer_mapped(16, wgpu::BufferUsage::COPY_SRC)
|
.map(|e| e.to_bits().to_ne_bytes())
|
||||||
.fill_from_slice(&transform);
|
.for_each(|b| tranform_bytes.extend(b.iter()));
|
||||||
|
let mapped = self.device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||||
|
label: None,
|
||||||
|
size: tranform_bytes.len() as u64,
|
||||||
|
usage: wgpu::BufferUsage::COPY_SRC,
|
||||||
|
});
|
||||||
|
mapped.data.copy_from_slice(&tranform_bytes);
|
||||||
|
let temp_buf = mapped.finish();
|
||||||
|
encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.uniform_buffer, 0, 64);
|
||||||
encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.uniform_buffer, 0, 64);
|
encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.uniform_buffer, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue