use anyhow::Result; use image::GenericImageView; pub(super) struct RawTexture { pub(super) view: wgpu::TextureView, } impl RawTexture { pub(super) fn from_bytes( device: &wgpu::Device, queue: &wgpu::Queue, bytes: &[u8], label: &str, ) -> Result { let img = image::load_from_memory(bytes)?; Self::from_image(device, queue, &img, Some(label)) } pub(super) fn from_image( device: &wgpu::Device, queue: &wgpu::Queue, img: &image::DynamicImage, label: Option<&str>, ) -> Result { let rgba = img.to_rgba8(); let dimensions = img.dimensions(); let size = wgpu::Extent3d { width: dimensions.0, height: dimensions.1, depth_or_array_layers: 1, }; let texture = device.create_texture(&wgpu::TextureDescriptor { label, size, mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, format: wgpu::TextureFormat::Rgba8UnormSrgb, usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, view_formats: &[], }); let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); queue.write_texture( wgpu::ImageCopyTexture { aspect: wgpu::TextureAspect::All, texture: &texture, mip_level: 0, origin: wgpu::Origin3d::ZERO, }, &rgba, wgpu::ImageDataLayout { offset: 0, bytes_per_row: Some(4 * dimensions.0), rows_per_image: Some(dimensions.1), }, size, ); Ok(Self { view }) } }