1use std;
4use glium;
5use image;
6use log;
7
8pub const CROSSHAIR_PNG_FILE_BYTES : &[u8; 101] =
11 include_bytes!("../crosshair.png");
12pub const CROSSHAIR_INVERSE_PNG_FILE_BYTES : &[u8; 95] =
15 include_bytes!("../crosshair-inverse.png");
16pub const TILESET_EASCII_ACORN_8X8_PNG_FILE_BYTES : &[u8; 2538] =
17 include_bytes!("../tileset_eascii_acorn-bbc-micro_8x8.png");
18pub const TILESET_EASCII_ACORN_8X8_INVERSE_PNG_FILE_BYTES : &[u8; 2526] =
19 include_bytes!("../tileset_eascii_acorn-bbc-micro_8x8-inverse.png");
20pub const TILESET_EASCII_ACORN_16X16_PNG_FILE_BYTES : &[u8; 3427] =
21 include_bytes!("../tileset_eascii_acorn-bbc-micro_16x16.png");
22pub const TILESET_EASCII_ACORN_16X16_INVERSE_PNG_FILE_BYTES : &[u8; 3427] =
23 include_bytes!("../tileset_eascii_acorn-bbc-micro_16x16-inverse.png");
24pub const POINTER_HAND_PNG_FILE_BYTES_OFFSET : (&[u8; 183], [i16; 2]) =
25 (include_bytes!("../pointer-hand.png"), [3, -10]);
26
27#[derive(Debug)]
28pub enum LoadError {
29 IoError (std::io::Error),
30 ImageError (image::ImageError),
31 TextureCreationError (glium::texture::TextureCreationError)
32}
33
34pub fn texture2d_with_mipmaps_from_bytes (
36 glium_facade : &dyn glium::backend::Facade,
37 bytes : &[u8],
38 image_format : image::ImageFormat,
39 mipmaps : glium::texture::MipmapsOption
40) -> Result <glium::Texture2d, LoadError> {
41 let img = image::load_from_memory_with_format (bytes, image_format)?
42 .to_rgba8();
43 let img_dimensions = img.dimensions();
44 log::debug!(dimensions:?=img_dimensions; "texture load bytes");
45 let raw_image_2d = glium::texture::RawImage2d::from_raw_rgba_reversed (
46 img.into_raw().as_slice(),
47 img_dimensions);
48
49 glium::Texture2d::with_mipmaps (glium_facade, raw_image_2d, mipmaps)
50 .map_err (Into::into)
51}
52
53pub fn texture2d_with_mipmaps_from_file (
55 glium_facade : &dyn glium::backend::Facade,
56 filepath : &'static str,
57 image_format : image::ImageFormat,
58 mipmaps : glium::texture::MipmapsOption
59) -> Result <glium::Texture2d, LoadError> {
60 use std::io::Read;
61 log::debug!(filepath:?; "texture load file");
62 let mut file = std::fs::File::open (filepath)?;
63 let mut bytes = Vec::new();
64 let _ = file.read_to_end (&mut bytes)?;
65 texture2d_with_mipmaps_from_bytes (
66 glium_facade, bytes.as_slice(), image_format, mipmaps)
67}
68
69pub fn texture2darray_with_mipmaps_from_bytes (
72 glium_facade : &dyn glium::backend::Facade,
73 bytes_slices : &[&[u8]],
74 image_format : image::ImageFormat,
75 mipmaps : glium::texture::MipmapsOption
76) -> Result <glium::texture::Texture2dArray, LoadError> {
77 let raw_images = {
78 let mut v = Vec::with_capacity (bytes_slices.len());
79 for bytes in bytes_slices {
80 let img = image::load_from_memory_with_format (bytes, image_format)?
81 .to_rgba8();
82 let img_dimensions = img.dimensions();
83 log::debug!(dimensions:?=img_dimensions; "texture array load bytes");
84 let raw_image_2d = glium::texture::RawImage2d::from_raw_rgba_reversed (
85 img.into_raw().as_slice(),
86 img_dimensions);
87 v.push (raw_image_2d);
88 }
89 v
90 };
91
92 glium::texture::Texture2dArray::with_mipmaps (
93 glium_facade, raw_images, mipmaps
94 ).map_err (Into::into)
95}
96
97pub fn texture2darray_with_mipmaps_from_files (
100 glium_facade : &dyn glium::backend::Facade,
101 filepaths : &[&'static str],
102 image_format : image::ImageFormat,
103 mipmaps : glium::texture::MipmapsOption
104) -> Result <glium::texture::Texture2dArray, LoadError> {
105 use std::io::Read;
106
107 if filepaths.is_empty() {
108 return Err (std::io::Error::new (std::io::ErrorKind::InvalidInput,
109 "no input paths provided").into())
110 }
111
112 let bytes = {
113 let mut v = Vec::with_capacity (filepaths.len());
114 v.resize_with (filepaths.len(), Default::default);
115 for (i, filepath) in filepaths.iter().enumerate() {
116 log::debug!(filepath:?; "texture load file");
117 let mut file = std::fs::File::open (filepath)?;
118 let _ = file.read_to_end (&mut v[i])?;
119 }
120 v
121 };
122
123 let bytes_vec = {
124 let mut v = Vec::with_capacity (filepaths.len());
125 for bytes in bytes.iter() {
126 v.push (bytes.as_slice());
127 }
128 v
129 };
130
131 let texture2darray = texture2darray_with_mipmaps_from_bytes (
132 glium_facade, &bytes_vec, image_format, mipmaps)?;
133 Ok (texture2darray)
135}
136
137impl std::fmt::Display for LoadError {
141 fn fmt (&self, fmt : &mut std::fmt::Formatter) -> std::fmt::Result {
142 match *self {
143 LoadError::IoError (ref err) =>
144 write!(fmt, "I/O error: {err}"),
145 LoadError::ImageError (ref err) => err.fmt (fmt),
146 LoadError::TextureCreationError (ref err) => err.fmt (fmt)
147 }
148 }
149}
150
151impl std::error::Error for LoadError {
152 fn source (&self) -> Option <&(dyn std::error::Error + 'static)> {
153 match *self {
154 LoadError::IoError (ref err) => err.source(),
155 LoadError::ImageError (ref err) => err.source(),
156 LoadError::TextureCreationError (ref err) => err.source()
157 }
158 }
159}
160
161impl From <std::io::Error> for LoadError {
162 fn from (err : std::io::Error) -> Self {
163 LoadError::IoError (err)
164 }
165}
166
167impl From <image::ImageError> for LoadError {
168 fn from (err : image::ImageError) -> Self {
169 LoadError::ImageError (err)
170 }
171}
172
173impl From <glium::texture::TextureCreationError> for LoadError {
174 fn from (err : glium::texture::TextureCreationError) -> Self {
175 LoadError::TextureCreationError (err)
176 }
177}