Mercurial > touhou
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()); |