aboutsummaryrefslogtreecommitdiff
path: root/src/classes
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes')
-rw-r--r--src/classes/texture2d.rs77
1 files changed, 63 insertions, 14 deletions
diff --git a/src/classes/texture2d.rs b/src/classes/texture2d.rs
index 2bc1ade..e3f3225 100644
--- a/src/classes/texture2d.rs
+++ b/src/classes/texture2d.rs
@@ -1,7 +1,8 @@
use super::{FromValue, streaminginfo::StreamingInfo};
use crate::object::Value;
use anyhow::{Result, bail};
-use image::{DynamicImage, Rgb, Rgba};
+use image::{DynamicImage, ImageBuffer, Luma, Rgb, Rgba};
+use log::info;
use serde::Serialize;
use std::mem::transmute;
@@ -11,6 +12,7 @@ pub struct Texture2D {
pub height: i32,
pub mip_count: i32,
pub name: String,
+ #[serde(skip)]
pub image_data: Vec<u8>,
pub format: TextureFormat,
pub texture_dimension: i32,
@@ -45,23 +47,70 @@ impl Texture2D {
let w = self.width as usize;
let h = self.height as usize;
use TextureFormat::*;
+ let u32_rgba_buf_to_image = |buf: Vec<u32>| {
+ let buf = buf.into_iter().flat_map(u32::to_be_bytes).collect();
+ let im = ImageBuffer::<Rgba<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf).unwrap();
+ im.into()
+ };
match self.format {
- DXT1 | DXT3 | DXT5 => {
- use texpresso::Format::*;
- let mut buf = vec![0u8; w * h * 4];
+ Alpha8 => {
+ let buf = self.image_data.clone();
+ let im =
+ ImageBuffer::<Luma<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf).unwrap();
+ Ok(im.into())
+ }
+ RGBAHalf => {
+ let buf = self
+ .image_data
+ .clone()
+ .into_iter()
+ .array_chunks::<2>()
+ .map(|x| u16::from_be_bytes(x))
+ .map(|x| f16::from_bits(x) as f32)
+ .collect::<Vec<f32>>();
+ Ok(
+ ImageBuffer::<Rgba<f32>, Vec<_>>::from_raw(w as u32, h as u32, buf)
+ .unwrap()
+ .into(),
+ )
+ }
+ DXT1 | DXT3 | DXT5 | BC4 | BC5 => {
+ use texpresso::Format as F;
let format = match self.format {
- DXT1 => Bc1,
- DXT3 => Bc2,
- DXT5 => Bc3,
+ DXT1 => F::Bc1,
+ DXT3 => F::Bc2,
+ DXT5 => F::Bc3,
+ BC4 => F::Bc4,
+ BC5 => F::Bc5,
_ => unreachable!(),
};
+ info!(
+ "decompressing {w}x{h} {:?} ({:?}) texture",
+ format, self.format
+ );
+ let mut buf = vec![0u8; w * h * 4];
format.decompress(&self.image_data, w, h, &mut buf);
- let im = image::ImageBuffer::<Rgba<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf)
- .unwrap();
+ let im =
+ ImageBuffer::<Rgba<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf).unwrap();
Ok(im.into())
}
+ DXT1Crunched | DXT5Crunched => {
+ let mut buf = vec![0u32; w * h];
+ texture2ddecoder::decode_unity_crunch(&self.image_data, w, h, &mut buf).unwrap();
+ Ok(u32_rgba_buf_to_image(buf))
+ }
+ BC7 => {
+ let mut buf = vec![0u32; w * h];
+ texture2ddecoder::decode_bc7(&self.image_data, w, h, &mut buf).unwrap();
+ Ok(u32_rgba_buf_to_image(buf))
+ }
+ BC6H => {
+ let mut buf = vec![0u32; w * h];
+ texture2ddecoder::decode_bc6(&self.image_data, w, h, &mut buf, false).unwrap();
+ Ok(u32_rgba_buf_to_image(buf))
+ }
RGB24 => {
- let im = image::ImageBuffer::<Rgb<u8>, Vec<_>>::from_raw(
+ let im = ImageBuffer::<Rgb<u8>, Vec<_>>::from_raw(
w as u32,
h as u32,
self.image_data.clone(),
@@ -78,14 +127,14 @@ impl Texture2D {
pix[2] = pix[3];
pix[3] = a;
}
- let im = image::ImageBuffer::<Rgba<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf)
- .unwrap();
+ let im =
+ ImageBuffer::<Rgba<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf).unwrap();
Ok(im.into())
}
RGBA32 => {
let buf = self.image_data.clone();
- let im = image::ImageBuffer::<Rgba<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf)
- .unwrap();
+ let im =
+ ImageBuffer::<Rgba<u8>, Vec<_>>::from_raw(w as u32, h as u32, buf).unwrap();
Ok(im.into())
}
x => bail!("texture format {x:?} not supported"),