old school music tracker
at main 103 lines 3.3 kB view raw
1use std::sync::Arc; 2 3use winit::{dpi::PhysicalSize, event_loop::ActiveEventLoop, window::Window}; 4 5use crate::{ 6 coordinates::WINDOW_SIZE, 7 palettes::{Palette, RGB8}, 8}; 9 10#[cfg(all(feature = "gpu_scaling", feature = "soft_scaling"))] 11compile_error!("it's impossible to have both gpu and software scaling enabled"); 12 13#[cfg(not(any(feature = "gpu_scaling", feature = "soft_scaling")))] 14compile_error!("at least one of gpu_scaling or soft_scaling needs to be active"); 15 16#[cfg(feature = "gpu_scaling")] 17pub struct RenderBackend { 18 backend: crate::gpu::GPUState, 19} 20 21#[cfg(feature = "gpu_scaling")] 22impl RenderBackend { 23 pub fn new(window: Arc<Window>, palette: Palette<RGB8>) -> Self { 24 let mut backend = smol::block_on(crate::gpu::GPUState::new(window)); 25 backend.queue_palette_update(palette.into()); 26 27 Self { backend } 28 } 29 30 pub fn resize(&mut self, size: PhysicalSize<u32>) { 31 self.backend.resize(size); 32 } 33 34 pub fn render( 35 &mut self, 36 frame_buffer: &[[u8; WINDOW_SIZE.0]; WINDOW_SIZE.1], 37 event_loop: &ActiveEventLoop, 38 ) { 39 match self.backend.render(frame_buffer) { 40 Ok(_) => {} 41 Err(wgpu::SurfaceError::Lost) => self.backend.reinit_surface(), 42 Err(wgpu::SurfaceError::OutOfMemory) => event_loop.exit(), 43 Err(e) => eprint!("{:?}", e), 44 } 45 } 46} 47 48#[cfg(feature = "soft_scaling")] 49pub struct RenderBackend { 50 backend: softbuffer::Surface<Arc<Window>, Arc<Window>>, 51 width: u32, 52 height: u32, 53 palette: Palette<crate::palettes::ZRGB>, 54} 55 56#[cfg(feature = "soft_scaling")] 57impl RenderBackend { 58 pub fn new(window: Arc<Window>, palette: Palette<RGB8>) -> Self { 59 let size = window.inner_size(); 60 let context = softbuffer::Context::new(window.clone()).unwrap(); 61 Self { 62 backend: softbuffer::Surface::new(&context, window).unwrap(), 63 width: size.width, 64 height: size.height, 65 palette: palette.into(), 66 } 67 } 68 69 pub fn resize(&mut self, size: PhysicalSize<u32>) { 70 self.width = size.width; 71 self.height = size.height; 72 self.backend 73 .resize( 74 std::num::NonZeroU32::new(size.width).unwrap(), 75 std::num::NonZeroU32::new(size.height).unwrap(), 76 ) 77 .unwrap() 78 } 79 80 pub fn render( 81 &mut self, 82 frame_buffer: &[[u8; WINDOW_SIZE.0]; WINDOW_SIZE.1], 83 _: &ActiveEventLoop, 84 ) { 85 let mut buffer = self.backend.buffer_mut().unwrap(); 86 assert!(buffer.len() == usize::try_from(self.width * self.height).unwrap()); 87 let x_step = WINDOW_SIZE.0 as f32 / self.width as f32; 88 let y_step = WINDOW_SIZE.1 as f32 / self.height as f32; 89 for (y_idx, row) in buffer 90 .chunks_exact_mut(self.width.try_into().unwrap()) 91 .enumerate() 92 { 93 for (x_idx, pixel) in row.iter_mut().enumerate() { 94 let x_idx = x_idx as f32 * x_step; 95 let y_idx = y_idx as f32 * y_step; 96 *pixel = self 97 .palette 98 .get_raw(frame_buffer[y_idx.floor() as usize][x_idx.floor() as usize]); 99 } 100 } 101 buffer.present().unwrap(); 102 } 103}