pub struct WgpuTexture {
pub texture: wgpu::Texture,
pub view: wgpu::TextureView,
pub sampler: Option<wgpu::Sampler>,
pub width: u32,
pub height: u32,
}
pub struct WgpuRenderTexture {
pub texture: wgpu::Texture,
pub view: wgpu::TextureView,
pub sampler: Option<wgpu::Sampler>,
pub width: u32,
pub height: u32,
pub is_hidden: bool,
}
impl WgpuTexture {
pub fn new_render_target(
device: &wgpu::Device,
width: u32,
height: u32,
) -> Self {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("RustPixel Render Target"),
size: wgpu::Extent3d {
width,
height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8Unorm, usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
Self {
texture,
view,
sampler: None,
width,
height,
}
}
pub fn new_render_target_with_format(
device: &wgpu::Device,
width: u32,
height: u32,
format: wgpu::TextureFormat,
) -> Self {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("RustPixel Custom Render Target"),
size: wgpu::Extent3d {
width,
height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
Self {
texture,
view,
sampler: None,
width,
height,
}
}
pub fn from_bytes(
device: &wgpu::Device,
queue: &wgpu::Queue,
width: u32,
height: u32,
data: &[u8],
) -> Self {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("RustPixel Texture"),
size: wgpu::Extent3d {
width,
height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8Unorm, usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
queue.write_texture(
texture.as_image_copy(),
data,
wgpu::TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(4 * width),
rows_per_image: Some(height),
},
wgpu::Extent3d {
width,
height,
depth_or_array_layers: 1,
},
);
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: Some("RustPixel Sampler"),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Nearest,
mipmap_filter: wgpu::FilterMode::Nearest,
..Default::default()
});
Self {
texture,
view,
sampler: Some(sampler),
width,
height,
}
}
pub fn add_sampler(&mut self, device: &wgpu::Device) {
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: Some("RustPixel Render Target Sampler"),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Nearest,
mipmap_filter: wgpu::FilterMode::Nearest,
..Default::default()
});
self.sampler = Some(sampler);
}
}
impl WgpuRenderTexture {
pub fn new(
device: &wgpu::Device,
width: u32,
height: u32,
is_hidden: bool,
) -> Result<Self, String> {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("RustPixel Render Texture"),
size: wgpu::Extent3d {
width,
height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8Unorm, usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: Some("RustPixel Render Texture Sampler"),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Nearest,
mipmap_filter: wgpu::FilterMode::Nearest,
..Default::default()
});
Ok(Self {
texture,
view,
sampler: Some(sampler),
width,
height,
is_hidden,
})
}
pub fn new_with_format(
device: &wgpu::Device,
width: u32,
height: u32,
format: wgpu::TextureFormat,
is_hidden: bool,
) -> Result<Self, String> {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("RustPixel Custom Render Texture"),
size: wgpu::Extent3d {
width,
height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: Some("RustPixel Custom Render Texture Sampler"),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Nearest,
mipmap_filter: wgpu::FilterMode::Nearest,
..Default::default()
});
Ok(Self {
texture,
view,
sampler: Some(sampler),
width,
height,
is_hidden,
})
}
pub fn get_texture(&self) -> &wgpu::Texture {
&self.texture
}
pub fn get_view(&self) -> &wgpu::TextureView {
&self.view
}
pub fn get_sampler(&self) -> Option<&wgpu::Sampler> {
self.sampler.as_ref()
}
pub fn is_hidden(&self) -> bool {
self.is_hidden
}
pub fn set_hidden(&mut self, hidden: bool) {
self.is_hidden = hidden;
}
pub fn get_dimensions(&self) -> (u32, u32) {
(self.width, self.height)
}
}
pub struct WgpuTextureArray {
pub texture: wgpu::Texture,
pub view: wgpu::TextureView,
pub sampler: wgpu::Sampler,
pub layer_size: u32,
pub layer_count: u32,
}
impl WgpuTextureArray {
pub fn from_layers(
device: &wgpu::Device,
queue: &wgpu::Queue,
layer_size: u32,
layers: &[&[u8]],
) -> Result<Self, String> {
let layer_count = layers.len() as u32;
if layer_count == 0 {
return Err("No layers provided".to_string());
}
let expected_bytes = (layer_size * layer_size * 4) as usize;
for (i, layer) in layers.iter().enumerate() {
if layer.len() != expected_bytes {
return Err(format!(
"Layer {} has {} bytes, expected {} ({}x{}x4)",
i, layer.len(), expected_bytes, layer_size, layer_size
));
}
}
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("Symbol Texture2DArray"),
size: wgpu::Extent3d {
width: layer_size,
height: layer_size,
depth_or_array_layers: layer_count,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8Unorm,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
let bytes_per_row = 4 * layer_size;
for (i, layer_data) in layers.iter().enumerate() {
queue.write_texture(
wgpu::TexelCopyTextureInfo {
texture: &texture,
mip_level: 0,
origin: wgpu::Origin3d {
x: 0,
y: 0,
z: i as u32,
},
aspect: wgpu::TextureAspect::All,
},
layer_data,
wgpu::TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(bytes_per_row),
rows_per_image: Some(layer_size),
},
wgpu::Extent3d {
width: layer_size,
height: layer_size,
depth_or_array_layers: 1,
},
);
}
let view = texture.create_view(&wgpu::TextureViewDescriptor {
label: Some("Symbol Texture2DArray View"),
dimension: Some(wgpu::TextureViewDimension::D2Array),
..Default::default()
});
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: Some("Symbol Texture2DArray Sampler"),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Linear,
min_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::FilterMode::Linear,
..Default::default()
});
Ok(Self {
texture,
view,
sampler,
layer_size,
layer_count,
})
}
}