diff options
Diffstat (limited to 'modules/dds')
-rw-r--r-- | modules/dds/SCsub | 4 | ||||
-rw-r--r-- | modules/dds/config.py | 1 | ||||
-rw-r--r-- | modules/dds/register_types.cpp | 2 | ||||
-rw-r--r-- | modules/dds/register_types.h | 5 | ||||
-rw-r--r-- | modules/dds/texture_loader_dds.cpp | 106 | ||||
-rw-r--r-- | modules/dds/texture_loader_dds.h | 2 |
6 files changed, 47 insertions, 73 deletions
diff --git a/modules/dds/SCsub b/modules/dds/SCsub index 3d92ff02d6..06980bd670 100644 --- a/modules/dds/SCsub +++ b/modules/dds/SCsub @@ -1,7 +1,7 @@ #!/usr/bin/env python -Import('env') -Import('env_modules') +Import("env") +Import("env_modules") env_dds = env_modules.Clone() diff --git a/modules/dds/config.py b/modules/dds/config.py index 1c8cd12a2d..d22f9454ed 100644 --- a/modules/dds/config.py +++ b/modules/dds/config.py @@ -1,5 +1,6 @@ def can_build(env, platform): return True + def configure(env): pass diff --git a/modules/dds/register_types.cpp b/modules/dds/register_types.cpp index c6281ff01b..3991964a28 100644 --- a/modules/dds/register_types.cpp +++ b/modules/dds/register_types.cpp @@ -35,13 +35,11 @@ static Ref<ResourceFormatDDS> resource_loader_dds; void register_dds_types() { - resource_loader_dds.instance(); ResourceLoader::add_resource_format_loader(resource_loader_dds); } void unregister_dds_types() { - ResourceLoader::remove_resource_format_loader(resource_loader_dds); resource_loader_dds.unref(); } diff --git a/modules/dds/register_types.h b/modules/dds/register_types.h index 1808a4af36..3cb7b5c2a6 100644 --- a/modules/dds/register_types.h +++ b/modules/dds/register_types.h @@ -28,5 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef DDS_REGISTER_TYPES_H +#define DDS_REGISTER_TYPES_H + void register_dds_types(); void unregister_dds_types(); + +#endif // DDS_REGISTER_TYPES_H diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index a7701329d8..2f4f7d7a4c 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -29,14 +29,15 @@ /*************************************************************************/ #include "texture_loader_dds.h" + #include "core/os/file_access.h" #define PF_FOURCC(s) ((uint32_t)(((s)[3] << 24U) | ((s)[2] << 16U) | ((s)[1] << 8U) | ((s)[0]))) +// Reference: https://docs.microsoft.com/en-us/windows/win32/direct3ddds/dds-header + enum { DDS_MAGIC = 0x20534444, - DDSD_CAPS = 0x00000001, - DDSD_PIXELFORMAT = 0x00001000, DDSD_PITCH = 0x00000008, DDSD_LINEARSIZE = 0x00080000, DDSD_MIPMAPCOUNT = 0x00020000, @@ -47,7 +48,6 @@ enum { }; enum DDSFormat { - DDS_DXT1, DDS_DXT3, DDS_DXT5, @@ -94,19 +94,21 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = { { "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 } }; -RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error) { - - if (r_error) +RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { + if (r_error) { *r_error = ERR_CANT_OPEN; + } Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); - if (!f) + if (!f) { return RES(); + } FileAccessRef fref(f); - if (r_error) + if (r_error) { *r_error = ERR_FILE_CORRUPT; + } ERR_FAIL_COND_V_MSG(err != OK, RES(), "Unable to open DDS texture file '" + p_path + "'."); @@ -120,13 +122,15 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, uint32_t mipmaps = f->get_32(); //skip 11 - for (int i = 0; i < 11; i++) + for (int i = 0; i < 11; i++) { f->get_32(); + } //validate - if (magic != DDS_MAGIC || hsize != 124 || !(flags & DDSD_PIXELFORMAT) || !(flags & DDSD_CAPS)) { - + // We don't check DDSD_CAPS or DDSD_PIXELFORMAT, as they're mandatory when writing, + // but non-mandatory when reading (as some writers don't set them)... + if (magic != DDS_MAGIC || hsize != 124) { ERR_FAIL_V_MSG(RES(), "Invalid or unsupported DDS texture file '" + p_path + "'."); } @@ -157,72 +161,57 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, */ //must avoid this later - while (f->get_position() < 128) + while (f->get_position() < 128) { f->get_8(); + } DDSFormat dds_format; if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("DXT1")) { - dds_format = DDS_DXT1; } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("DXT3")) { - dds_format = DDS_DXT3; } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("DXT5")) { - dds_format = DDS_DXT5; } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("ATI1")) { - dds_format = DDS_ATI1; } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("ATI2")) { - dds_format = DDS_ATI2; } else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("A2XY")) { - dds_format = DDS_A2XY; } else if (format_flags & DDPF_RGB && format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 32 && format_red_mask == 0xff0000 && format_green_mask == 0xff00 && format_blue_mask == 0xff && format_alpha_mask == 0xff000000) { - dds_format = DDS_BGRA8; } else if (format_flags & DDPF_RGB && !(format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 24 && format_red_mask == 0xff0000 && format_green_mask == 0xff00 && format_blue_mask == 0xff) { - dds_format = DDS_BGR8; } else if (format_flags & DDPF_RGB && format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 32 && format_red_mask == 0xff && format_green_mask == 0xff00 && format_blue_mask == 0xff0000 && format_alpha_mask == 0xff000000) { - dds_format = DDS_RGBA8; } else if (format_flags & DDPF_RGB && !(format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 24 && format_red_mask == 0xff && format_green_mask == 0xff00 && format_blue_mask == 0xff0000) { - dds_format = DDS_RGB8; } else if (format_flags & DDPF_RGB && format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 16 && format_red_mask == 0x00007c00 && format_green_mask == 0x000003e0 && format_blue_mask == 0x0000001f && format_alpha_mask == 0x00008000) { - dds_format = DDS_BGR5A1; } else if (format_flags & DDPF_RGB && format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 32 && format_red_mask == 0x3ff00000 && format_green_mask == 0xffc00 && format_blue_mask == 0x3ff && format_alpha_mask == 0xc0000000) { - dds_format = DDS_BGR10A2; } else if (format_flags & DDPF_RGB && !(format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 16 && format_red_mask == 0x0000f800 && format_green_mask == 0x000007e0 && format_blue_mask == 0x0000001f) { - dds_format = DDS_BGR565; } else if (!(format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 8 && format_red_mask == 0xff && format_green_mask == 0xff && format_blue_mask == 0xff) { - dds_format = DDS_LUMINANCE; } else if ((format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 16 && format_red_mask == 0xff && format_green_mask == 0xff && format_blue_mask == 0xff && format_alpha_mask == 0xff00) { - dds_format = DDS_LUMINANCE_ALPHA; } else if (format_flags & DDPF_INDEXED && format_rgb_bits == 8) { - dds_format = DDS_BGR565; } else { - printf("unrecognized fourcc %x format_flags: %x - rgbbits %i - red_mask %x green mask %x blue mask %x alpha mask %x\n", format_fourcc, format_flags, format_rgb_bits, format_red_mask, format_green_mask, format_blue_mask, format_alpha_mask); ERR_FAIL_V_MSG(RES(), "Unrecognized or unsupported color layout in DDS '" + p_path + "'."); } - if (!(flags & DDSD_MIPMAPCOUNT)) + if (!(flags & DDSD_MIPMAPCOUNT)) { mipmaps = 1; + } - PoolVector<uint8_t> src_data; + Vector<uint8_t> src_data; const DDSFormatInfo &info = dds_format_info[dds_format]; uint32_t w = width; @@ -236,7 +225,6 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, ERR_FAIL_COND_V(!(flags & DDSD_LINEARSIZE), RES()); for (uint32_t i = 1; i < mipmaps; i++) { - w = MAX(1, w >> 1); h = MAX(1, h >> 1); uint32_t bsize = MAX(info.divisor, w) / info.divisor * MAX(info.divisor, h) / info.divisor * info.block_size; @@ -245,11 +233,10 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, } src_data.resize(size); - PoolVector<uint8_t>::Write wb = src_data.write(); - f->get_buffer(wb.ptr(), size); + uint8_t *wb = src_data.ptrw(); + f->get_buffer(wb, size); } else if (info.palette) { - //indexed ERR_FAIL_COND_V(!(flags & DDSD_PITCH), RES()); ERR_FAIL_COND_V(format_rgb_bits != 8, RES()); @@ -262,34 +249,33 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, int colsize = 3; for (int i = 0; i < 256; i++) { - - if (palette[i * 4 + 3] < 255) + if (palette[i * 4 + 3] < 255) { colsize = 4; + } } int w2 = width; int h2 = height; for (uint32_t i = 1; i < mipmaps; i++) { - w2 = (w2 + 1) >> 1; h2 = (h2 + 1) >> 1; size += w2 * h2 * info.block_size; } src_data.resize(size + 256 * colsize); - PoolVector<uint8_t>::Write wb = src_data.write(); - f->get_buffer(wb.ptr(), size); + uint8_t *wb = src_data.ptrw(); + f->get_buffer(wb, size); for (int i = 0; i < 256; i++) { - int dst_ofs = size + i * colsize; int src_ofs = i * 4; wb[dst_ofs + 0] = palette[src_ofs + 2]; wb[dst_ofs + 1] = palette[src_ofs + 1]; wb[dst_ofs + 2] = palette[src_ofs + 0]; - if (colsize == 4) + if (colsize == 4) { wb[dst_ofs + 3] = palette[src_ofs + 3]; + } } } else { //uncompressed generic... @@ -297,30 +283,27 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, uint32_t size = width * height * info.block_size; for (uint32_t i = 1; i < mipmaps; i++) { - w = (w + 1) >> 1; h = (h + 1) >> 1; size += w * h * info.block_size; } - if (dds_format == DDS_BGR565) + if (dds_format == DDS_BGR565) { size = size * 3 / 2; - else if (dds_format == DDS_BGR5A1) + } else if (dds_format == DDS_BGR5A1) { size = size * 2; + } src_data.resize(size); - PoolVector<uint8_t>::Write wb = src_data.write(); - f->get_buffer(wb.ptr(), size); + uint8_t *wb = src_data.ptrw(); + f->get_buffer(wb, size); switch (dds_format) { - case DDS_BGR5A1: { - // TO RGBA int colcount = size / 4; for (int i = colcount - 1; i >= 0; i--) { - int src_ofs = i * 2; int dst_ofs = i * 4; @@ -335,11 +318,9 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, } } break; case DDS_BGR565: { - int colcount = size / 3; for (int i = colcount - 1; i >= 0; i--) { - int src_ofs = i * 2; int dst_ofs = i * 3; @@ -353,12 +334,10 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, } break; case DDS_BGR10A2: { - // TO RGBA int colcount = size / 4; for (int i = colcount - 1; i >= 0; i--) { - int ofs = i * 4; uint32_t w32 = uint32_t(wb[ofs + 0]) | (uint32_t(wb[ofs + 1]) << 8) | (uint32_t(wb[ofs + 2]) << 16) | (uint32_t(wb[ofs + 3]) << 24); @@ -375,26 +354,21 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, } } break; case DDS_BGRA8: { - int colcount = size / 4; for (int i = 0; i < colcount; i++) { - SWAP(wb[i * 4 + 0], wb[i * 4 + 2]); } } break; case DDS_BGR8: { - int colcount = size / 3; for (int i = 0; i < colcount; i++) { - SWAP(wb[i * 3 + 0], wb[i * 3 + 2]); } } break; case DDS_RGBA8: { - /* do nothing either int colcount = size/4; @@ -413,7 +387,6 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, */ } break; case DDS_RGB8: { - // do nothing /* int colcount = size/3; @@ -424,12 +397,10 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, }*/ } break; case DDS_LUMINANCE: { - // do nothing i guess? } break; case DDS_LUMINANCE_ALPHA: { - // do nothing i guess? } break; @@ -444,25 +415,24 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Ref<ImageTexture> texture = memnew(ImageTexture); texture->create_from_image(img); - if (r_error) + if (r_error) { *r_error = OK; + } return texture; } void ResourceFormatDDS::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("dds"); } bool ResourceFormatDDS::handles_type(const String &p_type) const { - - return ClassDB::is_parent_class(p_type, "Texture"); + return ClassDB::is_parent_class(p_type, "Texture2D"); } String ResourceFormatDDS::get_resource_type(const String &p_path) const { - - if (p_path.get_extension().to_lower() == "dds") + if (p_path.get_extension().to_lower() == "dds") { return "ImageTexture"; + } return ""; } diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h index 34f4e9b548..ef08967df7 100644 --- a/modules/dds/texture_loader_dds.h +++ b/modules/dds/texture_loader_dds.h @@ -36,7 +36,7 @@ class ResourceFormatDDS : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; |