Mercurial > touhou
diff examples/common.rs @ 753:a662dddd4a2b
examples: Use array textures for enemy PNGs
This requires luminance 0.39.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 25 Feb 2020 21:03:44 +0100 |
parents | 5e5e7136ac92 |
children |
line wrap: on
line diff
--- a/examples/common.rs +++ b/examples/common.rs @@ -1,6 +1,6 @@ use image::{GenericImageView, DynamicImage, GrayImage, ImageError}; use luminance::pixel::{NormRGB8UI, NormRGBA8UI}; -use luminance::texture::{Dim2, Flat, Sampler, Texture, GenMipmaps}; +use luminance::texture::{Dim2, Dim2Array, Sampler, Texture, GenMipmaps}; use luminance_glfw::GlfwSurface; use touhou::th06::anm0::Anm0; use std::fs::File; @@ -16,8 +16,9 @@ pub fn load_file_into_vec<P: AsRef<Path> } pub enum LoadedTexture { - Rgba(Texture<Flat, Dim2, NormRGBA8UI>), - Rgb(Texture<Flat, Dim2, NormRGB8UI>), + Rgba(Texture<Dim2, NormRGBA8UI>), + Rgb(Texture<Dim2, NormRGB8UI>), + RgbaArray(Texture<Dim2Array, NormRGBA8UI>), } #[derive(Debug)] @@ -49,7 +50,7 @@ pub fn load_from_data(data: &[u8]) -> Re image::load_from_memory(data) } -pub fn reupload_texture_from_rgb_image(tex: &mut Texture<Flat, Dim2, NormRGB8UI>, img: DynamicImage) -> Result<(), TextureLoadError> { +pub fn reupload_texture_from_rgb_image(tex: &mut Texture<Dim2, NormRGB8UI>, img: DynamicImage) -> Result<(), TextureLoadError> { let texels = img .pixels() .map(|(_x, _y, rgb)| (rgb[0], rgb[1], rgb[2])) @@ -118,3 +119,46 @@ pub fn load_anm_image<P: AsRef<Path>>(mu } } } + +fn load_array_texture(surface: &mut GlfwSurface, images: &[(&Path, &Path)]) -> Result<LoadedTexture, TextureLoadError> { + let mut decoded = vec![]; + let dimensions = (256, 256); + for (rgb, alpha) in images { + let img = open_alpha_png(&alpha)?; + assert_eq!(dimensions, img.dimensions()); + let alpha = match img.grayscale() { + DynamicImage::ImageLuma8(img) => img, + _ => { + return Err(TextureLoadError::AlphaToGrayscale(alpha.to_str().unwrap().to_owned())) + } + }; + let img = open_rgb_png(&rgb)?; + assert_eq!(dimensions, img.dimensions()); + let texels = merge_rgb_alpha(&img, &alpha); + decoded.push(texels); + } + + // create the luminance texture; the third argument is the number of mipmaps we want (leave it + // to 0 for now) and the latest is a the sampler to use when sampling the texels in the + // shader (we’ll just use the default one) + let tex = + Texture::new(surface, ([dimensions.0, dimensions.1], images.len() as u32), 0, Sampler::default()).expect("luminance texture creation"); + + // the first argument disables mipmap generation (we don’t care so far) + tex.upload(GenMipmaps::No, &decoded.into_iter().flatten().collect::<Vec<_>>()).unwrap(); + + Ok(LoadedTexture::RgbaArray(tex)) +} + +pub fn load_multiple_anm_images<P: AsRef<Path>>(mut surface: &mut GlfwSurface, anms: &[Anm0], anm_filename: P) -> Result<LoadedTexture, TextureLoadError> { + let anm_filename = anm_filename.as_ref(); + let mut paths = vec![]; + for anm0 in anms.iter() { + let rgb_filename = anm_filename.with_file_name(Path::new(&anm0.png_filename).file_name().unwrap()); + let filename = anm0.alpha_filename.as_ref().expect("Can’t not have alpha here!"); + let alpha_filename = anm_filename.with_file_name(Path::new(filename).file_name().unwrap()); + paths.push((rgb_filename, alpha_filename)); + } + let paths: Vec<_> = paths.iter().map(|(rgb, alpha)| (rgb.as_ref(), alpha.as_ref())).collect(); + load_array_texture(&mut surface, paths.as_slice()) +}