Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

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