mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
add support for uncompressed luminance and luminance-alpha dds files
This commit is contained in:
parent
5f3cd68162
commit
30155fb72e
@ -2776,6 +2776,12 @@ do_read_dds(istream &in, const string &filename, bool header_only) {
|
||||
header.pf.b_mask == 0x000000ff &&
|
||||
header.pf.a_mask == 0xff000000U) {
|
||||
func = read_dds_level_rgba8;
|
||||
|
||||
} else if (header.pf.r_mask != 0 &&
|
||||
header.pf.g_mask == 0 &&
|
||||
header.pf.b_mask == 0) {
|
||||
func = read_dds_level_luminance_uncompressed;
|
||||
format = F_luminance_alpha;
|
||||
}
|
||||
} else {
|
||||
// An uncompressed format that doesn't involve alpha.
|
||||
@ -2789,8 +2795,15 @@ do_read_dds(istream &in, const string &filename, bool header_only) {
|
||||
header.pf.g_mask == 0x0000ff00 &&
|
||||
header.pf.b_mask == 0x00ff0000) {
|
||||
func = read_dds_level_rgb8;
|
||||
|
||||
} else if (header.pf.r_mask != 0 &&
|
||||
header.pf.g_mask == 0 &&
|
||||
header.pf.b_mask == 0) {
|
||||
func = read_dds_level_luminance_uncompressed;
|
||||
format = F_luminance;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
do_setup_texture(texture_type, header.width, header.height, header.depth,
|
||||
@ -5074,6 +5087,91 @@ read_dds_level_generic_uncompressed(Texture *tex, const DDSHeader &header,
|
||||
return image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::read_dds_level_luminance_uncompressed
|
||||
// Access: Private, Static
|
||||
// Description: Called by read_dds for a DDS file in uncompressed
|
||||
// luminance or luminance-alpha format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_uchar Texture::
|
||||
read_dds_level_luminance_uncompressed(Texture *tex, const DDSHeader &header,
|
||||
int n, istream &in) {
|
||||
int x_size = tex->do_get_expected_mipmap_x_size(n);
|
||||
int y_size = tex->do_get_expected_mipmap_y_size(n);
|
||||
|
||||
int pitch = (x_size * header.pf.rgb_bitcount) / 8;
|
||||
|
||||
// MS says the pitch can be supplied in the header file and must be
|
||||
// DWORD aligned, but this appears to apply to level 0 mipmaps only
|
||||
// (where it almost always will be anyway). Other mipmap levels
|
||||
// seem to be tightly packed, but there isn't a separate pitch for
|
||||
// each mipmap level. Weird.
|
||||
if (n == 0) {
|
||||
pitch = ((pitch + 3) / 4) * 4;
|
||||
if (header.dds_flags & DDSD_PITCH) {
|
||||
pitch = header.pitch;
|
||||
}
|
||||
}
|
||||
|
||||
int bpp = header.pf.rgb_bitcount / 8;
|
||||
int skip_bytes = pitch - (bpp * x_size);
|
||||
nassertr(skip_bytes >= 0, PTA_uchar());
|
||||
|
||||
unsigned int r_mask = header.pf.r_mask;
|
||||
unsigned int a_mask = header.pf.a_mask;
|
||||
|
||||
// Determine the number of bits to shift each mask to the right so
|
||||
// that the lowest on bit is at bit 0.
|
||||
int r_shift = get_lowest_on_bit(r_mask);
|
||||
int a_shift = get_lowest_on_bit(a_mask);
|
||||
|
||||
// Then determine the scale factor required to raise the highest
|
||||
// color value to 0xff000000.
|
||||
unsigned int r_scale = 0;
|
||||
if (r_mask != 0) {
|
||||
r_scale = 0xff000000 / (r_mask >> r_shift);
|
||||
}
|
||||
unsigned int a_scale = 0;
|
||||
if (a_mask != 0) {
|
||||
a_scale = 0xff000000 / (a_mask >> a_shift);
|
||||
}
|
||||
|
||||
bool add_alpha = has_alpha(tex->_format);
|
||||
|
||||
size_t size = tex->do_get_expected_ram_mipmap_page_size(n);
|
||||
size_t row_bytes = x_size * tex->_num_components;
|
||||
PTA_uchar image = PTA_uchar::empty_array(size);
|
||||
for (int y = y_size - 1; y >= 0; --y) {
|
||||
unsigned char *p = image.p() + y * row_bytes;
|
||||
for (int x = 0; x < x_size; ++x) {
|
||||
|
||||
// Read a little-endian numeric value of bpp bytes.
|
||||
unsigned int pixel = 0;
|
||||
int shift = 0;
|
||||
for (int bi = 0; bi < bpp; ++bi) {
|
||||
unsigned int ch = (unsigned char)in.get();
|
||||
pixel |= (ch << shift);
|
||||
shift += 8;
|
||||
}
|
||||
|
||||
unsigned int r = (((pixel & r_mask) >> r_shift) * r_scale) >> 24;
|
||||
|
||||
// Store the components in the Texture's image data.
|
||||
store_unscaled_byte(p, r);
|
||||
if (add_alpha) {
|
||||
unsigned int a = (((pixel & a_mask) >> a_shift) * a_scale) >> 24;
|
||||
store_unscaled_byte(p, a);
|
||||
}
|
||||
}
|
||||
nassertr(p <= image.p() + size, PTA_uchar());
|
||||
for (int bi = 0; bi < skip_bytes; ++bi) {
|
||||
in.get();
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::read_dds_level_dxt1
|
||||
// Access: Private, Static
|
||||
|
@ -591,6 +591,9 @@ private:
|
||||
static PTA_uchar read_dds_level_generic_uncompressed(Texture *tex,
|
||||
const DDSHeader &header,
|
||||
int n, istream &in);
|
||||
static PTA_uchar read_dds_level_luminance_uncompressed(Texture *tex,
|
||||
const DDSHeader &header,
|
||||
int n, istream &in);
|
||||
static PTA_uchar read_dds_level_dxt1(Texture *tex,
|
||||
const DDSHeader &header,
|
||||
int n, istream &in);
|
||||
|
Loading…
x
Reference in New Issue
Block a user