Skip to content

Commit

Permalink
Merge pull request #76572 from acazuc/ktx_format_support
Browse files Browse the repository at this point in the history
Add support for KTX image format so that we can use Basis Universal for GLTF
  • Loading branch information
akien-mga authored Aug 19, 2023
2 parents 91cc7aa + a00cf02 commit 5444afa
Show file tree
Hide file tree
Showing 55 changed files with 20,856 additions and 0 deletions.
6 changes: 6 additions & 0 deletions COPYRIGHT.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ Comment: jpeg-compressor
Copyright: 2012, Rich Geldreich
License: public-domain or Apache-2.0

Files: ./thirdparty/libktx/
Comment: KTX
Copyright: 2013-2020, Mark Callow
2010-2020 The Khronos Group, Inc.
License: Apache-2.0

Files: ./thirdparty/libogg/
Comment: OggVorbis
Copyright: 2002, Xiph.org Foundation
Expand Down
10 changes: 10 additions & 0 deletions core/io/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3018,6 +3018,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::_dds_mem_loader_func = nullptr;
ImageMemLoadFunc Image::_ktx_mem_loader_func = nullptr;

void (*Image::_image_compress_bc_func)(Image *, Image::UsedChannels) = nullptr;
void (*Image::_image_compress_bptc_func)(Image *, Image::UsedChannels) = nullptr;
Expand Down Expand Up @@ -3490,6 +3491,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_dds_from_buffer", "buffer"), &Image::load_dds_from_buffer);
ClassDB::bind_method(D_METHOD("load_ktx_from_buffer", "buffer"), &Image::load_ktx_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 @@ -3873,6 +3875,14 @@ Error Image::load_dds_from_buffer(const Vector<uint8_t> &p_array) {
return _load_from_buffer(p_array, _dds_mem_loader_func);
}

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

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

static void (*_image_compress_bc_func)(Image *, UsedChannels p_channels);
static void (*_image_compress_bptc_func)(Image *, UsedChannels p_channels);
Expand Down Expand Up @@ -404,6 +405,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_dds_from_buffer(const Vector<uint8_t> &p_array);
Error load_ktx_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
7 changes: 7 additions & 0 deletions doc/classes/Image.xml
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,13 @@
Loads an image from the binary contents of a JPEG file.
</description>
</method>
<method name="load_ktx_from_buffer">
<return type="int" enum="Error" />
<param index="0" name="buffer" type="PackedByteArray" />
<description>
Loads an image from the binary contents of a KTX file.
</description>
</method>
<method name="load_png_from_buffer">
<return type="int" enum="Error" />
<param index="0" name="buffer" type="PackedByteArray" />
Expand Down
66 changes: 66 additions & 0 deletions modules/gltf/extensions/gltf_document_extension_texture_ktx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**************************************************************************/
/* gltf_document_extension_texture_ktx.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#include "gltf_document_extension_texture_ktx.h"

// Import process.
Error GLTFDocumentExtensionTextureKTX::import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) {
if (!p_extensions.has("KHR_texture_basisu")) {
return ERR_SKIP;
}
return OK;
}

Vector<String> GLTFDocumentExtensionTextureKTX::get_supported_extensions() {
Vector<String> ret;
ret.push_back("KHR_texture_basisu");
return ret;
}

Error GLTFDocumentExtensionTextureKTX::parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image) {
if (p_mime_type == "image/ktx2") {
return r_image->load_ktx_from_buffer(p_image_data);
}
return OK;
}

Error GLTFDocumentExtensionTextureKTX::parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture) {
if (!p_texture_json.has("extensions")) {
return OK;
}
const Dictionary &extensions = p_texture_json["extensions"];
if (!extensions.has("KHR_texture_basisu")) {
return OK;
}
const Dictionary &texture_ktx = extensions["KHR_texture_basisu"];
ERR_FAIL_COND_V(!texture_ktx.has("source"), ERR_PARSE_ERROR);
r_gltf_texture->set_src_image(texture_ktx["source"]);
return OK;
}
47 changes: 47 additions & 0 deletions modules/gltf/extensions/gltf_document_extension_texture_ktx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**************************************************************************/
/* gltf_document_extension_texture_ktx.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef GLTF_DOCUMENT_EXTENSION_TEXTURE_KTX_H
#define GLTF_DOCUMENT_EXTENSION_TEXTURE_KTX_H

#include "gltf_document_extension.h"

class GLTFDocumentExtensionTextureKTX : public GLTFDocumentExtension {
GDCLASS(GLTFDocumentExtensionTextureKTX, GLTFDocumentExtension);

public:
// Import process.
Error import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) override;
Vector<String> get_supported_extensions() override;
Error parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image) override;
Error parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture) override;
};

#endif // GLTF_DOCUMENT_EXTENSION_TEXTURE_KTX_H
2 changes: 2 additions & 0 deletions modules/gltf/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "register_types.h"

#include "extensions/gltf_document_extension_convert_importer_mesh.h"
#include "extensions/gltf_document_extension_texture_ktx.h"
#include "extensions/gltf_document_extension_texture_webp.h"
#include "extensions/gltf_spec_gloss.h"
#include "extensions/physics/gltf_document_extension_physics.h"
Expand Down Expand Up @@ -118,6 +119,7 @@ void initialize_gltf_module(ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(GLTFTextureSampler);
// Register GLTFDocumentExtension classes with GLTFDocument.
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionPhysics);
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionTextureKTX);
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionTextureWebP);
bool is_editor = ::Engine::get_singleton()->is_editor_hint();
if (!is_editor) {
Expand Down
60 changes: 60 additions & 0 deletions modules/ktx/SCsub
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env python

Import("env")
Import("env_modules")

env_ktx = env_modules.Clone()

# libktx thirdparty source files

thirdparty_obj = []

thirdparty_dir = "#thirdparty/libktx/"
thirdparty_sources = [
"lib/checkheader.c",
"lib/filestream.c",
"lib/hashlist.c",
"lib/memstream.c",
"lib/swap.c",
"lib/texture.c",
"lib/texture1.c",
"lib/texture2.c",
"lib/dfdutils/createdfd.c",
"lib/dfdutils/colourspaces.c",
"lib/dfdutils/interpretdfd.c",
"lib/dfdutils/printdfd.c",
"lib/dfdutils/queries.c",
"lib/dfdutils/vk2dfd.c",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]

env_ktx.Prepend(CPPPATH=[thirdparty_dir + "include"])
env_ktx.Prepend(CPPPATH=[thirdparty_dir + "utils"])
env_ktx.Prepend(CPPPATH=[thirdparty_dir + "lib"])
env_ktx.Prepend(CPPPATH=[thirdparty_dir + "other_include"])

if env["module_basis_universal_enabled"]:
thirdparty_sources += [thirdparty_dir + "lib/basis_transcode.cpp"]
env_ktx.Prepend(CPPPATH=["#thirdparty/basis_universal"])

if env["vulkan"]:
env_ktx.Prepend(CPPPATH=["#thirdparty/vulkan/include"])
else:
# Falls back on bundled `vkformat_enum.h`.
env_ktx.Append(CPPDEFINES=["LIBKTX"])

env_ktx.Append(CPPDEFINES=[("KHRONOS_STATIC", 1)])

env_thirdparty = env_ktx.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
env.modules_sources += thirdparty_obj

# Godot source files
module_obj = []

env_ktx.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj

# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)
6 changes: 6 additions & 0 deletions modules/ktx/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def can_build(env, platform):
return True


def configure(env):
pass
53 changes: 53 additions & 0 deletions modules/ktx/register_types.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**************************************************************************/
/* register_types.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#include "register_types.h"

#include "texture_loader_ktx.h"

static Ref<ResourceFormatKTX> resource_loader_ktx;

void initialize_ktx_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}

resource_loader_ktx.instantiate();
ResourceLoader::add_resource_format_loader(resource_loader_ktx);
}

void uninitialize_ktx_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}

ResourceLoader::remove_resource_format_loader(resource_loader_ktx);
resource_loader_ktx.unref();
}
39 changes: 39 additions & 0 deletions modules/ktx/register_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**************************************************************************/
/* register_types.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef KTX_REGISTER_TYPES_H
#define KTX_REGISTER_TYPES_H

#include "modules/register_module_types.h"

void initialize_ktx_module(ModuleInitializationLevel p_level);
void uninitialize_ktx_module(ModuleInitializationLevel p_level);

#endif // KTX_REGISTER_TYPES_H
Loading

0 comments on commit 5444afa

Please sign in to comment.