Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement loading DDS textures at run-time again #101549

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions core/io/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr;
ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr;
ScalableImageMemLoadFunc Image::_svg_scalable_mem_loader_func = nullptr;
ImageMemLoadFunc Image::_ktx_mem_loader_func = nullptr;
ImageMemLoadFunc Image::_dds_mem_loader_func = nullptr;

// External VRAM compression function pointers.

Expand Down Expand Up @@ -3577,6 +3578,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_tga_from_buffer", "buffer"), &Image::load_tga_from_buffer);
ClassDB::bind_method(D_METHOD("load_bmp_from_buffer", "buffer"), &Image::load_bmp_from_buffer);
ClassDB::bind_method(D_METHOD("load_ktx_from_buffer", "buffer"), &Image::load_ktx_from_buffer);
ClassDB::bind_method(D_METHOD("load_dds_from_buffer", "buffer"), &Image::load_dds_from_buffer);

ClassDB::bind_method(D_METHOD("load_svg_from_buffer", "buffer", "scale"), &Image::load_svg_from_buffer, DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("load_svg_from_string", "svg_str", "scale"), &Image::load_svg_from_string, DEFVAL(1.0));
Expand Down Expand Up @@ -4102,6 +4104,14 @@ Error Image::load_ktx_from_buffer(const Vector<uint8_t> &p_array) {
return _load_from_buffer(p_array, _ktx_mem_loader_func);
}

Error Image::load_dds_from_buffer(const Vector<uint8_t> &p_array) {
ERR_FAIL_NULL_V_MSG(
_dds_mem_loader_func,
ERR_UNAVAILABLE,
"The DDS module isn't enabled. Recompile the Redot editor or export template binary with the `module_dds_enabled=yes` SCons option.");
return _load_from_buffer(p_array, _dds_mem_loader_func);
}

void Image::convert_rg_to_ra_rgba8() {
ERR_FAIL_COND(format != FORMAT_RGBA8);
ERR_FAIL_COND(data.is_empty());
Expand Down
2 changes: 2 additions & 0 deletions core/io/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class Image : public Resource {
static ImageMemLoadFunc _bmp_mem_loader_func;
static ScalableImageMemLoadFunc _svg_scalable_mem_loader_func;
static ImageMemLoadFunc _ktx_mem_loader_func;
static ImageMemLoadFunc _dds_mem_loader_func;

// External VRAM compression function pointers.

Expand Down Expand Up @@ -403,6 +404,7 @@ class Image : public Resource {
Error load_tga_from_buffer(const Vector<uint8_t> &p_array);
Error load_bmp_from_buffer(const Vector<uint8_t> &p_array);
Error load_ktx_from_buffer(const Vector<uint8_t> &p_array);
Error load_dds_from_buffer(const Vector<uint8_t> &p_array);

Error load_svg_from_buffer(const Vector<uint8_t> &p_array, float scale = 1.0);
Error load_svg_from_string(const String &p_svg_str, float scale = 1.0);
Expand Down
28 changes: 23 additions & 5 deletions core/io/image_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,15 @@ void ImageFormatLoader::_bind_methods() {
BIND_BITFIELD_FLAG(FLAG_CONVERT_COLORS);
}

bool ImageFormatLoader::recognize(const String &p_extension) const {
bool ImageFormatLoader::should_import(const String &p_resource_type) const {
return true;
}

bool ImageFormatLoader::recognize(const String &p_extension, const String &p_resource_type) const {
if (!should_import(p_resource_type)) {
return false;
}

List<String> extensions;
get_recognized_extensions(&extensions);
for (const String &E : extensions) {
Expand All @@ -63,6 +71,12 @@ void ImageFormatLoaderExtension::get_recognized_extensions(List<String> *p_exten
}
}

bool ImageFormatLoaderExtension::should_import(const String &p_resource_type) const {
bool should_import = true;
GDVIRTUAL_CALL(_should_import, p_resource_type, should_import);
return should_import;
}

void ImageFormatLoaderExtension::add_format_loader() {
ImageLoader::add_image_format_loader(this);
}
Expand All @@ -73,6 +87,7 @@ void ImageFormatLoaderExtension::remove_format_loader() {

void ImageFormatLoaderExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_recognized_extensions);
GDVIRTUAL_BIND(_should_import, "resource_type");
GDVIRTUAL_BIND(_load_image, "image", "fileaccess", "flags", "scale");
ClassDB::bind_method(D_METHOD("add_format_loader"), &ImageFormatLoaderExtension::add_format_loader);
ClassDB::bind_method(D_METHOD("remove_format_loader"), &ImageFormatLoaderExtension::remove_format_loader);
Expand Down Expand Up @@ -108,15 +123,18 @@ Error ImageLoader::load_image(const String &p_file, Ref<Image> p_image, Ref<File
return ERR_FILE_UNRECOGNIZED;
}

void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
void ImageLoader::get_recognized_extensions(List<String> *p_extensions, const String &p_resource_type) {
for (int i = 0; i < loader.size(); i++) {
if (!loader[i]->should_import(p_resource_type)) {
continue;
}
loader[i]->get_recognized_extensions(p_extensions);
}
}

Ref<ImageFormatLoader> ImageLoader::recognize(const String &p_extension) {
Ref<ImageFormatLoader> ImageLoader::recognize(const String &p_extension, const String &p_resource_type) {
for (int i = 0; i < loader.size(); i++) {
if (loader[i]->recognize(p_extension)) {
if (loader[i]->recognize(p_extension, p_resource_type)) {
return loader[i];
}
}
Expand Down Expand Up @@ -167,7 +185,7 @@ Ref<Resource> ResourceFormatLoaderImage::load(const String &p_path, const String
int idx = -1;

for (int i = 0; i < ImageLoader::loader.size(); i++) {
if (ImageLoader::loader[i]->recognize(extension)) {
if (ImageLoader::loader[i]->recognize(extension, "Image")) {
idx = i;
break;
}
Expand Down
9 changes: 6 additions & 3 deletions core/io/image_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class ImageFormatLoader : public RefCounted {

virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, BitField<ImageFormatLoader::LoaderFlags> p_flags = FLAG_NONE, float p_scale = 1.0) = 0;
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
bool recognize(const String &p_extension) const;
virtual bool should_import(const String &p_resource_type) const;
bool recognize(const String &p_extension, const String &p_resource_type = "") const;

public:
virtual ~ImageFormatLoader() {}
Expand All @@ -77,11 +78,13 @@ class ImageFormatLoaderExtension : public ImageFormatLoader {
public:
virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, BitField<ImageFormatLoader::LoaderFlags> p_flags = FLAG_NONE, float p_scale = 1.0) override;
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
virtual bool should_import(const String &p_resource_type) const override;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

virtual bool should_import(const String &p_resource_type) const override; I think this was added so that Godot Engine can ignore this format loader?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah with #100538, should_import enables format loaders to designate when they would and would not be ignored by the import process based on the resource type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels wrong on a gut feeling; I've been ignoring this problem in my other pull request. #101994


void add_format_loader();
void remove_format_loader();

GDVIRTUAL0RC(PackedStringArray, _get_recognized_extensions);
GDVIRTUAL1RC(bool, _should_import, String);
GDVIRTUAL4R(Error, _load_image, Ref<Image>, Ref<FileAccess>, BitField<ImageFormatLoader::LoaderFlags>, float);
};

Expand All @@ -92,8 +95,8 @@ class ImageLoader {
protected:
public:
static Error load_image(const String &p_file, Ref<Image> p_image, Ref<FileAccess> p_custom = Ref<FileAccess>(), BitField<ImageFormatLoader::LoaderFlags> p_flags = ImageFormatLoader::FLAG_NONE, float p_scale = 1.0);
static void get_recognized_extensions(List<String> *p_extensions);
static Ref<ImageFormatLoader> recognize(const String &p_extension);
static void get_recognized_extensions(List<String> *p_extensions, const String &p_resource_type = "");
static Ref<ImageFormatLoader> recognize(const String &p_extension, const String &p_resource_type = "");

static void add_image_format_loader(Ref<ImageFormatLoader> p_loader);
static void remove_image_format_loader(Ref<ImageFormatLoader> p_loader);
Expand Down
7 changes: 7 additions & 0 deletions doc/classes/Image.xml
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,13 @@
[b]Note:[/b] This method is only available in engine builds with the BMP module enabled. By default, the BMP module is enabled, but it can be disabled at build-time using the [code]module_bmp_enabled=no[/code] SCons option.
</description>
</method>
<method name="load_dds_from_buffer">
<return type="int" enum="Error" />
<param index="0" name="buffer" type="PackedByteArray" />
<description>
Loads an image from the binary contents of a DDS file.
</description>
</method>
<method name="load_from_file" qualifiers="static">
<return type="Image" />
<param index="0" name="path" type="String" />
Expand Down
8 changes: 8 additions & 0 deletions doc/classes/ImageFormatLoaderExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
Loads the content of [param fileaccess] into the provided [param image].
</description>
</method>
<method name="_should_import" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="resource_type" type="String" />
<description>
[b]Optional.[/b]
Returns [code]true[/code] if [param resource_type] should import.
</description>
</method>
<method name="add_format_loader">
<return type="void" />
<description>
Expand Down
2 changes: 1 addition & 1 deletion editor/import/resource_importer_bitmask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ String ResourceImporterBitMap::get_visible_name() const {
}

void ResourceImporterBitMap::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
ImageLoader::get_recognized_extensions(p_extensions, get_resource_type());
}

String ResourceImporterBitMap::get_save_extension() const {
Expand Down
2 changes: 1 addition & 1 deletion editor/import/resource_importer_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ String ResourceImporterImage::get_visible_name() const {
}

void ResourceImporterImage::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
ImageLoader::get_recognized_extensions(p_extensions, get_resource_type());
}

String ResourceImporterImage::get_save_extension() const {
Expand Down
2 changes: 1 addition & 1 deletion editor/import/resource_importer_imagefont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ String ResourceImporterImageFont::get_visible_name() const {

void ResourceImporterImageFont::get_recognized_extensions(List<String> *p_extensions) const {
if (p_extensions) {
ImageLoader::get_recognized_extensions(p_extensions);
ImageLoader::get_recognized_extensions(p_extensions, get_resource_type());
}
}

Expand Down
2 changes: 1 addition & 1 deletion editor/import/resource_importer_layered_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ String ResourceImporterLayeredTexture::get_visible_name() const {
}

void ResourceImporterLayeredTexture::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
ImageLoader::get_recognized_extensions(p_extensions, get_resource_type());
}

String ResourceImporterLayeredTexture::get_save_extension() const {
Expand Down
2 changes: 1 addition & 1 deletion editor/import/resource_importer_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ String ResourceImporterTexture::get_visible_name() const {
}

void ResourceImporterTexture::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
ImageLoader::get_recognized_extensions(p_extensions, get_resource_type());
}

String ResourceImporterTexture::get_save_extension() const {
Expand Down
2 changes: 1 addition & 1 deletion editor/import/resource_importer_texture_atlas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ String ResourceImporterTextureAtlas::get_visible_name() const {
}

void ResourceImporterTextureAtlas::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
ImageLoader::get_recognized_extensions(p_extensions, get_resource_type());
}

String ResourceImporterTextureAtlas::get_save_extension() const {
Expand Down
Loading