mirror of
https://github.com/redstrate/Physis.git
synced 2025-05-18 16:07:46 +00:00
Add a more exhaustive list of texture formats, support BC7 textures
As seen in certain bgpart model textures.
This commit is contained in:
parent
a905234a18
commit
e2a8c695d7
5 changed files with 631 additions and 11 deletions
333
src/bcn/bc7.rs
Normal file
333
src/bcn/bc7.rs
Normal file
|
@ -0,0 +1,333 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Rudolf Kolbe
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use super::bitreader::BitReader;
|
||||||
|
use super::color::color;
|
||||||
|
use super::consts::{S_BPTC_A2, S_BPTC_A3, S_BPTC_FACTORS, S_BPTC_P2, S_BPTC_P3};
|
||||||
|
use core::mem::swap;
|
||||||
|
|
||||||
|
struct Bc7ModeInfo {
|
||||||
|
num_subsets: usize,
|
||||||
|
partition_bits: usize,
|
||||||
|
rotation_bits: usize,
|
||||||
|
index_selection_bits: usize,
|
||||||
|
color_bits: usize,
|
||||||
|
alpha_bits: usize,
|
||||||
|
endpoint_pbits: usize,
|
||||||
|
shared_pbits: usize,
|
||||||
|
index_bits: [usize; 2],
|
||||||
|
}
|
||||||
|
|
||||||
|
static S_BP7_MODE_INFO: [Bc7ModeInfo; 8] = [
|
||||||
|
// +---------------------------- num subsets
|
||||||
|
// | +------------------------- partition bits
|
||||||
|
// | | +---------------------- rotation bits
|
||||||
|
// | | | +------------------- index selection bits
|
||||||
|
// | | | | +---------------- color bits
|
||||||
|
// | | | | | +------------- alpha bits
|
||||||
|
// | | | | | | +---------- endpoint P-bits
|
||||||
|
// | | | | | | | +------- shared P-bits
|
||||||
|
// | | | | | | | | +-- 2x index bits
|
||||||
|
// { 3, 4, 0, 0, 4, 0, 1, 0, { 3, 0 } }, // 0
|
||||||
|
// { 2, 6, 0, 0, 6, 0, 0, 1, { 3, 0 } }, // 1
|
||||||
|
// { 3, 6, 0, 0, 5, 0, 0, 0, { 2, 0 } }, // 2
|
||||||
|
// { 2, 6, 0, 0, 7, 0, 1, 0, { 2, 0 } }, // 3
|
||||||
|
// { 1, 0, 2, 1, 5, 6, 0, 0, { 2, 3 } }, // 4
|
||||||
|
// { 1, 0, 2, 0, 7, 8, 0, 0, { 2, 2 } }, // 5
|
||||||
|
// { 1, 0, 0, 0, 7, 7, 1, 0, { 4, 0 } }, // 6
|
||||||
|
// { 2, 6, 0, 0, 5, 5, 1, 0, { 2, 0 } }, // 7
|
||||||
|
Bc7ModeInfo {
|
||||||
|
num_subsets: 3,
|
||||||
|
partition_bits: 4,
|
||||||
|
rotation_bits: 0,
|
||||||
|
index_selection_bits: 0,
|
||||||
|
color_bits: 4,
|
||||||
|
alpha_bits: 0,
|
||||||
|
endpoint_pbits: 1,
|
||||||
|
shared_pbits: 0,
|
||||||
|
index_bits: [3, 0],
|
||||||
|
},
|
||||||
|
Bc7ModeInfo {
|
||||||
|
num_subsets: 2,
|
||||||
|
partition_bits: 6,
|
||||||
|
rotation_bits: 0,
|
||||||
|
index_selection_bits: 0,
|
||||||
|
color_bits: 6,
|
||||||
|
alpha_bits: 0,
|
||||||
|
endpoint_pbits: 0,
|
||||||
|
shared_pbits: 1,
|
||||||
|
index_bits: [3, 0],
|
||||||
|
},
|
||||||
|
Bc7ModeInfo {
|
||||||
|
num_subsets: 3,
|
||||||
|
partition_bits: 6,
|
||||||
|
rotation_bits: 0,
|
||||||
|
index_selection_bits: 0,
|
||||||
|
color_bits: 5,
|
||||||
|
alpha_bits: 0,
|
||||||
|
endpoint_pbits: 0,
|
||||||
|
shared_pbits: 0,
|
||||||
|
index_bits: [2, 0],
|
||||||
|
},
|
||||||
|
Bc7ModeInfo {
|
||||||
|
num_subsets: 2,
|
||||||
|
partition_bits: 6,
|
||||||
|
rotation_bits: 0,
|
||||||
|
index_selection_bits: 0,
|
||||||
|
color_bits: 7,
|
||||||
|
alpha_bits: 0,
|
||||||
|
endpoint_pbits: 1,
|
||||||
|
shared_pbits: 0,
|
||||||
|
index_bits: [2, 0],
|
||||||
|
},
|
||||||
|
Bc7ModeInfo {
|
||||||
|
num_subsets: 1,
|
||||||
|
partition_bits: 0,
|
||||||
|
rotation_bits: 2,
|
||||||
|
index_selection_bits: 1,
|
||||||
|
color_bits: 5,
|
||||||
|
alpha_bits: 6,
|
||||||
|
endpoint_pbits: 0,
|
||||||
|
shared_pbits: 0,
|
||||||
|
index_bits: [2, 3],
|
||||||
|
},
|
||||||
|
Bc7ModeInfo {
|
||||||
|
num_subsets: 1,
|
||||||
|
partition_bits: 0,
|
||||||
|
rotation_bits: 2,
|
||||||
|
index_selection_bits: 0,
|
||||||
|
color_bits: 7,
|
||||||
|
alpha_bits: 8,
|
||||||
|
endpoint_pbits: 0,
|
||||||
|
shared_pbits: 0,
|
||||||
|
index_bits: [2, 2],
|
||||||
|
},
|
||||||
|
Bc7ModeInfo {
|
||||||
|
num_subsets: 1,
|
||||||
|
partition_bits: 0,
|
||||||
|
rotation_bits: 0,
|
||||||
|
index_selection_bits: 0,
|
||||||
|
color_bits: 7,
|
||||||
|
alpha_bits: 7,
|
||||||
|
endpoint_pbits: 1,
|
||||||
|
shared_pbits: 0,
|
||||||
|
index_bits: [4, 0],
|
||||||
|
},
|
||||||
|
Bc7ModeInfo {
|
||||||
|
num_subsets: 2,
|
||||||
|
partition_bits: 6,
|
||||||
|
rotation_bits: 0,
|
||||||
|
index_selection_bits: 0,
|
||||||
|
color_bits: 5,
|
||||||
|
alpha_bits: 5,
|
||||||
|
endpoint_pbits: 1,
|
||||||
|
shared_pbits: 0,
|
||||||
|
index_bits: [2, 0],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn expand_quantized(v: u8, bits: usize) -> u8 {
|
||||||
|
let s = ((v as u16) << (8 - bits as u16)) as u8;
|
||||||
|
s | s.overflowing_shr(bits as u32).0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode_bc7_block(data: &[u8], outbuf: &mut [u32]) {
|
||||||
|
let mut bit = BitReader::new(data, 0);
|
||||||
|
let mode = {
|
||||||
|
let mut mode = 0;
|
||||||
|
while 0 == bit.read(1) && mode < 8 {
|
||||||
|
mode += 1;
|
||||||
|
}
|
||||||
|
mode
|
||||||
|
};
|
||||||
|
|
||||||
|
if mode == 8 {
|
||||||
|
outbuf[0..16].fill(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mi: &Bc7ModeInfo = &S_BP7_MODE_INFO[mode];
|
||||||
|
let mode_pbits: usize = if 0 != mi.endpoint_pbits {
|
||||||
|
mi.endpoint_pbits
|
||||||
|
} else {
|
||||||
|
mi.shared_pbits
|
||||||
|
};
|
||||||
|
|
||||||
|
let partition_set_idx: usize = bit.read(mi.partition_bits) as usize;
|
||||||
|
let rotation_mode: u8 = bit.read(mi.rotation_bits) as u8;
|
||||||
|
let index_selection_mode: usize = bit.read(mi.index_selection_bits) as usize;
|
||||||
|
|
||||||
|
let mut ep_r: [u8; 6] = [0; 6];
|
||||||
|
let mut ep_g: [u8; 6] = [0; 6];
|
||||||
|
let mut ep_b: [u8; 6] = [0; 6];
|
||||||
|
let mut ep_a: [u8; 6] = [0; 6];
|
||||||
|
|
||||||
|
(0..mi.num_subsets).for_each(|ii| {
|
||||||
|
ep_r[ii * 2] = (bit.read(mi.color_bits) << mode_pbits) as u8;
|
||||||
|
ep_r[ii * 2 + 1] = (bit.read(mi.color_bits) << mode_pbits) as u8;
|
||||||
|
});
|
||||||
|
|
||||||
|
(0..mi.num_subsets).for_each(|ii| {
|
||||||
|
ep_g[ii * 2] = (bit.read(mi.color_bits) << mode_pbits) as u8;
|
||||||
|
ep_g[ii * 2 + 1] = (bit.read(mi.color_bits) << mode_pbits) as u8;
|
||||||
|
});
|
||||||
|
|
||||||
|
(0..mi.num_subsets).for_each(|ii| {
|
||||||
|
ep_b[ii * 2] = (bit.read(mi.color_bits) << mode_pbits) as u8;
|
||||||
|
ep_b[ii * 2 + 1] = (bit.read(mi.color_bits) << mode_pbits) as u8;
|
||||||
|
});
|
||||||
|
|
||||||
|
if mi.alpha_bits > 0 {
|
||||||
|
(0..mi.num_subsets).for_each(|ii| {
|
||||||
|
ep_a[ii * 2] = (bit.read(mi.alpha_bits) << mode_pbits) as u8;
|
||||||
|
ep_a[ii * 2 + 1] = (bit.read(mi.alpha_bits) << mode_pbits) as u8;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ep_a = [0xff; 6];
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 != mode_pbits {
|
||||||
|
(0..mi.num_subsets).for_each(|ii| {
|
||||||
|
let pda: u8 = bit.read(mode_pbits) as u8;
|
||||||
|
let pdb: u8 = if 0 == mi.shared_pbits {
|
||||||
|
bit.read(mode_pbits) as u8
|
||||||
|
} else {
|
||||||
|
pda
|
||||||
|
};
|
||||||
|
|
||||||
|
ep_r[ii * 2] |= pda;
|
||||||
|
ep_r[ii * 2 + 1] |= pdb;
|
||||||
|
ep_g[ii * 2] |= pda;
|
||||||
|
ep_g[ii * 2 + 1] |= pdb;
|
||||||
|
ep_b[ii * 2] |= pda;
|
||||||
|
ep_b[ii * 2 + 1] |= pdb;
|
||||||
|
ep_a[ii * 2] |= pda;
|
||||||
|
ep_a[ii * 2 + 1] |= pdb;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let color_bits: usize = mi.color_bits + mode_pbits;
|
||||||
|
|
||||||
|
(0..mi.num_subsets).for_each(|ii| {
|
||||||
|
ep_r[ii * 2] = expand_quantized(ep_r[ii * 2], color_bits);
|
||||||
|
ep_r[ii * 2 + 1] = expand_quantized(ep_r[ii * 2 + 1], color_bits);
|
||||||
|
ep_g[ii * 2] = expand_quantized(ep_g[ii * 2], color_bits);
|
||||||
|
ep_g[ii * 2 + 1] = expand_quantized(ep_g[ii * 2 + 1], color_bits);
|
||||||
|
ep_b[ii * 2] = expand_quantized(ep_b[ii * 2], color_bits);
|
||||||
|
ep_b[ii * 2 + 1] = expand_quantized(ep_b[ii * 2 + 1], color_bits);
|
||||||
|
});
|
||||||
|
|
||||||
|
if mi.alpha_bits > 0 {
|
||||||
|
let alpha_bits = mi.alpha_bits + mode_pbits;
|
||||||
|
|
||||||
|
(0..mi.num_subsets).for_each(|ii| {
|
||||||
|
ep_a[ii * 2] = expand_quantized(ep_a[ii * 2], alpha_bits);
|
||||||
|
ep_a[ii * 2 + 1] = expand_quantized(ep_a[ii * 2 + 1], alpha_bits);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let has_index_bits1: bool = 0 != mi.index_bits[1];
|
||||||
|
|
||||||
|
let factors: [[u8; 16]; 2] = [
|
||||||
|
S_BPTC_FACTORS[mi.index_bits[0] - 2],
|
||||||
|
if has_index_bits1 {
|
||||||
|
S_BPTC_FACTORS[mi.index_bits[1] - 2]
|
||||||
|
} else {
|
||||||
|
S_BPTC_FACTORS[mi.index_bits[0] - 2]
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut offset: [usize; 2] = [0, mi.num_subsets * (16 * mi.index_bits[0] - 1)];
|
||||||
|
|
||||||
|
(0..4_usize).for_each(|yy| {
|
||||||
|
(0..4_usize).for_each(|xx| {
|
||||||
|
let idx = yy * 4 + xx;
|
||||||
|
|
||||||
|
let mut subset_index: usize = 0;
|
||||||
|
let mut index_anchor: usize = 0;
|
||||||
|
match mi.num_subsets {
|
||||||
|
2 => {
|
||||||
|
subset_index = (S_BPTC_P2[partition_set_idx] >> idx) & 1;
|
||||||
|
index_anchor = if 0 != subset_index {
|
||||||
|
S_BPTC_A2[partition_set_idx]
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
subset_index = (S_BPTC_P3[partition_set_idx] >> (2 * idx)) & 3;
|
||||||
|
index_anchor = if 0 != subset_index {
|
||||||
|
S_BPTC_A3[subset_index - 1][partition_set_idx]
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let anchor = idx == index_anchor;
|
||||||
|
let num: [usize; 2] = [
|
||||||
|
(mi.index_bits[0] - anchor as usize),
|
||||||
|
if has_index_bits1 {
|
||||||
|
mi.index_bits[1] - anchor as usize
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let index: [usize; 2] = {
|
||||||
|
let index_0 = bit.peek(offset[0], num[0]) as usize;
|
||||||
|
[
|
||||||
|
index_0,
|
||||||
|
if has_index_bits1 {
|
||||||
|
bit.peek(offset[1], num[1]) as usize
|
||||||
|
} else {
|
||||||
|
index_0
|
||||||
|
},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
offset[0] += num[0];
|
||||||
|
offset[1] += num[1];
|
||||||
|
|
||||||
|
// index selection mode 0 or 1
|
||||||
|
// !index_selection_mode == 1-index_selection_mode
|
||||||
|
let fc: u16 = factors[index_selection_mode][index[index_selection_mode]] as u16;
|
||||||
|
let fa: u16 = factors[1 - index_selection_mode][index[1 - index_selection_mode]] as u16;
|
||||||
|
|
||||||
|
let fca: u16 = 64 - fc;
|
||||||
|
let fcb: u16 = fc;
|
||||||
|
let faa: u16 = 64 - fa;
|
||||||
|
let fab: u16 = fa;
|
||||||
|
|
||||||
|
subset_index *= 2;
|
||||||
|
let mut rr: u8 =
|
||||||
|
((ep_r[subset_index] as u16 * fca + ep_r[subset_index + 1] as u16 * fcb + 32) >> 6)
|
||||||
|
as u8;
|
||||||
|
let mut gg: u8 =
|
||||||
|
((ep_g[subset_index] as u16 * fca + ep_g[subset_index + 1] as u16 * fcb + 32) >> 6)
|
||||||
|
as u8;
|
||||||
|
let mut bb: u8 =
|
||||||
|
((ep_b[subset_index] as u16 * fca + ep_b[subset_index + 1] as u16 * fcb + 32) >> 6)
|
||||||
|
as u8;
|
||||||
|
let mut aa: u8 =
|
||||||
|
((ep_a[subset_index] as u16 * faa + ep_a[subset_index + 1] as u16 * fab + 32) >> 6)
|
||||||
|
as u8;
|
||||||
|
|
||||||
|
match rotation_mode {
|
||||||
|
1 => {
|
||||||
|
swap(&mut aa, &mut rr);
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
swap(&mut aa, &mut gg);
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
swap(&mut aa, &mut bb);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
outbuf[idx] = color(rr, gg, bb, aa);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
73
src/bcn/bitreader.rs
Normal file
73
src/bcn/bitreader.rs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Rudolf Kolbe
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn getbits_raw(buf: &[u8], bit_offset: usize, num_bits: usize, dst: &mut [u8]) {
|
||||||
|
let bytes_offset = bit_offset / 8;
|
||||||
|
let bytes_end: usize = (bit_offset + num_bits).div_ceil(8);
|
||||||
|
dst[0..(bytes_end - bytes_offset)].copy_from_slice(&buf[bytes_offset..bytes_end]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn getbits(buf: &[u8], bit_offset: usize, num_bits: usize) -> i32 {
|
||||||
|
let shift = bit_offset % 8;
|
||||||
|
|
||||||
|
let mut raw = [0u8; 4];
|
||||||
|
getbits_raw(buf, bit_offset, num_bits, &mut raw);
|
||||||
|
|
||||||
|
// shift the bits we don't need out
|
||||||
|
i32::from_le_bytes(raw) >> shift & ((1 << num_bits) - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn getbits64(buf: &[u8], bit: isize, len: usize) -> u64 {
|
||||||
|
let mask: u64 = if len == 64 {
|
||||||
|
0xffffffffffffffff
|
||||||
|
} else {
|
||||||
|
(1 << len) - 1
|
||||||
|
};
|
||||||
|
if len == 0 {
|
||||||
|
0
|
||||||
|
} else if bit >= 64 {
|
||||||
|
u64::from_le_bytes(buf[8..16].try_into().unwrap()) >> (bit - 64) & mask
|
||||||
|
} else if bit <= 0 {
|
||||||
|
u64::from_le_bytes(buf[..8].try_into().unwrap()) << 0u64.overflowing_sub(bit as u64).0
|
||||||
|
& mask
|
||||||
|
} else if bit as usize + len <= 64 {
|
||||||
|
u64::from_le_bytes(buf[..8].try_into().unwrap()) >> bit & mask
|
||||||
|
} else {
|
||||||
|
u64::from_le_bytes(buf[..8].try_into().unwrap()) >> bit
|
||||||
|
| u64::from_le_bytes(buf[8..16].try_into().unwrap()) << (64 - bit) & mask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BitReader<'a> {
|
||||||
|
data: &'a [u8],
|
||||||
|
bit_pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitReader<'_> {
|
||||||
|
#[inline]
|
||||||
|
pub const fn new(data: &[u8], bit_pos: usize) -> BitReader {
|
||||||
|
BitReader { data, bit_pos }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn read(&mut self, num_bits: usize) -> u16 {
|
||||||
|
let ret = self.peek(0, num_bits);
|
||||||
|
self.bit_pos += num_bits;
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn peek(&self, offset: usize, num_bits: usize) -> u16 {
|
||||||
|
let bit_pos = self.bit_pos + offset;
|
||||||
|
let shift = bit_pos & 7;
|
||||||
|
|
||||||
|
let mut raw = [0u8; 4];
|
||||||
|
getbits_raw(self.data, bit_pos, num_bits, &mut raw);
|
||||||
|
let data: u32 = u32::from_le_bytes(raw);
|
||||||
|
|
||||||
|
(data >> shift as u32) as u16 & ((1 << num_bits as u16) - 1)
|
||||||
|
}
|
||||||
|
}
|
168
src/bcn/consts.rs
Normal file
168
src/bcn/consts.rs
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Rudolf Kolbe
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
// BC 6 & 7
|
||||||
|
pub(crate) static S_BPTC_A2: [usize; 64] = [
|
||||||
|
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 8, 2, 2, 8, 8, 15, 2, 8,
|
||||||
|
2, 2, 8, 8, 2, 2, 15, 15, 6, 8, 2, 8, 15, 15, 2, 8, 2, 2, 2, 15, 15, 6, 6, 2, 6, 8, 15, 15, 2,
|
||||||
|
2, 15, 15, 15, 15, 15, 2, 2, 15,
|
||||||
|
];
|
||||||
|
|
||||||
|
// BC7
|
||||||
|
pub(crate) static S_BPTC_A3: [[usize; 64]; 2] = [
|
||||||
|
[
|
||||||
|
3, 3, 15, 15, 8, 3, 15, 15, 8, 8, 6, 6, 6, 5, 3, 3, 3, 3, 8, 15, 3, 3, 6, 10, 5, 8, 8, 6,
|
||||||
|
8, 5, 15, 15, 8, 15, 3, 5, 6, 10, 8, 15, 15, 3, 15, 5, 15, 15, 15, 15, 3, 15, 5, 5, 5, 8,
|
||||||
|
5, 10, 5, 10, 8, 13, 15, 12, 3, 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
15, 8, 8, 3, 15, 15, 3, 8, 15, 15, 15, 15, 15, 15, 15, 8, 15, 8, 15, 3, 15, 8, 15, 8, 3,
|
||||||
|
15, 6, 10, 15, 15, 10, 8, 15, 3, 15, 10, 10, 8, 9, 10, 6, 15, 8, 15, 3, 6, 6, 8, 15, 3, 15,
|
||||||
|
15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 15, 15, 8,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// BC 6 & 7
|
||||||
|
pub(crate) static S_BPTC_FACTORS: [[u8; 16]; 3] = [
|
||||||
|
[0, 21, 43, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
[0, 9, 18, 27, 37, 46, 55, 64, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
[0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64],
|
||||||
|
];
|
||||||
|
|
||||||
|
// BC 6 & 7
|
||||||
|
pub(crate) static S_BPTC_P2: [usize; 64] = [
|
||||||
|
// 3210 0000000000 1111111111 2222222222 3333333333
|
||||||
|
0xcccc, // 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1
|
||||||
|
0x8888, // 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1
|
||||||
|
0xeeee, // 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1
|
||||||
|
0xecc8, // 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1
|
||||||
|
0xc880, // 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1
|
||||||
|
0xfeec, // 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
0xfec8, // 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
0xec80, // 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1
|
||||||
|
0xc800, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1
|
||||||
|
0xffec, // 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
0xfe80, // 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
0xe800, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1
|
||||||
|
0xffe8, // 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
0xff00, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
0xfff0, // 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
0xf000, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1
|
||||||
|
0xf710, // 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1
|
||||||
|
0x008e, // 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
0x7100, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0
|
||||||
|
0x08ce, // 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0
|
||||||
|
0x008c, // 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
0x7310, // 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0
|
||||||
|
0x3100, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0
|
||||||
|
0x8cce, // 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1
|
||||||
|
0x088c, // 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0
|
||||||
|
0x3110, // 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0
|
||||||
|
0x6666, // 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0
|
||||||
|
0x366c, // 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0
|
||||||
|
0x17e8, // 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0
|
||||||
|
0x0ff0, // 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0
|
||||||
|
0x718e, // 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0
|
||||||
|
0x399c, // 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0
|
||||||
|
0xaaaa, // 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
|
||||||
|
0xf0f0, // 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1
|
||||||
|
0x5a5a, // 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0
|
||||||
|
0x33cc, // 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0
|
||||||
|
0x3c3c, // 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0
|
||||||
|
0x55aa, // 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0
|
||||||
|
0x9696, // 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1
|
||||||
|
0xa55a, // 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1
|
||||||
|
0x73ce, // 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0
|
||||||
|
0x13c8, // 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0
|
||||||
|
0x324c, // 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0
|
||||||
|
0x3bdc, // 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0
|
||||||
|
0x6996, // 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
|
||||||
|
0xc33c, // 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1
|
||||||
|
0x9966, // 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1
|
||||||
|
0x0660, // 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0
|
||||||
|
0x0272, // 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0
|
||||||
|
0x04e4, // 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0
|
||||||
|
0x4e40, // 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0
|
||||||
|
0x2720, // 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0
|
||||||
|
0xc936, // 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1
|
||||||
|
0x936c, // 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1
|
||||||
|
0x39c6, // 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0
|
||||||
|
0x639c, // 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0
|
||||||
|
0x9336, // 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1
|
||||||
|
0x9cc6, // 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1
|
||||||
|
0x817e, // 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1
|
||||||
|
0xe718, // 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1
|
||||||
|
0xccf0, // 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1
|
||||||
|
0x0fcc, // 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0
|
||||||
|
0x7744, // 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0
|
||||||
|
0xee22, // 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1
|
||||||
|
];
|
||||||
|
|
||||||
|
// BC7
|
||||||
|
pub(crate) static S_BPTC_P3: [usize; 64] = [
|
||||||
|
// 76543210 0000 1111 2222 3333 4444 5555 6666 7777
|
||||||
|
0xaa685050, // 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 1, 2, 2, 2, 2
|
||||||
|
0x6a5a5040, // 0, 0, 0, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1
|
||||||
|
0x5a5a4200, // 0, 0, 0, 0, 2, 0, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1
|
||||||
|
0x5450a0a8, // 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 1, 1, 1
|
||||||
|
0xa5a50000, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2
|
||||||
|
0xa0a05050, // 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 2, 2
|
||||||
|
0x5555a0a0, // 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
0x5a5a5050, // 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1
|
||||||
|
0xaa550000, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2
|
||||||
|
0xaa555500, // 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2
|
||||||
|
0xaaaa5500, // 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
|
||||||
|
0x90909090, // 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2
|
||||||
|
0x94949494, // 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2
|
||||||
|
0xa4a4a4a4, // 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2
|
||||||
|
0xa9a59450, // 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2
|
||||||
|
0x2a0a4250, // 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0, 2, 2, 2, 0
|
||||||
|
0xa5945040, // 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2
|
||||||
|
0x0a425054, // 0, 1, 1, 1, 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0
|
||||||
|
0xa5a5a500, // 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2
|
||||||
|
0x55a0a0a0, // 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1
|
||||||
|
0xa8a85454, // 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2, 0, 2, 2, 2
|
||||||
|
0x6a6a4040, // 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 1, 2, 2, 2, 1
|
||||||
|
0xa4a45000, // 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2
|
||||||
|
0x1a1a0500, // 0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 1, 0, 2, 2, 1, 0
|
||||||
|
0x0050a4a4, // 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0
|
||||||
|
0xaaa59090, // 0, 0, 1, 2, 0, 0, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2
|
||||||
|
0x14696914, // 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1, 0, 1, 1, 0
|
||||||
|
0x69691400, // 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1
|
||||||
|
0xa08585a0, // 0, 0, 2, 2, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 2, 2
|
||||||
|
0xaa821414, // 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 0, 2, 2, 2, 2, 2
|
||||||
|
0x50a4a450, // 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1
|
||||||
|
0x6a5a0200, // 0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 1, 1, 2, 2, 2, 1
|
||||||
|
0xa9a58000, // 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 2, 2, 2
|
||||||
|
0x5090a0a8, // 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 2, 0, 0, 1, 1
|
||||||
|
0xa8a09050, // 0, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 2, 0, 2, 2, 2
|
||||||
|
0x24242424, // 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0
|
||||||
|
0x00aa5500, // 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0
|
||||||
|
0x24924924, // 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0
|
||||||
|
0x24499224, // 0, 1, 2, 0, 2, 0, 1, 2, 1, 2, 0, 1, 0, 1, 2, 0
|
||||||
|
0x50a50a50, // 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 1, 1
|
||||||
|
0x500aa550, // 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 1, 1
|
||||||
|
0xaaaa4444, // 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2
|
||||||
|
0x66660000, // 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1
|
||||||
|
0xa5a0a5a0, // 0, 0, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2, 1, 1, 2, 2
|
||||||
|
0x50a050a0, // 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 1, 1
|
||||||
|
0x69286928, // 0, 2, 2, 0, 1, 2, 2, 1, 0, 2, 2, 0, 1, 2, 2, 1
|
||||||
|
0x44aaaa44, // 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 1
|
||||||
|
0x66666600, // 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1
|
||||||
|
0xaa444444, // 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2
|
||||||
|
0x54a854a8, // 0, 2, 2, 2, 0, 1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 1
|
||||||
|
0x95809580, // 0, 0, 0, 2, 1, 1, 1, 2, 0, 0, 0, 2, 1, 1, 1, 2
|
||||||
|
0x96969600, // 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2
|
||||||
|
0xa85454a8, // 0, 2, 2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2
|
||||||
|
0x80959580, // 0, 0, 0, 2, 1, 1, 1, 2, 1, 1, 1, 2, 0, 0, 0, 2
|
||||||
|
0xaa141414, // 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2
|
||||||
|
0x96960000, // 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2
|
||||||
|
0xaaaa1414, // 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2
|
||||||
|
0xa05050a0, // 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2
|
||||||
|
0xa0a5a5a0, // 0, 0, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2
|
||||||
|
0x96000000, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2
|
||||||
|
0x40804080, // 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1
|
||||||
|
0xa9a8a9a8, // 0, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2
|
||||||
|
0xaaaaaa44, // 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
|
||||||
|
0x2a4a5254, // 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0
|
||||||
|
];
|
|
@ -6,13 +6,18 @@ extern crate alloc;
|
||||||
mod bc1;
|
mod bc1;
|
||||||
mod bc3;
|
mod bc3;
|
||||||
mod bc5;
|
mod bc5;
|
||||||
|
mod bc7;
|
||||||
|
mod bitreader;
|
||||||
mod color;
|
mod color;
|
||||||
|
mod consts;
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
pub use bc1::decode_bc1_block;
|
pub use bc1::decode_bc1_block;
|
||||||
pub use bc3::decode_bc3_block;
|
pub use bc3::decode_bc3_block;
|
||||||
pub use bc5::decode_bc5_block;
|
pub use bc5::decode_bc5_block;
|
||||||
|
pub use bc7::decode_bc7_block;
|
||||||
|
|
||||||
macros::block_decoder!(decode_bc1, 4, 4, 8, decode_bc1_block);
|
macros::block_decoder!(decode_bc1, 4, 4, 8, decode_bc1_block);
|
||||||
macros::block_decoder!(decode_bc3, 4, 4, 16, decode_bc3_block);
|
macros::block_decoder!(decode_bc3, 4, 4, 16, decode_bc3_block);
|
||||||
macros::block_decoder!(decode_bc5, 4, 4, 16, decode_bc5_block);
|
macros::block_decoder!(decode_bc5, 4, 4, 16, decode_bc5_block);
|
||||||
|
macros::block_decoder!(decode_bc7, 4, 4, 16, decode_bc7_block);
|
||||||
|
|
63
src/tex.rs
63
src/tex.rs
|
@ -9,6 +9,7 @@ use crate::ByteSpan;
|
||||||
use crate::bcn::decode_bc1;
|
use crate::bcn::decode_bc1;
|
||||||
use crate::bcn::decode_bc3;
|
use crate::bcn::decode_bc3;
|
||||||
use crate::bcn::decode_bc5;
|
use crate::bcn::decode_bc5;
|
||||||
|
use crate::bcn::decode_bc7;
|
||||||
use binrw::BinRead;
|
use binrw::BinRead;
|
||||||
use binrw::binrw;
|
use binrw::binrw;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
@ -39,6 +40,7 @@ bitflags! {
|
||||||
const TEXTURE_TYPE1_D = 0x400000;
|
const TEXTURE_TYPE1_D = 0x400000;
|
||||||
const TEXTURE_TYPE2_D = 0x800000;
|
const TEXTURE_TYPE2_D = 0x800000;
|
||||||
const TEXTURE_TYPE3_D = 0x1000000;
|
const TEXTURE_TYPE3_D = 0x1000000;
|
||||||
|
const TEXTURE_TYPE2_D_ARRAY = 0x10000000;
|
||||||
const TEXTURE_TYPE_CUBE = 0x2000000;
|
const TEXTURE_TYPE_CUBE = 0x2000000;
|
||||||
const TEXTURE_TYPE_MASK = 0x3C00000;
|
const TEXTURE_TYPE_MASK = 0x3C00000;
|
||||||
const TEXTURE_SWIZZLE = 0x4000000;
|
const TEXTURE_SWIZZLE = 0x4000000;
|
||||||
|
@ -47,15 +49,45 @@ bitflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From https://github.com/aers/FFXIVClientStructs/blob/344f5d488197e9c9d5fd78e92439e7104f25e2e0/FFXIVClientStructs/FFXIV/Client/Graphics/Kernel/Texture.cs#L97
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[brw(repr = u32)]
|
#[brw(repr = u32)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum TextureFormat {
|
enum TextureFormat {
|
||||||
B4G4R4A4 = 0x1440,
|
L8_UNORM = 0x1130,
|
||||||
B8G8R8A8 = 0x1450,
|
A8_UNORM = 0x1131,
|
||||||
BC1 = 0x3420,
|
R8_UNORM = 0x1132,
|
||||||
BC3 = 0x3431,
|
R8_UINT = 0x1133,
|
||||||
BC5 = 0x6230,
|
R16_UINT = 0x1140,
|
||||||
|
R32_UINT = 0x1150,
|
||||||
|
R8G8_UNORM = 0x1240,
|
||||||
|
B4G4R4A4_UNORM = 0x1440,
|
||||||
|
B5G5R5A1_UNORM = 0x1441,
|
||||||
|
B8G8R8A8_UNORM = 0x1450,
|
||||||
|
B8G8R8X8_UNORM = 0x1451,
|
||||||
|
R16_FLOAT = 0x2140,
|
||||||
|
R32_FLOAT = 0x2150,
|
||||||
|
R16G16_FLOAT = 0x2250,
|
||||||
|
R32G32_FLOAT = 0x2260,
|
||||||
|
R11G11B10_FLOAT = 0x2350,
|
||||||
|
R16G16B16A16_FLOAT = 0x2460,
|
||||||
|
R32G32B32A32_FLOAT = 0x2470,
|
||||||
|
BC1_UNORM = 0x3420,
|
||||||
|
BC2_UNORM = 0x3430,
|
||||||
|
BC3_UNORM = 0x3431,
|
||||||
|
D16_UNORM = 0x4140,
|
||||||
|
D24_UNORM_S8_UINT = 0x4250,
|
||||||
|
D16_UNORM_2 = 0x5140,
|
||||||
|
D24_UNORM_S8_UINT_2 = 0x5150,
|
||||||
|
BC4_UNORM = 0x6120,
|
||||||
|
BC5_UNORM = 0x6230,
|
||||||
|
BC6H_SF16 = 0x6330,
|
||||||
|
BC7_UNORM = 0x6432,
|
||||||
|
R16_UNORM = 0x7140,
|
||||||
|
R16G16_UNORM = 0x7250,
|
||||||
|
R10G10B10A2_UNORM_2 = 0x7350,
|
||||||
|
R10G10B10A2_UNORM = 0x7450,
|
||||||
|
D24_UNORM_S8_UINT_3 = 0x8250,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
|
@ -101,7 +133,7 @@ impl Texture {
|
||||||
/// Reads an existing TEX file
|
/// Reads an existing TEX file
|
||||||
pub fn from_existing(buffer: ByteSpan) -> Option<Texture> {
|
pub fn from_existing(buffer: ByteSpan) -> Option<Texture> {
|
||||||
let mut cursor = Cursor::new(buffer);
|
let mut cursor = Cursor::new(buffer);
|
||||||
let header = TexHeader::read(&mut cursor).ok()?;
|
let header = TexHeader::read(&mut cursor).unwrap();
|
||||||
|
|
||||||
cursor
|
cursor
|
||||||
.seek(SeekFrom::Start(std::mem::size_of::<TexHeader>() as u64))
|
.seek(SeekFrom::Start(std::mem::size_of::<TexHeader>() as u64))
|
||||||
|
@ -113,7 +145,7 @@ impl Texture {
|
||||||
let mut dst: Vec<u8>;
|
let mut dst: Vec<u8>;
|
||||||
|
|
||||||
match header.format {
|
match header.format {
|
||||||
TextureFormat::B4G4R4A4 => {
|
TextureFormat::B4G4R4A4_UNORM => {
|
||||||
dst =
|
dst =
|
||||||
vec![
|
vec![
|
||||||
0u8;
|
0u8;
|
||||||
|
@ -140,7 +172,7 @@ impl Texture {
|
||||||
dst_offset += 4;
|
dst_offset += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TextureFormat::B8G8R8A8 => {
|
TextureFormat::B8G8R8A8_UNORM => {
|
||||||
dst =
|
dst =
|
||||||
vec![
|
vec![
|
||||||
0u8;
|
0u8;
|
||||||
|
@ -163,7 +195,7 @@ impl Texture {
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TextureFormat::BC1 => {
|
TextureFormat::BC1_UNORM => {
|
||||||
dst = Texture::decode(
|
dst = Texture::decode(
|
||||||
&src,
|
&src,
|
||||||
header.width as usize,
|
header.width as usize,
|
||||||
|
@ -171,7 +203,7 @@ impl Texture {
|
||||||
decode_bc1,
|
decode_bc1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
TextureFormat::BC3 => {
|
TextureFormat::BC3_UNORM => {
|
||||||
dst = Texture::decode(
|
dst = Texture::decode(
|
||||||
&src,
|
&src,
|
||||||
header.width as usize,
|
header.width as usize,
|
||||||
|
@ -179,7 +211,7 @@ impl Texture {
|
||||||
decode_bc3,
|
decode_bc3,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
TextureFormat::BC5 => {
|
TextureFormat::BC5_UNORM => {
|
||||||
dst = Texture::decode(
|
dst = Texture::decode(
|
||||||
&src,
|
&src,
|
||||||
header.width as usize,
|
header.width as usize,
|
||||||
|
@ -187,6 +219,15 @@ impl Texture {
|
||||||
decode_bc5,
|
decode_bc5,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
TextureFormat::BC7_UNORM => {
|
||||||
|
dst = Texture::decode(
|
||||||
|
&src,
|
||||||
|
header.width as usize,
|
||||||
|
header.height as usize * header.depth as usize,
|
||||||
|
decode_bc7,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => panic!("Unsupported texture format {:?}!", header.format),
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Texture {
|
Some(Texture {
|
||||||
|
|
Loading…
Add table
Reference in a new issue