Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

915 рядки
24 KiB

  1. use std::fs::File;
  2. use std::io::{Read, Seek};
  3. use std::path::Path;
  4. use imagefmt::{read_from, ColFmt, Error as ImageFmtError};
  5. use crate::{
  6. error::Error,
  7. misc::{AsEnum, BindGuard, Bindable},
  8. };
  9. /* Texture */
  10. pub struct Texture {
  11. id: gl::GLuint,
  12. target: Target,
  13. filter_min: FilterMin,
  14. filter_mag: FilterMag,
  15. wrap_s: Wrap,
  16. wrap_t: Wrap,
  17. wrap_r: Wrap,
  18. }
  19. impl Texture {
  20. pub fn new(target: Target) -> Result<Self, Error> {
  21. let mut id = 0;
  22. Error::checked(|| gl::create_textures(target.as_enum(), 1, &mut id))?;
  23. Ok(Self {
  24. id,
  25. target,
  26. filter_min: FilterMin::Nearest,
  27. filter_mag: FilterMag::Nearest,
  28. wrap_s: Wrap::Repeat,
  29. wrap_t: Wrap::Repeat,
  30. wrap_r: Wrap::Repeat,
  31. })
  32. }
  33. pub fn upload(&mut self, data: &Data, generate_mipmap: bool) -> Result<(), Error> {
  34. let info = data.format.info();
  35. if info.gl_format == 0 || info.gl_format_data == 0 || info.gl_format_internal == 0 {
  36. return Err(Error::TextureUnsupportedFormat);
  37. }
  38. let target = self.target.as_enum();
  39. let _guard = BindGuard::new(&*self);
  40. Error::checked(|| {
  41. gl::tex_image_2d(
  42. target,
  43. 0,
  44. info.gl_format_internal as gl::GLint,
  45. data.width as gl::GLint,
  46. data.height as gl::GLint,
  47. 0,
  48. info.gl_format,
  49. info.gl_format_data,
  50. data.buffer.as_ptr() as *const _,
  51. )
  52. })?;
  53. if generate_mipmap {
  54. Error::checked(|| gl::generate_mipmap(target))?;
  55. }
  56. self.setup()
  57. }
  58. pub fn set_filter(&mut self, min: FilterMin, mag: FilterMag) -> Result<(), Error> {
  59. self.filter_min = min;
  60. self.filter_mag = mag;
  61. self.setup()
  62. }
  63. pub fn set_wrap(&mut self, s: Wrap, t: Wrap, r: Wrap) -> Result<(), Error> {
  64. self.wrap_s = s;
  65. self.wrap_t = t;
  66. self.wrap_r = r;
  67. self.setup()
  68. }
  69. fn setup(&self) -> Result<(), Error> {
  70. Error::checked(|| {
  71. gl::texture_parameter_i(
  72. self.id,
  73. gl::TEXTURE_MIN_FILTER,
  74. self.filter_min.as_enum() as gl::GLint,
  75. )
  76. })?;
  77. Error::checked(|| {
  78. gl::texture_parameter_i(
  79. self.id,
  80. gl::TEXTURE_MAG_FILTER,
  81. self.filter_mag.as_enum() as gl::GLint,
  82. )
  83. })?;
  84. Error::checked(|| {
  85. gl::texture_parameter_i(
  86. self.id,
  87. gl::TEXTURE_WRAP_S,
  88. self.wrap_s.as_enum() as gl::GLint,
  89. )
  90. })?;
  91. Error::checked(|| {
  92. gl::texture_parameter_i(
  93. self.id,
  94. gl::TEXTURE_WRAP_T,
  95. self.wrap_t.as_enum() as gl::GLint,
  96. )
  97. })?;
  98. Error::checked(|| {
  99. gl::texture_parameter_i(
  100. self.id,
  101. gl::TEXTURE_WRAP_R,
  102. self.wrap_r.as_enum() as gl::GLint,
  103. )
  104. })?;
  105. Ok(())
  106. }
  107. }
  108. impl Bindable for Texture {
  109. fn bind(&self) {
  110. gl::bind_texture(self.target.as_enum(), self.id);
  111. }
  112. fn unbind(&self) {
  113. gl::bind_texture(self.target.as_enum(), 0);
  114. }
  115. }
  116. /* Data */
  117. #[derive(Clone, Debug)]
  118. pub struct Data {
  119. width: usize,
  120. height: usize,
  121. format: Format,
  122. buffer: Vec<u8>,
  123. }
  124. impl Data {
  125. pub fn from_parts(width: usize, height: usize, format: Format, buffer: Vec<u8>) -> Self {
  126. Self {
  127. width,
  128. height,
  129. format,
  130. buffer,
  131. }
  132. }
  133. pub fn from_reader<R>(reader: &mut R) -> Result<Self, Error>
  134. where
  135. R: Read + Seek,
  136. {
  137. let image = read_from(reader, ColFmt::Auto)?;
  138. Ok(Self {
  139. width: image.w,
  140. height: image.h,
  141. format: match image.fmt {
  142. ColFmt::Y => Format::Luminance8ub1,
  143. ColFmt::YA => Format::Luminance8Alpha8ub2,
  144. ColFmt::AY => Format::Alpha8Luminance8ub2,
  145. ColFmt::RGB => Format::RGB8ub3,
  146. ColFmt::RGBA => Format::RGBA8ub4,
  147. ColFmt::BGR => Format::BGR8ub3,
  148. ColFmt::BGRA => Format::BGRA8ub4,
  149. ColFmt::ARGB => Format::ARGB8ub4,
  150. ColFmt::ABGR => Format::ABGR8ub4,
  151. ColFmt::Auto => {
  152. return Err(ImageFmtError::Internal("Unexpected Format: Auto").into())
  153. }
  154. },
  155. buffer: image.buf,
  156. })
  157. }
  158. pub fn from_file<P>(path: P) -> Result<Self, Error>
  159. where
  160. P: AsRef<Path>,
  161. {
  162. let mut file = File::open(path)?;
  163. Self::from_reader(&mut file)
  164. }
  165. pub fn format(&self) -> Format {
  166. self.format
  167. }
  168. pub fn width(&self) -> usize {
  169. self.width
  170. }
  171. pub fn height(&self) -> usize {
  172. self.height
  173. }
  174. pub fn convert<F>(&mut self, format: Format, func: F) -> Result<(), Error>
  175. where
  176. F: Fn(usize, usize, &mut PixelData),
  177. {
  178. let dst_info = format.info();
  179. let mut dst_descriptor = format.descriptor();
  180. let mut src_descriptor = self.format.descriptor();
  181. let mut tmp = Vec::with_capacity(self.width * self.height * dst_info.bits_per_pixel / 8);
  182. let mut src = self.buffer.as_slice();
  183. let mut dst = tmp.as_mut_slice();
  184. let mut data = PixelData::default();
  185. for x in 0..self.width {
  186. for y in 0..self.height {
  187. let b = src_descriptor.unmap(&mut data, src)?;
  188. src = &src[b..];
  189. func(x, y, &mut data);
  190. let b = dst_descriptor.map(&data, dst)?;
  191. dst = &mut dst[b..];
  192. }
  193. }
  194. self.buffer = tmp;
  195. Ok(())
  196. }
  197. pub fn convert_to(&mut self, format: Format) -> Result<(), Error> {
  198. if format == self.format {
  199. return Ok(());
  200. }
  201. if self.format.is_bit_equal(&format) {
  202. self.format = format;
  203. return Ok(());
  204. }
  205. let dst_info = format.info();
  206. let src_info = self.format.info();
  207. if src_info.same_size_channels(&dst_info) {
  208. self.convert(format, |_, _, _| {})
  209. } else {
  210. self.convert(format, |_, _, data| {
  211. data.r = data.r.map(|x| x * dst_info.r_max / src_info.r_max);
  212. data.g = data.g.map(|x| x * dst_info.g_max / src_info.g_max);
  213. data.b = data.b.map(|x| x * dst_info.b_max / src_info.b_max);
  214. data.a = data.a.map(|x| x * dst_info.a_max / src_info.a_max);
  215. })
  216. }
  217. }
  218. }
  219. /* FormatDescriptor */
  220. pub trait FormatDescriptor {
  221. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error>;
  222. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error>;
  223. }
  224. struct Luminance8ub1Descriptor;
  225. impl FormatDescriptor for Luminance8ub1Descriptor {
  226. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
  227. check_len(&buf, 1)?;
  228. if data.has_rgb() {
  229. buf[0] = data.luminance() as u8;
  230. } else {
  231. buf[0] = data.a.unwrap_or(0) as u8;
  232. }
  233. Ok(1)
  234. }
  235. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
  236. check_len(&buf, 1)?;
  237. data.r = Some(buf[0] as u32);
  238. data.g = Some(buf[0] as u32);
  239. data.b = Some(buf[0] as u32);
  240. data.a = None;
  241. Ok(1)
  242. }
  243. }
  244. struct Luminance8Alpha8ub2Descriptor;
  245. impl FormatDescriptor for Luminance8Alpha8ub2Descriptor {
  246. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
  247. check_len(&buf, 2)?;
  248. buf[0] = data.luminance() as u8;
  249. buf[1] = data.a.unwrap_or(255) as u8;
  250. Ok(2)
  251. }
  252. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
  253. check_len(&buf, 2)?;
  254. data.r = Some(buf[0] as u32);
  255. data.g = Some(buf[0] as u32);
  256. data.b = Some(buf[0] as u32);
  257. data.a = Some(buf[1] as u32);
  258. Ok(2)
  259. }
  260. }
  261. struct Alpha8Luminance8ub2Descriptor;
  262. impl FormatDescriptor for Alpha8Luminance8ub2Descriptor {
  263. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
  264. check_len(&buf, 2)?;
  265. buf[0] = data.a.unwrap_or(255) as u8;
  266. buf[1] = data.luminance() as u8;
  267. Ok(2)
  268. }
  269. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
  270. check_len(&buf, 2)?;
  271. data.r = Some(buf[1] as u32);
  272. data.g = Some(buf[1] as u32);
  273. data.b = Some(buf[1] as u32);
  274. data.a = Some(buf[0] as u32);
  275. Ok(2)
  276. }
  277. }
  278. struct RGB8ub3Descriptor;
  279. impl FormatDescriptor for RGB8ub3Descriptor {
  280. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
  281. check_len(&buf, 3)?;
  282. buf[0] = data.r.unwrap_or(0) as u8;
  283. buf[1] = data.g.unwrap_or(0) as u8;
  284. buf[2] = data.b.unwrap_or(0) as u8;
  285. Ok(3)
  286. }
  287. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
  288. check_len(&buf, 3)?;
  289. data.r = Some(buf[0] as u32);
  290. data.g = Some(buf[1] as u32);
  291. data.b = Some(buf[2] as u32);
  292. data.a = None;
  293. Ok(3)
  294. }
  295. }
  296. struct RGBA8ub4Descriptor;
  297. impl FormatDescriptor for RGBA8ub4Descriptor {
  298. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
  299. check_len(&buf, 4)?;
  300. buf[0] = data.r.unwrap_or(0) as u8;
  301. buf[1] = data.g.unwrap_or(0) as u8;
  302. buf[2] = data.b.unwrap_or(0) as u8;
  303. buf[3] = data.a.unwrap_or(0) as u8;
  304. Ok(4)
  305. }
  306. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
  307. check_len(&buf, 4)?;
  308. data.r = Some(buf[0] as u32);
  309. data.g = Some(buf[1] as u32);
  310. data.b = Some(buf[2] as u32);
  311. data.a = Some(buf[3] as u32);
  312. Ok(4)
  313. }
  314. }
  315. struct ARGB8ub4Descriptor;
  316. impl FormatDescriptor for ARGB8ub4Descriptor {
  317. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
  318. check_len(&buf, 4)?;
  319. buf[0] = data.a.unwrap_or(0) as u8;
  320. buf[1] = data.r.unwrap_or(0) as u8;
  321. buf[2] = data.g.unwrap_or(0) as u8;
  322. buf[3] = data.b.unwrap_or(0) as u8;
  323. Ok(4)
  324. }
  325. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
  326. check_len(&buf, 4)?;
  327. data.a = Some(buf[0] as u32);
  328. data.r = Some(buf[1] as u32);
  329. data.g = Some(buf[2] as u32);
  330. data.b = Some(buf[3] as u32);
  331. Ok(4)
  332. }
  333. }
  334. struct BGR8ub3Descriptor;
  335. impl FormatDescriptor for BGR8ub3Descriptor {
  336. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
  337. check_len(&buf, 3)?;
  338. buf[0] = data.b.unwrap_or(0) as u8;
  339. buf[1] = data.g.unwrap_or(0) as u8;
  340. buf[2] = data.r.unwrap_or(0) as u8;
  341. Ok(3)
  342. }
  343. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
  344. check_len(&buf, 3)?;
  345. data.b = Some(buf[1] as u32);
  346. data.g = Some(buf[2] as u32);
  347. data.r = Some(buf[3] as u32);
  348. data.a = None;
  349. Ok(3)
  350. }
  351. }
  352. struct BGRA8ub4Descriptor;
  353. impl FormatDescriptor for BGRA8ub4Descriptor {
  354. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
  355. check_len(&buf, 4)?;
  356. buf[0] = data.b.unwrap_or(0) as u8;
  357. buf[1] = data.g.unwrap_or(0) as u8;
  358. buf[2] = data.r.unwrap_or(0) as u8;
  359. buf[3] = data.a.unwrap_or(0) as u8;
  360. Ok(4)
  361. }
  362. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
  363. check_len(&buf, 4)?;
  364. data.b = Some(buf[0] as u32);
  365. data.g = Some(buf[1] as u32);
  366. data.r = Some(buf[2] as u32);
  367. data.a = Some(buf[3] as u32);
  368. Ok(4)
  369. }
  370. }
  371. struct ABGR8ub4Descriptor;
  372. impl FormatDescriptor for ABGR8ub4Descriptor {
  373. fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
  374. check_len(&buf, 4)?;
  375. buf[0] = data.a.unwrap_or(0) as u8;
  376. buf[1] = data.b.unwrap_or(0) as u8;
  377. buf[2] = data.g.unwrap_or(0) as u8;
  378. buf[3] = data.r.unwrap_or(0) as u8;
  379. Ok(4)
  380. }
  381. fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
  382. check_len(&buf, 4)?;
  383. data.a = Some(buf[0] as u32);
  384. data.b = Some(buf[1] as u32);
  385. data.g = Some(buf[2] as u32);
  386. data.r = Some(buf[3] as u32);
  387. Ok(4)
  388. }
  389. }
  390. fn check_len(buf: &[u8], len: usize) -> Result<(), Error> {
  391. if buf.len() < len {
  392. Err(Error::TextureBufferOverflow)
  393. } else {
  394. Ok(())
  395. }
  396. }
  397. /* PixelData */
  398. #[derive(Default)]
  399. pub struct PixelData {
  400. pub r: Option<u32>,
  401. pub g: Option<u32>,
  402. pub b: Option<u32>,
  403. pub a: Option<u32>,
  404. }
  405. impl PixelData {
  406. pub fn has_rgb(&self) -> bool {
  407. self.r.is_some() && self.g.is_some() && self.b.is_some()
  408. }
  409. pub fn luminance(&self) -> u32 {
  410. (LUMINANCE_WEIGHT_R * self.r.unwrap_or(0) as f32
  411. + LUMINANCE_WEIGHT_G * self.g.unwrap_or(0) as f32
  412. + LUMINANCE_WEIGHT_B * self.b.unwrap_or(0) as f32) as u32
  413. }
  414. }
  415. const LUMINANCE_WEIGHT_R: f32 = 0.30;
  416. const LUMINANCE_WEIGHT_G: f32 = 0.59;
  417. const LUMINANCE_WEIGHT_B: f32 = 0.11;
  418. /* FormatInfo */
  419. pub struct FormatInfo {
  420. pub gl_format: gl::GLenum,
  421. pub gl_format_data: gl::GLenum,
  422. pub gl_format_internal: gl::GLenum,
  423. pub format_gl_support: Format,
  424. pub format_with_alpha: Format,
  425. pub format_without_alpha: Format,
  426. pub bits_per_pixel: usize,
  427. pub r_max: u32,
  428. pub g_max: u32,
  429. pub b_max: u32,
  430. pub a_max: u32,
  431. pub r_bits: u32,
  432. pub g_bits: u32,
  433. pub b_bits: u32,
  434. pub a_bits: u32,
  435. }
  436. impl FormatInfo {
  437. pub fn same_size_channels(&self, other: &Self) -> bool {
  438. (self.r_bits == other.r_bits || self.r_bits == 0 || other.r_bits == 0)
  439. && (self.g_bits == other.g_bits || self.g_bits == 0 || other.g_bits == 0)
  440. && (self.b_bits == other.b_bits || self.b_bits == 0 || other.b_bits == 0)
  441. && (self.a_bits == other.a_bits || self.a_bits == 0 || other.a_bits == 0)
  442. }
  443. }
  444. static INFO_LUMINANCE8_UB1: FormatInfo = FormatInfo {
  445. gl_format: gl::LUMINANCE,
  446. gl_format_data: gl::UNSIGNED_BYTE,
  447. gl_format_internal: gl::LUMINANCE8,
  448. format_gl_support: Format::Luminance8ub1,
  449. format_with_alpha: Format::Luminance8Alpha8ub2,
  450. format_without_alpha: Format::Luminance8ub1,
  451. bits_per_pixel: 8,
  452. r_max: 255,
  453. g_max: 255,
  454. b_max: 255,
  455. a_max: 0,
  456. r_bits: 8,
  457. g_bits: 8,
  458. b_bits: 8,
  459. a_bits: 0,
  460. };
  461. static INFO_LUMINANCE8_ALPHA8_UB2: FormatInfo = FormatInfo {
  462. gl_format: gl::LUMINANCE_ALPHA,
  463. gl_format_data: gl::UNSIGNED_BYTE,
  464. gl_format_internal: gl::LUMINANCE8_ALPHA8,
  465. format_gl_support: Format::Luminance8Alpha8ub2,
  466. format_with_alpha: Format::Luminance8Alpha8ub2,
  467. format_without_alpha: Format::Luminance8ub1,
  468. bits_per_pixel: 16,
  469. r_max: 255,
  470. g_max: 255,
  471. b_max: 255,
  472. a_max: 255,
  473. r_bits: 8,
  474. g_bits: 8,
  475. b_bits: 8,
  476. a_bits: 8,
  477. };
  478. static INFO_ALPHA8_LUMINANCE8_UB2: FormatInfo = FormatInfo {
  479. gl_format: gl::LUMINANCE_ALPHA,
  480. gl_format_data: gl::UNSIGNED_BYTE,
  481. gl_format_internal: gl::LUMINANCE8_ALPHA8,
  482. format_gl_support: Format::Luminance8Alpha8ub2,
  483. format_with_alpha: Format::Alpha8Luminance8ub2,
  484. format_without_alpha: Format::Luminance8ub1,
  485. bits_per_pixel: 16,
  486. r_max: 255,
  487. g_max: 255,
  488. b_max: 255,
  489. a_max: 255,
  490. r_bits: 8,
  491. g_bits: 8,
  492. b_bits: 8,
  493. a_bits: 8,
  494. };
  495. static INFO_RGB8_UB3: FormatInfo = FormatInfo {
  496. gl_format: gl::RGB,
  497. gl_format_data: gl::UNSIGNED_BYTE,
  498. gl_format_internal: gl::RGB8,
  499. format_gl_support: Format::RGB8ub3,
  500. format_with_alpha: Format::RGBA8ub4,
  501. format_without_alpha: Format::RGB8ub3,
  502. bits_per_pixel: 24,
  503. r_max: 255,
  504. g_max: 255,
  505. b_max: 255,
  506. a_max: 0,
  507. r_bits: 8,
  508. g_bits: 8,
  509. b_bits: 8,
  510. a_bits: 0,
  511. };
  512. static INFO_RGBA8_UB4: FormatInfo = FormatInfo {
  513. gl_format: gl::RGBA,
  514. gl_format_data: gl::UNSIGNED_BYTE,
  515. gl_format_internal: gl::RGBA8,
  516. format_gl_support: Format::RGBA8ub4,
  517. format_with_alpha: Format::RGBA8ub4,
  518. format_without_alpha: Format::RGB8ub3,
  519. bits_per_pixel: 32,
  520. r_max: 255,
  521. g_max: 255,
  522. b_max: 255,
  523. a_max: 255,
  524. r_bits: 8,
  525. g_bits: 8,
  526. b_bits: 8,
  527. a_bits: 8,
  528. };
  529. static INFO_ARGB8_UB4: FormatInfo = FormatInfo {
  530. gl_format: gl::RGBA,
  531. gl_format_data: gl::UNSIGNED_INT_8_8_8_8_REV,
  532. gl_format_internal: gl::RGBA8,
  533. format_gl_support: Format::ARGB8ub4,
  534. format_with_alpha: Format::ARGB8ub4,
  535. format_without_alpha: Format::RGB8ub3,
  536. bits_per_pixel: 32,
  537. r_max: 255,
  538. g_max: 255,
  539. b_max: 255,
  540. a_max: 255,
  541. r_bits: 8,
  542. g_bits: 8,
  543. b_bits: 8,
  544. a_bits: 8,
  545. };
  546. static INFO_BGR8_UB3: FormatInfo = FormatInfo {
  547. gl_format: gl::BGR,
  548. gl_format_data: gl::UNSIGNED_BYTE,
  549. gl_format_internal: gl::RGB8,
  550. format_gl_support: Format::BGR8ub3,
  551. format_with_alpha: Format::BGRA8ub4,
  552. format_without_alpha: Format::BGR8ub3,
  553. bits_per_pixel: 24,
  554. r_max: 255,
  555. g_max: 255,
  556. b_max: 255,
  557. a_max: 0,
  558. r_bits: 8,
  559. g_bits: 8,
  560. b_bits: 8,
  561. a_bits: 0,
  562. };
  563. static INFO_BGRA8_UB4: FormatInfo = FormatInfo {
  564. gl_format: gl::BGR,
  565. gl_format_data: gl::UNSIGNED_BYTE,
  566. gl_format_internal: gl::RGBA8,
  567. format_gl_support: Format::BGRA8ub4,
  568. format_with_alpha: Format::BGRA8ub4,
  569. format_without_alpha: Format::BGR8ub3,
  570. bits_per_pixel: 32,
  571. r_max: 255,
  572. g_max: 255,
  573. b_max: 255,
  574. a_max: 255,
  575. r_bits: 8,
  576. g_bits: 8,
  577. b_bits: 8,
  578. a_bits: 8,
  579. };
  580. static INFO_ABGR8_UB4: FormatInfo = FormatInfo {
  581. gl_format: gl::BGR,
  582. gl_format_data: gl::UNSIGNED_INT_8_8_8_8_REV,
  583. gl_format_internal: gl::RGBA8,
  584. format_gl_support: Format::ABGR8ub4,
  585. format_with_alpha: Format::ABGR8ub4,
  586. format_without_alpha: Format::BGR8ub3,
  587. bits_per_pixel: 32,
  588. r_max: 255,
  589. g_max: 255,
  590. b_max: 255,
  591. a_max: 255,
  592. r_bits: 8,
  593. g_bits: 8,
  594. b_bits: 8,
  595. a_bits: 8,
  596. };
  597. /* Format */
  598. #[derive(Clone, Copy, Debug, Eq, PartialEq)]
  599. pub enum Format {
  600. /// [LLLL_LLLL]
  601. Luminance8ub1,
  602. /// [LLLL_LLLL][AAAA_AAAA]
  603. Luminance8Alpha8ub2,
  604. /// [AAAA_AAAA][LLLL_LLLL]
  605. Alpha8Luminance8ub2,
  606. /// [RRRR_RRRR][GGGG_GGGG][BBBB_BBBB]
  607. RGB8ub3,
  608. /// [RRRR_RRRR][GGGG_GGGG][BBBB_BBBB][AAAA_AAAA]
  609. RGBA8ub4,
  610. /// [AAAA_AAAA][RRRR_RRRR][GGGG_GGGG][BBBB_BBBB]
  611. ARGB8ub4,
  612. /// [BBBB_BBBB][GGGG_GGGG][RRRR_RRRR]
  613. BGR8ub3,
  614. /// [BBBB_BBBB][GGGG_GGGG][RRRR_RRRR][AAAA_AAAA]
  615. BGRA8ub4,
  616. /// [AAAA_AAAA][BBBB_BBBB][GGGG_GGGG][RRRR_RRRR]
  617. ABGR8ub4,
  618. }
  619. impl Format {
  620. pub fn info(&self) -> &'static FormatInfo {
  621. match self {
  622. Format::Luminance8ub1 => &INFO_LUMINANCE8_UB1,
  623. Format::Luminance8Alpha8ub2 => &INFO_LUMINANCE8_ALPHA8_UB2,
  624. Format::Alpha8Luminance8ub2 => &INFO_ALPHA8_LUMINANCE8_UB2,
  625. Format::RGB8ub3 => &INFO_RGB8_UB3,
  626. Format::RGBA8ub4 => &INFO_RGBA8_UB4,
  627. Format::ARGB8ub4 => &INFO_ARGB8_UB4,
  628. Format::BGR8ub3 => &INFO_BGR8_UB3,
  629. Format::BGRA8ub4 => &INFO_BGRA8_UB4,
  630. Format::ABGR8ub4 => &INFO_ABGR8_UB4,
  631. }
  632. }
  633. pub fn descriptor(&self) -> Box<dyn FormatDescriptor> {
  634. match self {
  635. Format::Luminance8ub1 => Box::new(Luminance8ub1Descriptor),
  636. Format::Luminance8Alpha8ub2 => Box::new(Luminance8Alpha8ub2Descriptor),
  637. Format::Alpha8Luminance8ub2 => Box::new(Alpha8Luminance8ub2Descriptor),
  638. Format::RGB8ub3 => Box::new(RGB8ub3Descriptor),
  639. Format::RGBA8ub4 => Box::new(RGBA8ub4Descriptor),
  640. Format::ARGB8ub4 => Box::new(ARGB8ub4Descriptor),
  641. Format::BGR8ub3 => Box::new(BGR8ub3Descriptor),
  642. Format::BGRA8ub4 => Box::new(BGRA8ub4Descriptor),
  643. Format::ABGR8ub4 => Box::new(ABGR8ub4Descriptor),
  644. }
  645. }
  646. pub fn is_bit_equal(&self, _other: &Self) -> bool {
  647. false
  648. }
  649. }
  650. /* Target */
  651. pub enum Target {
  652. Texture1D,
  653. Texture2D,
  654. Texture3D,
  655. Texture1DArray,
  656. Texture2DArray,
  657. TextureRectangle,
  658. TextureCubeMap,
  659. TextureCubeMapArray,
  660. TextureBuffer,
  661. Texture2DMultisample,
  662. Texture2DMultisampleArray,
  663. }
  664. impl AsEnum for Target {
  665. fn as_enum(&self) -> gl::GLenum {
  666. match self {
  667. Self::Texture1D => gl::TEXTURE_1D,
  668. Self::Texture2D => gl::TEXTURE_2D,
  669. Self::Texture3D => gl::TEXTURE_3D,
  670. Self::Texture1DArray => gl::TEXTURE_1D_ARRAY,
  671. Self::Texture2DArray => gl::TEXTURE_2D_ARRAY,
  672. Self::TextureRectangle => gl::TEXTURE_RECTANGLE,
  673. Self::TextureCubeMap => gl::TEXTURE_CUBE_MAP,
  674. Self::TextureCubeMapArray => gl::TEXTURE_CUBE_MAP_ARRAY,
  675. Self::TextureBuffer => gl::TEXTURE_BUFFER,
  676. Self::Texture2DMultisample => gl::TEXTURE_2D_MULTISAMPLE,
  677. Self::Texture2DMultisampleArray => gl::TEXTURE_2D_MULTISAMPLE_ARRAY,
  678. }
  679. }
  680. }
  681. /* FilterMin */
  682. pub enum FilterMin {
  683. /// Returns the value of the texture element that is nearest
  684. /// (in Manhattan distance) to the specified texture coordinates.
  685. Nearest,
  686. /// Returns the weighted average of the four texture elements
  687. /// that are closest to the specified texture coordinates.
  688. /// These can include items wrapped or repeated from other parts
  689. /// of a texture, depending on the values of GL_TEXTURE_WRAP_S
  690. /// and GL_TEXTURE_WRAP_T, and on the exact mapping.
  691. Linear,
  692. /// Chooses the mipmap that most closely matches the size of the
  693. /// pixel being textured and uses the GL_NEAREST criterion (the
  694. /// texture element closest to the specified texture coordinates)
  695. /// to produce a texture value.
  696. NearestMipmapNearest,
  697. /// Chooses the mipmap that most closely matches the size of the pixel
  698. /// being textured and uses the GL_LINEAR criterion (a weighted average
  699. /// of the four texture elements that are closest to the specified
  700. /// texture coordinates) to produce a texture value.
  701. LinearMipmapNearest,
  702. /// Chooses the two mipmaps that most closely match the size of the pixel
  703. /// being textured and uses the GL_NEAREST criterion (the texture element
  704. /// closest to the specified texture coordinates ) to produce a texture
  705. /// value from each mipmap. The final texture value is a weighted average
  706. /// of those two values.
  707. NearestMipmapLinear,
  708. /// Chooses the two mipmaps that most closely match the size of the pixel
  709. /// being textured and uses the GL_LINEAR criterion (a weighted average of
  710. /// the texture elements that are closest to the specified texture coordinates)
  711. /// to produce a texture value from each mipmap. The final texture value
  712. /// is a weighted average of those two values.
  713. LinearMipmapLinear,
  714. }
  715. impl AsEnum for FilterMin {
  716. fn as_enum(&self) -> gl::GLenum {
  717. match self {
  718. Self::Nearest => gl::NEAREST,
  719. Self::Linear => gl::LINEAR,
  720. Self::NearestMipmapNearest => gl::NEAREST_MIPMAP_NEAREST,
  721. Self::LinearMipmapNearest => gl::LINEAR_MIPMAP_NEAREST,
  722. Self::NearestMipmapLinear => gl::NEAREST_MIPMAP_LINEAR,
  723. Self::LinearMipmapLinear => gl::LINEAR_MIPMAP_LINEAR,
  724. }
  725. }
  726. }
  727. /* FilterMag */
  728. pub enum FilterMag {
  729. /// Returns the value of the texture element that is nearest
  730. /// (in Manhattan distance) to the specified texture coordinates.
  731. Nearest,
  732. /// Returns the weighted average of the texture elements that are
  733. /// closest to the specified texture coordinates. These can include
  734. /// items wrapped or repeated from other parts of a texture, depending
  735. /// on the values of GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T, and on
  736. /// the exact mapping.
  737. Linear,
  738. }
  739. impl AsEnum for FilterMag {
  740. fn as_enum(&self) -> gl::GLenum {
  741. match self {
  742. Self::Nearest => gl::NEAREST,
  743. Self::Linear => gl::LINEAR,
  744. }
  745. }
  746. }
  747. /* Wrap */
  748. pub enum Wrap {
  749. ClampToEdge,
  750. ClampToBorder,
  751. MirrorRepeat,
  752. Repeat,
  753. MirrorClampToEdge,
  754. }
  755. impl AsEnum for Wrap {
  756. fn as_enum(&self) -> gl::GLenum {
  757. match self {
  758. Self::ClampToEdge => gl::CLAMP_TO_EDGE,
  759. Self::ClampToBorder => gl::CLAMP_TO_BORDER,
  760. Self::MirrorRepeat => gl::MIRRORED_REPEAT,
  761. Self::Repeat => gl::REPEAT,
  762. Self::MirrorClampToEdge => gl::MIRROR_CLAMP_TO_EDGE,
  763. }
  764. }
  765. }