Mercurial > touhou
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 } |