comparison examples/common.rs @ 745:90e907859bae

examples: Simplify PNG load functions.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sat, 18 Jan 2020 16:27:57 +0100
parents 8d29dac12219
children 0ebf6467e4ff
comparison
equal deleted inserted replaced
744:3687205fe620 745:90e907859bae
1 use image::{GenericImageView, DynamicImage, 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, Flat, 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;
25 CannotOpenRgb(String, ImageError), 25 CannotOpenRgb(String, ImageError),
26 CannotOpenAlpha(String, ImageError), 26 CannotOpenAlpha(String, ImageError),
27 AlphaToGrayscale(String), 27 AlphaToGrayscale(String),
28 } 28 }
29 29
30 fn open_rgb_png(path: &Path) -> Result<DynamicImage, TextureLoadError> {
31 // load the texture into memory as a whole bloc (i.e. no streaming)
32 image::open(&path).map_err(|e| TextureLoadError::CannotOpenRgb(path.to_str().unwrap().to_owned(), e))
33 }
34
35 fn open_alpha_png(path: &Path) -> Result<DynamicImage, TextureLoadError> {
36 // load the texture into memory as a whole bloc (i.e. no streaming)
37 image::open(&path).map_err(|e| TextureLoadError::CannotOpenAlpha(path.to_str().unwrap().to_owned(), e))
38 }
39
40 fn merge_rgb_alpha(rgb: &DynamicImage, alpha: &GrayImage) -> Vec<(u8, u8, u8, u8)> {
41 rgb
42 .pixels()
43 .zip(alpha.pixels())
44 .map(|((_x, _y, rgb), luma)| (rgb[0], rgb[1], rgb[2], luma[0]))
45 .collect::<Vec<_>>()
46 }
47
30 fn load_rgb_png(surface: &mut GlfwSurface, path: &Path) -> Result<LoadedTexture, TextureLoadError> { 48 fn load_rgb_png(surface: &mut GlfwSurface, path: &Path) -> Result<LoadedTexture, TextureLoadError> {
31 // load the texture into memory as a whole bloc (i.e. no streaming) 49 let img = open_rgb_png(&path)?;
32 match image::open(&path) { 50 let (width, height) = img.dimensions();
33 Ok(img) => { 51 let texels = img
34 let (width, height) = img.dimensions(); 52 .pixels()
35 let texels = img 53 .map(|(_x, _y, rgb)| (rgb[0], rgb[1], rgb[2]))
36 .pixels() 54 .collect::<Vec<_>>();
37 .map(|(_x, _y, rgb)| (rgb[0], rgb[1], rgb[2]))
38 .collect::<Vec<_>>();
39 55
40 // create the luminance texture; the third argument is the number of mipmaps we want (leave it 56 // create the luminance texture; the third argument is the number of mipmaps we want (leave it
41 // to 0 for now) and the latest is a the sampler to use when sampling the texels in the 57 // to 0 for now) and the latest is a the sampler to use when sampling the texels in the
42 // shader (we’ll just use the default one) 58 // shader (we’ll just use the default one)
43 let tex = 59 let tex =
44 Texture::new(surface, [width, height], 0, Sampler::default()).expect("luminance texture creation"); 60 Texture::new(surface, [width, height], 0, Sampler::default()).expect("luminance texture creation");
45 61
46 // the first argument disables mipmap generation (we don’t care so far) 62 // the first argument disables mipmap generation (we don’t care so far)
47 tex.upload(GenMipmaps::No, &texels).unwrap(); 63 tex.upload(GenMipmaps::No, &texels).unwrap();
48 64
49 Ok(LoadedTexture::Rgb(tex)) 65 Ok(LoadedTexture::Rgb(tex))
50 }
51
52 Err(e) => {
53 Err(TextureLoadError::CannotOpenRgb(path.to_str().unwrap().to_owned(), e))
54 }
55 }
56 } 66 }
57 67
58 fn load_rgb_a_pngs(surface: &mut GlfwSurface, rgb: &Path, alpha: &Path) -> Result<LoadedTexture, TextureLoadError> { 68 fn load_rgb_a_pngs(surface: &mut GlfwSurface, rgb: &Path, alpha: &Path) -> Result<LoadedTexture, TextureLoadError> {
59 // load the texture into memory as a whole bloc (i.e. no streaming) 69 let img = open_alpha_png(&alpha)?;
60 match image::open(&alpha) { 70 let alpha = match img.grayscale() {
61 Ok(img) => { 71 DynamicImage::ImageLuma8(img) => img,
62 let (width, height) = img.dimensions(); 72 _ => {
63 let alpha = match img.grayscale() { 73 return Err(TextureLoadError::AlphaToGrayscale(alpha.to_str().unwrap().to_owned()))
64 DynamicImage::ImageLuma8(img) => img, 74 }
65 _ => { 75 };
66 return Err(TextureLoadError::AlphaToGrayscale(alpha.to_str().unwrap().to_owned())) 76 let (width, height) = img.dimensions();
67 } 77 let img = open_rgb_png(&rgb)?;
68 }; 78 assert_eq!((width, height), img.dimensions());
69 let img = match image::open(&rgb) { 79 let texels = merge_rgb_alpha(&img, &alpha);
70 Ok(img) => img,
71 Err(e) => {
72 return Err(TextureLoadError::CannotOpenRgb(rgb.to_str().unwrap().to_owned(), e))
73 },
74 };
75 let texels = img
76 .pixels()
77 .zip(alpha.pixels())
78 .map(|((_x, _y, rgb), luma)| (rgb[0], rgb[1], rgb[2], luma[0]))
79 .collect::<Vec<_>>();
80 80
81 // create the luminance texture; the third argument is the number of mipmaps we want (leave it 81 // create the luminance texture; the third argument is the number of mipmaps we want (leave it
82 // to 0 for now) and the latest is a the sampler to use when sampling the texels in the 82 // to 0 for now) and the latest is a the sampler to use when sampling the texels in the
83 // shader (we’ll just use the default one) 83 // shader (we’ll just use the default one)
84 let tex = 84 let tex =
85 Texture::new(surface, [width, height], 0, Sampler::default()).expect("luminance texture creation"); 85 Texture::new(surface, [width, height], 0, Sampler::default()).expect("luminance texture creation");
86 86
87 // the first argument disables mipmap generation (we don’t care so far) 87 // the first argument disables mipmap generation (we don’t care so far)
88 tex.upload(GenMipmaps::No, &texels).unwrap(); 88 tex.upload(GenMipmaps::No, &texels).unwrap();
89 89
90 Ok(LoadedTexture::Rgba(tex)) 90 Ok(LoadedTexture::Rgba(tex))
91 }
92
93 Err(e) => {
94 Err(TextureLoadError::CannotOpenAlpha(alpha.to_str().unwrap().to_owned(), e))
95 }
96 }
97 } 91 }
98 92
99 pub fn load_anm_image<P: AsRef<Path>>(mut surface: &mut GlfwSurface, anm0: &Anm0, anm_filename: P) -> Result<LoadedTexture, TextureLoadError> { 93 pub fn load_anm_image<P: AsRef<Path>>(mut surface: &mut GlfwSurface, anm0: &Anm0, anm_filename: P) -> Result<LoadedTexture, TextureLoadError> {
100 let anm_filename = anm_filename.as_ref(); 94 let anm_filename = anm_filename.as_ref();
101 let png_filename = anm_filename.with_file_name(Path::new(&anm0.png_filename).file_name().unwrap()); 95 let png_filename = anm_filename.with_file_name(Path::new(&anm0.png_filename).file_name().unwrap());