comparison 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
comparison
equal deleted inserted replaced
752:5e5e7136ac92 753:a662dddd4a2b
1 use image::{GenericImageView, DynamicImage, GrayImage, ImageError}; 1 use image::{GenericImageView, DynamicImage, GrayImage, ImageError};
2 use luminance::pixel::{NormRGB8UI, NormRGBA8UI}; 2 use luminance::pixel::{NormRGB8UI, NormRGBA8UI};
3 use luminance::texture::{Dim2, Flat, Sampler, Texture, GenMipmaps}; 3 use luminance::texture::{Dim2, Dim2Array, Sampler, Texture, GenMipmaps};
4 use luminance_glfw::GlfwSurface; 4 use luminance_glfw::GlfwSurface;
5 use touhou::th06::anm0::Anm0; 5 use touhou::th06::anm0::Anm0;
6 use std::fs::File; 6 use std::fs::File;
7 use std::io::{self, BufReader, Read}; 7 use std::io::{self, BufReader, Read};
8 use std::path::Path; 8 use std::path::Path;
14 file.read_to_end(&mut buf)?; 14 file.read_to_end(&mut buf)?;
15 Ok(buf) 15 Ok(buf)
16 } 16 }
17 17
18 pub enum LoadedTexture { 18 pub enum LoadedTexture {
19 Rgba(Texture<Flat, Dim2, NormRGBA8UI>), 19 Rgba(Texture<Dim2, NormRGBA8UI>),
20 Rgb(Texture<Flat, Dim2, NormRGB8UI>), 20 Rgb(Texture<Dim2, NormRGB8UI>),
21 RgbaArray(Texture<Dim2Array, NormRGBA8UI>),
21 } 22 }
22 23
23 #[derive(Debug)] 24 #[derive(Debug)]
24 pub enum TextureLoadError { 25 pub enum TextureLoadError {
25 CannotOpenRgb(String, ImageError), 26 CannotOpenRgb(String, ImageError),
47 48
48 pub fn load_from_data(data: &[u8]) -> Result<DynamicImage, ImageError> { 49 pub fn load_from_data(data: &[u8]) -> Result<DynamicImage, ImageError> {
49 image::load_from_memory(data) 50 image::load_from_memory(data)
50 } 51 }
51 52
52 pub fn reupload_texture_from_rgb_image(tex: &mut Texture<Flat, Dim2, NormRGB8UI>, img: DynamicImage) -> Result<(), TextureLoadError> { 53 pub fn reupload_texture_from_rgb_image(tex: &mut Texture<Dim2, NormRGB8UI>, img: DynamicImage) -> Result<(), TextureLoadError> {
53 let texels = img 54 let texels = img
54 .pixels() 55 .pixels()
55 .map(|(_x, _y, rgb)| (rgb[0], rgb[1], rgb[2])) 56 .map(|(_x, _y, rgb)| (rgb[0], rgb[1], rgb[2]))
56 .collect::<Vec<_>>(); 57 .collect::<Vec<_>>();
57 58
116 None => { 117 None => {
117 load_rgb_texture(&mut surface, &png_filename) 118 load_rgb_texture(&mut surface, &png_filename)
118 } 119 }
119 } 120 }
120 } 121 }
122
123 fn load_array_texture(surface: &mut GlfwSurface, images: &[(&Path, &Path)]) -> Result<LoadedTexture, TextureLoadError> {
124 let mut decoded = vec![];
125 let dimensions = (256, 256);
126 for (rgb, alpha) in images {
127 let img = open_alpha_png(&alpha)?;
128 assert_eq!(dimensions, img.dimensions());
129 let alpha = match img.grayscale() {
130 DynamicImage::ImageLuma8(img) => img,
131 _ => {
132 return Err(TextureLoadError::AlphaToGrayscale(alpha.to_str().unwrap().to_owned()))
133 }
134 };
135 let img = open_rgb_png(&rgb)?;
136 assert_eq!(dimensions, img.dimensions());
137 let texels = merge_rgb_alpha(&img, &alpha);
138 decoded.push(texels);
139 }
140
141 // create the luminance texture; the third argument is the number of mipmaps we want (leave it
142 // to 0 for now) and the latest is a the sampler to use when sampling the texels in the
143 // shader (we’ll just use the default one)
144 let tex =
145 Texture::new(surface, ([dimensions.0, dimensions.1], images.len() as u32), 0, Sampler::default()).expect("luminance texture creation");
146
147 // the first argument disables mipmap generation (we don’t care so far)
148 tex.upload(GenMipmaps::No, &decoded.into_iter().flatten().collect::<Vec<_>>()).unwrap();
149
150 Ok(LoadedTexture::RgbaArray(tex))
151 }
152
153 pub fn load_multiple_anm_images<P: AsRef<Path>>(mut surface: &mut GlfwSurface, anms: &[Anm0], anm_filename: P) -> Result<LoadedTexture, TextureLoadError> {
154 let anm_filename = anm_filename.as_ref();
155 let mut paths = vec![];
156 for anm0 in anms.iter() {
157 let rgb_filename = anm_filename.with_file_name(Path::new(&anm0.png_filename).file_name().unwrap());
158 let filename = anm0.alpha_filename.as_ref().expect("Can’t not have alpha here!");
159 let alpha_filename = anm_filename.with_file_name(Path::new(filename).file_name().unwrap());
160 paths.push((rgb_filename, alpha_filename));
161 }
162 let paths: Vec<_> = paths.iter().map(|(rgb, alpha)| (rgb.as_ref(), alpha.as_ref())).collect();
163 load_array_texture(&mut surface, paths.as_slice())
164 }