Update public API to provide &mut [u8]
instead of accepting &[u8]
from the app (#22)
- Closes #19
This commit is contained in:
parent
b18690f19f
commit
8801bad58a
|
@ -42,7 +42,7 @@ fn main() -> Result<(), Error> {
|
|||
};
|
||||
|
||||
let surface_texture = SurfaceTexture::new(width, height, surface);
|
||||
let mut pixels = Pixels::new(224, 256, surface_texture)?;
|
||||
let mut pixels = Pixels::new(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32, surface_texture)?;
|
||||
let mut invaders = World::new(debug);
|
||||
let mut time = Instant::now();
|
||||
let mut controls = Controls::default();
|
||||
|
@ -54,7 +54,8 @@ fn main() -> Result<(), Error> {
|
|||
event: WindowEvent::RedrawRequested,
|
||||
..
|
||||
} => {
|
||||
pixels.render(invaders.draw());
|
||||
invaders.draw(pixels.get_frame());
|
||||
pixels.render();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ pub struct World {
|
|||
collision: Collision,
|
||||
score: u32,
|
||||
assets: Assets,
|
||||
screen: Vec<u8>,
|
||||
dt: Duration,
|
||||
gameover: bool,
|
||||
random: OsRng,
|
||||
|
@ -149,10 +148,6 @@ impl World {
|
|||
let collision = Collision::default();
|
||||
let score = 0;
|
||||
|
||||
// Create a screen with the correct size
|
||||
let mut screen = Vec::new();
|
||||
screen.resize_with(SCREEN_WIDTH * SCREEN_HEIGHT * 4, Default::default);
|
||||
|
||||
let dt = Duration::default();
|
||||
let gameover = false;
|
||||
let random = OsRng;
|
||||
|
@ -166,7 +161,6 @@ impl World {
|
|||
collision,
|
||||
score,
|
||||
assets,
|
||||
screen,
|
||||
dt,
|
||||
gameover,
|
||||
random,
|
||||
|
@ -261,47 +255,45 @@ impl World {
|
|||
/// Draw the internal state to the screen.
|
||||
///
|
||||
/// Calling this method more than once without an `update` call between is a no-op.
|
||||
pub fn draw(&mut self) -> &[u8] {
|
||||
pub fn draw(&mut self, screen: &mut [u8]) {
|
||||
// Clear the screen
|
||||
self.clear();
|
||||
clear(screen);
|
||||
|
||||
// Draw the invaders
|
||||
for row in &self.invaders.grid {
|
||||
for col in row {
|
||||
if let Some(invader) = col {
|
||||
blit(&mut self.screen, &invader.pos, &invader.sprite);
|
||||
blit(screen, &invader.pos, &invader.sprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the shields
|
||||
for shield in &self.shields {
|
||||
blit(&mut self.screen, &shield.pos, &shield.sprite);
|
||||
blit(screen, &shield.pos, &shield.sprite);
|
||||
}
|
||||
|
||||
// Draw the player
|
||||
blit(&mut self.screen, &self.player.pos, &self.player.sprite);
|
||||
blit(screen, &self.player.pos, &self.player.sprite);
|
||||
|
||||
// Draw the bullet
|
||||
if let Some(bullet) = &self.bullet {
|
||||
blit(&mut self.screen, &bullet.pos, &bullet.sprite);
|
||||
blit(screen, &bullet.pos, &bullet.sprite);
|
||||
}
|
||||
|
||||
// Draw lasers
|
||||
for laser in self.lasers.iter() {
|
||||
blit(&mut self.screen, &laser.pos, &laser.sprite);
|
||||
blit(screen, &laser.pos, &laser.sprite);
|
||||
}
|
||||
|
||||
// Draw debug information
|
||||
if self.debug {
|
||||
debug::draw_invaders(&mut self.screen, &self.invaders, &self.collision);
|
||||
debug::draw_bullet(&mut self.screen, self.bullet.as_ref());
|
||||
debug::draw_lasers(&mut self.screen, &self.lasers);
|
||||
debug::draw_player(&mut self.screen, &self.player, &self.collision);
|
||||
debug::draw_shields(&mut self.screen, &self.shields, &self.collision);
|
||||
debug::draw_invaders(screen, &self.invaders, &self.collision);
|
||||
debug::draw_bullet(screen, self.bullet.as_ref());
|
||||
debug::draw_lasers(screen, &self.lasers);
|
||||
debug::draw_player(screen, &self.player, &self.collision);
|
||||
debug::draw_shields(screen, &self.shields, &self.collision);
|
||||
}
|
||||
|
||||
&self.screen
|
||||
}
|
||||
|
||||
fn step_invaders(&mut self) {
|
||||
|
@ -406,13 +398,6 @@ impl World {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear the screen
|
||||
fn clear(&mut self) {
|
||||
for (i, byte) in self.screen.iter_mut().enumerate() {
|
||||
*byte = if i % 4 == 3 { 255 } else { 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for World {
|
||||
|
@ -522,6 +507,13 @@ impl Default for Bounds {
|
|||
}
|
||||
}
|
||||
|
||||
/// Clear the screen
|
||||
fn clear(screen: &mut [u8]) {
|
||||
for (i, byte) in screen.iter_mut().enumerate() {
|
||||
*byte = if i % 4 == 3 { 255 } else { 0 };
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a grid of invaders.
|
||||
fn make_invader_grid(assets: &Assets) -> Vec<Vec<Option<Invader>>> {
|
||||
use Frame::*;
|
||||
|
|
42
src/lib.rs
42
src/lib.rs
|
@ -53,6 +53,7 @@ pub struct Pixels {
|
|||
texture: wgpu::Texture,
|
||||
texture_extent: wgpu::Extent3d,
|
||||
texture_format_size: u32,
|
||||
pixels: Vec<u8>,
|
||||
}
|
||||
|
||||
/// A builder to help create customized pixel buffers.
|
||||
|
@ -124,7 +125,7 @@ impl Pixels {
|
|||
/// # use pixels::Pixels;
|
||||
/// # let surface = wgpu::Surface::create(&pixels_mocks::RWH);
|
||||
/// # let surface_texture = pixels::SurfaceTexture::new(1024, 768, surface);
|
||||
/// let fb = Pixels::new(320, 240, surface_texture)?;
|
||||
/// let mut pixels = Pixels::new(320, 240, surface_texture)?;
|
||||
/// # Ok::<(), pixels::Error>(())
|
||||
/// ```
|
||||
///
|
||||
|
@ -169,12 +170,7 @@ impl Pixels {
|
|||
/// Draw this pixel buffer to the configured [`SurfaceTexture`].
|
||||
///
|
||||
/// This executes all render passes in sequence. See [`RenderPass`].
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `texels` - Byte slice of texture pixels (AKA texels) to draw. The texture format can be
|
||||
/// configured with [`PixelsBuilder`].
|
||||
pub fn render(&mut self, texels: &[u8]) {
|
||||
pub fn render(&mut self) {
|
||||
// TODO: Center frame buffer in surface
|
||||
let frame = self.swap_chain.get_next_texture();
|
||||
let mut encoder = self
|
||||
|
@ -184,8 +180,8 @@ impl Pixels {
|
|||
// Update the pixel buffer texture view
|
||||
let buffer = self
|
||||
.device
|
||||
.create_buffer_mapped(texels.len(), wgpu::BufferUsage::COPY_SRC)
|
||||
.fill_from_slice(texels);
|
||||
.create_buffer_mapped(self.pixels.len(), wgpu::BufferUsage::COPY_SRC)
|
||||
.fill_from_slice(&self.pixels);
|
||||
encoder.copy_buffer_to_texture(
|
||||
wgpu::BufferCopyView {
|
||||
buffer: &buffer,
|
||||
|
@ -214,6 +210,26 @@ impl Pixels {
|
|||
|
||||
self.queue.borrow_mut().submit(&[encoder.finish()]);
|
||||
}
|
||||
|
||||
/// Get a mutable byte slice for the pixel buffer. The buffer is _not_ cleared for you; it will
|
||||
/// retain the previous frame's contents until you clear it yourself.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use pixels::Pixels;
|
||||
/// # let surface = wgpu::Surface::create(&pixels_mocks::RWH);
|
||||
/// # let surface_texture = pixels::SurfaceTexture::new(1024, 768, surface);
|
||||
/// let mut pixels = Pixels::new(320, 240, surface_texture)?;
|
||||
/// let frame = pixels.get_frame();
|
||||
/// for pixel in frame {
|
||||
/// *pixel = 0;
|
||||
/// }
|
||||
/// # Ok::<(), pixels::Error>(())
|
||||
/// ```
|
||||
pub fn get_frame(&mut self) -> &mut [u8] {
|
||||
&mut self.pixels
|
||||
}
|
||||
}
|
||||
|
||||
impl PixelsBuilder {
|
||||
|
@ -235,7 +251,7 @@ impl PixelsBuilder {
|
|||
/// # fn render_pass(&self, _: &mut wgpu::CommandEncoder, _: &wgpu::TextureView) {}
|
||||
/// }
|
||||
///
|
||||
/// let fb = PixelsBuilder::new(256, 240, surface_texture)
|
||||
/// let mut pixels = PixelsBuilder::new(256, 240, surface_texture)
|
||||
/// .pixel_aspect_ratio(8.0 / 7.0)
|
||||
/// .add_render_pass(|device, queue, texture| {
|
||||
/// // Create reources for MyRenderPass here
|
||||
|
@ -391,6 +407,11 @@ impl PixelsBuilder {
|
|||
let texture_view = texture.create_default_view();
|
||||
let texture_format_size = get_texture_format_size(self.texture_format);
|
||||
|
||||
// Create the pixel buffer
|
||||
let capacity = (width * height * texture_format_size) as usize;
|
||||
let mut pixels = Vec::with_capacity(capacity);
|
||||
pixels.resize_with(capacity, Default::default);
|
||||
|
||||
// Create swap chain
|
||||
let surface_texture = self.surface_texture;
|
||||
let swap_chain = device.create_swap_chain(
|
||||
|
@ -426,6 +447,7 @@ impl PixelsBuilder {
|
|||
texture,
|
||||
texture_extent,
|
||||
texture_format_size,
|
||||
pixels,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue