diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index e67a83e6fa..941257219e 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -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 diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index 558d0ce8ce..f58a6e5d80 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -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);