From 8320b70eeb8a20e694f2a1ce5189247650e70b69 Mon Sep 17 00:00:00 2001 From: 2shady4u Date: Sun, 10 Mar 2024 17:02:09 +0100 Subject: [PATCH] Update source files and demo project to GDExtension --- .gitignore | 7 +- demo/Main.gd | 6 +- demo/Main.tscn | 6 +- .../bin/libkra_importer.gdnlib | 18 ----- .../bin/libkra_importer.gdns | 8 --- .../godot-krita-importer.gd | 4 +- .../krita_import_plugin.gd | 65 +++++++++---------- .../libkra_importer.gdextension | 22 +++++++ demo/default_env.tres | 6 +- demo/icon.png.import | 31 +++++---- demo/project.godot | 5 +- src/godot_kra_importer.cpp | 45 +++++++------ src/godot_kra_importer.h | 20 +++--- src/library.cpp | 18 ----- src/register_types.cpp | 40 ++++++++++++ src/register_types.h | 10 +++ 16 files changed, 168 insertions(+), 143 deletions(-) delete mode 100644 demo/addons/godot-krita-importer/bin/libkra_importer.gdnlib delete mode 100644 demo/addons/godot-krita-importer/bin/libkra_importer.gdns create mode 100644 demo/addons/godot-krita-importer/libkra_importer.gdextension delete mode 100644 src/library.cpp create mode 100644 src/register_types.cpp create mode 100644 src/register_types.h diff --git a/.gitignore b/.gitignore index 34486ee..77e8ef0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Godot-specific ignores +*.gen.* .import/ +.godot/ +/gen/ # Imported translations (automatically generated from CSV files) *.translation @@ -20,8 +23,6 @@ mono_crash.*.json *.sql *.sqlite *.db -# Do not ignore the database that is to be opened in read-only mode! -!data_to_be_packaged.db # Compiled source # ################### @@ -49,8 +50,6 @@ Thumbs.db # Etc .sconsign.dblite demo/build -test_backup_new.json -test_backup_base64_new.json # VS vsproj/.vs/ diff --git a/demo/Main.gd b/demo/Main.gd index 4bab353..2bd75b9 100644 --- a/demo/Main.gd +++ b/demo/Main.gd @@ -1,14 +1,12 @@ extends Node2D -const KraImporter = preload("res://addons/godot-krita-importer/bin/libkra_importer.gdns") - func _ready(): var importer := KraImporter.new() importer.load("res://addons/godot-krita-importer/examples/example.kra") var options := { "ignore_invisible_layers": false, - "flags/filter": false + "texture_filter": CanvasItem.TEXTURE_FILTER_NEAREST } # We can't instance this class, but we can still access the static methods! @@ -19,7 +17,7 @@ func _ready(): match(layer_data.get("type", -1)): 0: - var sprite : Sprite = import_plugin.import_paint_layer(layer_data, options) + var sprite : Sprite2D = import_plugin.import_paint_layer(layer_data, options) if sprite != null: add_child(sprite) 1: diff --git a/demo/Main.tscn b/demo/Main.tscn index cc043c2..2f9bf51 100644 --- a/demo/Main.tscn +++ b/demo/Main.tscn @@ -1,6 +1,6 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=2 format=3 uid="uid://b67rg4hn2tcgh"] -[ext_resource path="res://Main.gd" type="Script" id=1] +[ext_resource type="Script" path="res://Main.gd" id="1"] [node name="Main" type="Node2D"] -script = ExtResource( 1 ) +script = ExtResource("1") diff --git a/demo/addons/godot-krita-importer/bin/libkra_importer.gdnlib b/demo/addons/godot-krita-importer/bin/libkra_importer.gdnlib deleted file mode 100644 index 145ed32..0000000 --- a/demo/addons/godot-krita-importer/bin/libkra_importer.gdnlib +++ /dev/null @@ -1,18 +0,0 @@ -[general] - -singleton=false -load_once=true -symbol_prefix="godot_" -reloadable=false - -[entry] - -OSX.64="res://addons/godot-krita-importer/bin/osx/libkra_importer.dylib" -Windows.64="res://addons/godot-krita-importer/bin/windows/libkra_importer.dll" -X11.64="res://addons/godot-krita-importer/bin/linux/libkra_importer.so" - -[dependencies] - -OSX.64=[ ] -Windows.64=[ ] -X11.64=[ ] diff --git a/demo/addons/godot-krita-importer/bin/libkra_importer.gdns b/demo/addons/godot-krita-importer/bin/libkra_importer.gdns deleted file mode 100644 index 3f96727..0000000 --- a/demo/addons/godot-krita-importer/bin/libkra_importer.gdns +++ /dev/null @@ -1,8 +0,0 @@ -[gd_resource type="NativeScript" load_steps=2 format=2] - -[ext_resource path="res://addons/godot-krita-importer/bin/libkra_importer.gdnlib" type="GDNativeLibrary" id=1] - -[resource] -resource_name = "libkra_importer" -class_name = "KraImporter" -library = ExtResource( 1 ) diff --git a/demo/addons/godot-krita-importer/godot-krita-importer.gd b/demo/addons/godot-krita-importer/godot-krita-importer.gd index 76eea25..0b0bf6b 100644 --- a/demo/addons/godot-krita-importer/godot-krita-importer.gd +++ b/demo/addons/godot-krita-importer/godot-krita-importer.gd @@ -4,12 +4,12 @@ # See LICENSE in the project root for license information. # ############################################################################ # -tool +@tool extends EditorPlugin var import_plugin = null -func get_name() -> String: +func get_name() -> StringName: return "Godot Krita Importer" func _enter_tree(): diff --git a/demo/addons/godot-krita-importer/krita_import_plugin.gd b/demo/addons/godot-krita-importer/krita_import_plugin.gd index 88f6510..93268d3 100644 --- a/demo/addons/godot-krita-importer/krita_import_plugin.gd +++ b/demo/addons/godot-krita-importer/krita_import_plugin.gd @@ -4,7 +4,7 @@ # See LICENSE in the project root for license information. # ############################################################################ # -tool +@tool extends EditorImportPlugin enum VerbosityLevel { @@ -14,47 +14,52 @@ enum VerbosityLevel { VERY_VERBOSE } -const presets := [ - {"name": "ignore_invisible_layers", "default_value": false}, - {"name": "flags/filter", "default_value": true}, +var presets : Array[Dictionary] = [ + { + "name": "ignore_invisible_layers", + "default_value": false + },{ + "name": "texture_filter", + "default_value": CanvasItem.TEXTURE_FILTER_PARENT_NODE, + "property_hint": PROPERTY_HINT_ENUM, + "hint_string": ",".join(range(0, CanvasItem.TEXTURE_FILTER_MAX)) + }, ] -const KraImporter = preload("res://addons/godot-krita-importer/bin/libkra_importer.gdns") - -func get_import_options(preset : int) -> Array: +func _get_import_options(path : String, preset : int) -> Array[Dictionary]: return presets -func get_import_order() -> int: +func _get_import_order() -> int: return 100 -func get_importer_name() -> String: +func _get_importer_name() -> String: return "godot-krita-importer" -func get_option_visibility(option : String, options : Dictionary) -> bool: +func _get_option_visibility(path: String, option_name: StringName, options: Dictionary) -> bool: return true -func get_preset_count() -> int: +func _get_preset_count() -> int: return 1 -func get_preset_name(preset : int) -> String: +func _get_preset_name(preset : int) -> String: return "Default" -func get_priority() -> float: +func _get_priority() -> float: return 1.0 -func get_recognized_extensions() -> Array: +func _get_recognized_extensions() -> PackedStringArray: return ["kra", "krz"] -func get_resource_type() -> String: +func _get_resource_type() -> String: return "PackedScene" -func get_save_extension() -> String: +func _get_save_extension() -> String: return "scn" -func get_visible_name() -> String: +func _get_visible_name() -> String: return "Scene from Krita" -func import(source_file: String, save_path: String, options: Dictionary, platform_variants: Array, gen_files: Array) -> int: +func _import(source_file: String, save_path: String, options: Dictionary, platform_variants: Array, gen_files: Array) -> int: var importer = KraImporter.new() importer.verbosity_level = VerbosityLevel.QUIET @@ -69,7 +74,7 @@ func import(source_file: String, save_path: String, options: Dictionary, platfor match(layer_data.get("type", -1)): 0: - var sprite : Sprite = import_paint_layer(layer_data, options) + var sprite : Sprite2D = import_paint_layer(layer_data, options) if sprite != null: node.add_child(sprite) 1: @@ -81,7 +86,7 @@ func import(source_file: String, save_path: String, options: Dictionary, platfor set_owner_recursively(node, node) scene.pack(node) - var error := ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], scene) + var error := ResourceSaver.save(scene, "%s.%s" % [save_path, _get_save_extension()]) # The node needs to be freed to avoid memory leakage node.queue_free() return error @@ -96,14 +101,14 @@ static func import_group_layer(importer : KraImporter, layer_data : Dictionary, return null node.modulate.a = layer_data.get("opacity", 255.0)/255.0 - var child_uuids : PoolStringArray = layer_data.get("child_uuids", PoolStringArray()) + var child_uuids : PackedStringArray = layer_data.get("child_uuids", PackedStringArray()) # Needs to be in reverse order as to preserve layer ordering! for i in range(child_uuids.size() - 1, -1, -1): var uuid : String = child_uuids[i] var child_data : Dictionary = importer.get_layer_data_with_uuid(uuid) match(child_data.get("type", -1)): 0: - var sprite : Sprite = import_paint_layer(child_data, options) + var sprite : Sprite2D = import_paint_layer(child_data, options) if sprite != null: sprite.position -= node.position node.add_child(sprite) @@ -116,7 +121,7 @@ static func import_group_layer(importer : KraImporter, layer_data : Dictionary, return node static func import_paint_layer(layer_data : Dictionary, options: Dictionary) -> Node2D: - var sprite = Sprite.new() + var sprite = Sprite2D.new() sprite.name = layer_data.get("name", sprite.name) sprite.position = layer_data.get("position", Vector2.ZERO) sprite.centered = false @@ -126,19 +131,11 @@ static func import_paint_layer(layer_data : Dictionary, options: Dictionary) -> return null sprite.modulate.a = layer_data.get("opacity", 255.0)/255.0 - var image = Image.new() #create_from_data(width: int, height: int, use_mipmaps: bool, format: Format, data: PoolByteArray) - image.create_from_data(layer_data.width, layer_data.height, false, layer_data.format, layer_data.data) - - var texture = ImageTexture.new() - texture.create_from_image(image) - - # Disable/enable the filter option which is positioned at the second bit position - if options.get("flags/filter", true): - texture.flags = enable_bit(texture.flags, Texture.FLAG_FILTER) - else: - texture.flags = disable_bit(texture.flags, Texture.FLAG_FILTER) + var image = Image.create_from_data(layer_data.width, layer_data.height, false, layer_data.format, layer_data.data) + var texture = ImageTexture.create_from_image(image) + sprite.texture_filter = options.get("texture_filter", CanvasItem.TEXTURE_FILTER_PARENT_NODE) sprite.texture = texture return sprite diff --git a/demo/addons/godot-krita-importer/libkra_importer.gdextension b/demo/addons/godot-krita-importer/libkra_importer.gdextension new file mode 100644 index 0000000..b10b36f --- /dev/null +++ b/demo/addons/godot-krita-importer/libkra_importer.gdextension @@ -0,0 +1,22 @@ +[configuration] + +entry_symbol = "kra_importer_library_init" +compatibility_minimum = 4.2 + +[libraries] + +macos = "res://addons/godot-krita-importer/bin/libkra_importer.macos.template_debug.framework" +macos.template_release = "res://addons/godot-krita-importer/bin/libkra_importer.macos.template_release.framework" +windows.x86_64 = "res://addons/godot-krita-importer/bin/libkra_importer.windows.template_debug.x86_64.dll" +windows.template_release.x86_64 = "res://addons/godot-krita-importer/bin/libkra_importer.windows.template_release.x86_64.dll" +linux.x86_64 = "res://addons/godot-krita-importer/bin/libkra_importer.linux.template_debug.x86_64.so" +linux.template_release.x86_64 = "res://addons/godot-krita-importer/bin/libkra_importer.linux.template_release.x86_64.so" + +[dependencies] + +macos = {} +macos.template_release = {} +windows.x86_64 = {} +windows.template_release.x86_64 = {} +linux.x86_64 = {} +linux.template_release.x86_64 = {} \ No newline at end of file diff --git a/demo/default_env.tres b/demo/default_env.tres index 20207a4..4b43659 100644 --- a/demo/default_env.tres +++ b/demo/default_env.tres @@ -1,7 +1,7 @@ -[gd_resource type="Environment" load_steps=2 format=2] +[gd_resource type="Environment" load_steps=2 format=3 uid="uid://c2b0yc570iuee"] -[sub_resource type="ProceduralSky" id=1] +[sub_resource type="Sky" id="1"] [resource] background_mode = 2 -background_sky = SubResource( 1 ) +sky = SubResource("1") diff --git a/demo/icon.png.import b/demo/icon.png.import index a4c02e6..da908ec 100644 --- a/demo/icon.png.import +++ b/demo/icon.png.import @@ -1,8 +1,9 @@ [remap] importer="texture" -type="StreamTexture" -path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +type="CompressedTexture2D" +uid="uid://jdoxa5waor7i" +path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" metadata={ "vram_texture": false } @@ -10,26 +11,24 @@ metadata={ [deps] source_file="res://icon.png" -dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] +dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 +compress/hdr_compression=1 compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" process/fix_alpha_border=true process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/project.godot b/demo/project.godot index c270bf4..b2fd412 100644 --- a/demo/project.godot +++ b/demo/project.godot @@ -6,12 +6,13 @@ ; [section] ; section goes between [] ; param=value ; assign values to parameters -config_version=4 +config_version=5 [application] config/name="Krita Importer Demo" run/main_scene="res://Main.tscn" +config/features=PackedStringArray("4.2") config/icon="res://icon.png" [debug] @@ -24,4 +25,4 @@ common/enable_pause_aware_picking=true [rendering] -environment/default_environment="res://default_env.tres" +environment/defaults/default_environment="res://default_env.tres" diff --git a/src/godot_kra_importer.cpp b/src/godot_kra_importer.cpp index f6e1fa4..ecf70f9 100644 --- a/src/godot_kra_importer.cpp +++ b/src/godot_kra_importer.cpp @@ -2,36 +2,40 @@ using namespace godot; -void KraImporter::_register_methods() +void KraImporter::_bind_methods() { - register_method("load", &KraImporter::load); - register_method("get_layer_data_at", &KraImporter::get_layer_data_at); - register_method("get_layer_data_with_uuid", &KraImporter::get_layer_data_with_uuid); - - register_property("layer_count", &KraImporter::set_layer_count, &KraImporter::get_layer_count, 0); - register_property("verbosity_level", &KraImporter::set_verbosity_level, &KraImporter::get_verbosity_level, 0); + // Methods. + ClassDB::bind_method(D_METHOD("load", "path"), &KraImporter::load); + ClassDB::bind_method(D_METHOD("get_layer_data_at", "layer_index"), &KraImporter::get_layer_data_at); + ClassDB::bind_method(D_METHOD("get_layer_data_with_uuid", "UUID"), &KraImporter::get_layer_data_with_uuid); + + // Properties. + ClassDB::bind_method(D_METHOD("set_layer_count"), &KraImporter::set_layer_count); + ClassDB::bind_method(D_METHOD("get_layer_count"), &KraImporter::get_layer_count); + ADD_PROPERTY(PropertyInfo(Variant::INT, "layer_count"), "set_layer_count", "get_layer_count"); + + ClassDB::bind_method(D_METHOD("set_verbosity_level"), &KraImporter::set_verbosity_level); + ClassDB::bind_method(D_METHOD("get_verbosity_level"), &KraImporter::get_verbosity_level); + ADD_PROPERTY(PropertyInfo(Variant::INT, "verbosity_level"), "set_verbosity_level", "get_verbosity_level"); } KraImporter::KraImporter() { + document = std::make_unique(); } KraImporter::~KraImporter() { } -void KraImporter::_init() -{ - document = std::make_unique(); -} - void KraImporter::load(String p_path) { /* Find the real path */ p_path = ProjectSettings::get_singleton()->globalize_path(p_path.strip_edges()); /* Convert wstring to string */ - const char *char_path = p_path.alloc_c_string(); + const CharString dummy_path = p_path.utf8(); + const char *char_path = dummy_path.get_data(); std::wstring ws = std::wstring_convert>().from_bytes(char_path); document->load(ws); } @@ -47,7 +51,7 @@ Dictionary KraImporter::get_layer_data_at(int p_layer_index) } else { - Godot::print("Error: Index " + String(p_layer_index) + " is out of range, should be between 0 and " + String(document->layers.size())); + UtilityFunctions::printerr("Error: Index " + String(std::to_string(p_layer_index).c_str()) + " is out of range, should be between 0 and " + String(std::to_string(document->layers.size()).c_str())); return Dictionary(); } } @@ -55,7 +59,9 @@ Dictionary KraImporter::get_layer_data_at(int p_layer_index) Dictionary KraImporter::get_layer_data_with_uuid(String p_uuid) { std::unique_ptr exported_layer = std::make_unique(); - exported_layer = document->get_exported_layer_with_uuid(p_uuid.alloc_c_string()); + const CharString dummy_uuid = p_uuid.utf8(); + const char *char_uuid = dummy_uuid.get_data(); + exported_layer = document->get_exported_layer_with_uuid(char_uuid); return _get_layer_data(exported_layer); } @@ -92,7 +98,7 @@ Dictionary KraImporter::_get_layer_data(const std::unique_ptrcolor_space).c_str()) + "' color space is not supported by Godot!"); + UtilityFunctions::printerr("Error: Importing an image with the '" + String(kra::get_color_space_name(exported_layer->color_space).c_str()) + "' color space is not supported by Godot!"); layer_data["format"] = Image::FORMAT_RGBA8; /* Also force the pixel_size to 4 */ pixel_size = 4; @@ -100,13 +106,12 @@ Dictionary KraImporter::_get_layer_data(const std::unique_ptrcolor_space == kra::RGBA || exported_layer-> color_space == kra::RGBAF32) { - PoolByteArray::Write write = arr.write(); - memcpy(write.ptr(), exported_layer->data.data(), bytes); + memcpy((void *)arr.ptrw(), exported_layer->data.data(), bytes); layer_data["data"] = arr; } else @@ -120,7 +125,7 @@ Dictionary KraImporter::_get_layer_data(const std::unique_ptrchild_uuids.size(); - PoolStringArray arr = PoolStringArray(); + PackedStringArray arr = PackedStringArray(); for (const auto &uuid : exported_layer->child_uuids) { arr.push_back(uuid.c_str()); diff --git a/src/godot_kra_importer.h b/src/godot_kra_importer.h index 1f2630e..e57e982 100644 --- a/src/godot_kra_importer.h +++ b/src/godot_kra_importer.h @@ -1,9 +1,10 @@ #ifndef KRA_IMPORTER_H #define KRA_IMPORTER_H -#include -#include -#include +#include + +#include +#include #include #include @@ -13,25 +14,22 @@ namespace godot { - class KraImporter : public Reference + class KraImporter : public RefCounted { - GODOT_CLASS(KraImporter, Reference) + GDCLASS(KraImporter, RefCounted) private: std::unique_ptr document; Dictionary _get_layer_data(const std::unique_ptr &exported_layer); - public: - int layer_count; - - static void _register_methods(); + protected: + static void _bind_methods(); + public: KraImporter(); ~KraImporter(); - void _init(); - void load(String p_path); Dictionary get_layer_data_at(int p_layer_index); diff --git a/src/library.cpp b/src/library.cpp deleted file mode 100644 index 111bd0a..0000000 --- a/src/library.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "godot_kra_importer.h" - -extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) -{ - godot::Godot::gdnative_init(o); -} - -extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) -{ - godot::Godot::gdnative_terminate(o); -} - -extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) -{ - godot::Godot::nativescript_init(handle); - - godot::register_class(); -} \ No newline at end of file diff --git a/src/register_types.cpp b/src/register_types.cpp new file mode 100644 index 0000000..5f9a5a0 --- /dev/null +++ b/src/register_types.cpp @@ -0,0 +1,40 @@ +#include "register_types.h" + +#include + +#include +#include +#include + +#include "godot_kra_importer.h" + +using namespace godot; + +void initialize_kra_importer_module(ModuleInitializationLevel p_level) { + if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { + return; + } + + ClassDB::register_class(); +} + +void uninitialize_kra_importer_module(ModuleInitializationLevel p_level) { + if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { + return; + } +} + +extern "C" { + +// Initialization. + +GDExtensionBool GDE_EXPORT kra_importer_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) { + godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); + + init_obj.register_initializer(initialize_kra_importer_module); + init_obj.register_terminator(uninitialize_kra_importer_module); + init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE); + + return init_obj.init(); +} +} \ No newline at end of file diff --git a/src/register_types.h b/src/register_types.h new file mode 100644 index 0000000..1979b77 --- /dev/null +++ b/src/register_types.h @@ -0,0 +1,10 @@ +#ifndef KRA_IMPORTER_REGISTER_TYPES_H +#define KRA_IMPORTER_REGISTER_TYPES_H + +#include +using namespace godot; + +void initialize_kra_importer_module(ModuleInitializationLevel p_level); +void uninitialize_kra_importer_module(ModuleInitializationLevel p_level); + +#endif // ! KRA_IMPORTER_REGISTER_TYPES_H \ No newline at end of file