diff options
49 files changed, 519 insertions, 127 deletions
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 9327e000f5..427ce2c2cd 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -33,6 +33,10 @@ #include "core/os/os.h" #include "core/variant_parser.h" +bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const { + return p_a->get_importer_name() < p_b->get_importer_name(); +} + Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const { Error err; @@ -90,6 +94,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy r_path_and_type.type = value; } else if (assign == "importer") { r_path_and_type.importer = value; + } else if (assign == "metadata") { + r_path_and_type.metadata = value; } else if (assign == "valid") { if (r_valid) { *r_valid = value; @@ -304,6 +310,18 @@ String ResourceFormatImporter::get_resource_type(const String &p_path) const { return pat.type; } +Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) const { + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err != OK) { + + return Variant(); + } + + return pat.metadata; +} + void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { PathAndType pat; @@ -366,6 +384,35 @@ String ResourceFormatImporter::get_import_base_path(const String &p_for_file) co return "res://.import/" + p_for_file.get_file() + "-" + p_for_file.md5_text(); } +bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const { + + bool valid = true; + PathAndType pat; + _get_path_and_type(p_path, pat, &valid); + + if (!valid) { + return false; + } + + for (int i = 0; i < importers.size(); i++) { + if (importers[i]->get_importer_name() == pat.importer) { + if (!importers[i]->are_import_settings_valid(p_path)) { //importer thinks this is not valid + return false; + } + } + } + + return true; +} + +String ResourceFormatImporter::get_import_settings_hash() const { + String hash; + for (int i = 0; i < importers.size(); i++) { + hash += ":" + importers[i]->get_importer_name() + ":" + importers[i]->get_import_settings_string(); + } + return hash.md5_text(); +} + ResourceFormatImporter *ResourceFormatImporter::singleton = NULL; ResourceFormatImporter::ResourceFormatImporter() { diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 32c39a8085..db1befb51e 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -43,12 +43,18 @@ class ResourceFormatImporter : public ResourceFormatLoader { String path; String type; String importer; + Variant metadata; }; Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = NULL) const; static ResourceFormatImporter *singleton; + //need them to stay in order to compute the settings hash + struct SortImporterByName { + bool operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const; + }; + Vector<Ref<ResourceImporter> > importers; public: @@ -59,6 +65,7 @@ public: virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual Variant get_resource_metadata(const String &p_path) const; virtual bool is_import_valid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); @@ -68,12 +75,18 @@ public: String get_internal_resource_path(const String &p_path) const; void get_internal_resource_path_list(const String &p_path, List<String> *r_paths); - void add_importer(const Ref<ResourceImporter> &p_importer) { importers.push_back(p_importer); } + void add_importer(const Ref<ResourceImporter> &p_importer) { + importers.push_back(p_importer); + importers.sort_custom<SortImporterByName>(); + } void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); } Ref<ResourceImporter> get_importer_by_name(const String &p_name) const; Ref<ResourceImporter> get_importer_by_extension(const String &p_extension) const; void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter> > *r_importers); + bool are_import_settings_valid(const String &p_path) const; + String get_import_settings_hash() const; + String get_import_base_path(const String &p_for_file) const; ResourceFormatImporter(); }; @@ -107,7 +120,9 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const = 0; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const = 0; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL) = 0; + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL) = 0; + virtual bool are_import_settings_valid(const String &p_path) const { return true; } + virtual String get_import_settings_string() const { return String(); } }; #endif // RESOURCE_IMPORTER_H diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 9780cc48ea..3ed25f118d 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -1054,7 +1054,6 @@ void ScriptDebuggerRemote::profiling_set_frame_times(float p_frame_time, float p physics_frame_time = p_physics_frame_time; } - ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func = NULL; ScriptDebuggerRemote::ScriptDebuggerRemote() : diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index c81825def4..0fd36cfb9c 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -42,8 +42,6 @@ #define glClearDepth glClearDepthf #endif -#define _DEPTH_COMPONENT24_OES 0x81A6 - static const GLenum _cube_side_enum[6] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, @@ -569,7 +567,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0); glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth); - glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size, size); // Note: used to be _DEPTH_COMPONENT24_OES. GL_DEPTH_COMPONENT untested. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth); #ifdef DEBUG_ENABLED diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index db88339249..9d2e609e5e 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -54,8 +54,6 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; #define _EXT_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#define _DEPTH_COMPONENT24_OES 0x81A6 - #define _RED_OES 0x1903 void RasterizerStorageGLES2::bind_quad_array() const { @@ -4309,11 +4307,8 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glGenTextures(1, &rt->depth); glBindTexture(GL_TEXTURE_2D, rt->depth); -#ifdef JAVASCRIPT_ENABLED glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); -#else - glTexImage2D(GL_TEXTURE_2D, 0, _DEPTH_COMPONENT24_OES, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); -#endif + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -4536,15 +4531,17 @@ RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) { glGenFramebuffers(1, &cls->fbo); glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); - glGenRenderbuffers(1, &cls->depth); - glBindRenderbuffer(GL_RENDERBUFFER, cls->depth); -#ifdef JAVASCRIPT_ENABLED - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height); -#else - glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, cls->size, cls->height); -#endif - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, cls->depth); - glBindRenderbuffer(GL_RENDERBUFFER, 0); + glGenTextures(1, &cls->depth); + glBindTexture(GL_TEXTURE_2D, cls->depth); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, cls->size, cls->height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, cls->depth, 0); glGenTextures(1, &cls->distance); glBindTexture(GL_TEXTURE_2D, cls->distance); @@ -4909,7 +4906,7 @@ bool RasterizerStorageGLES2::free(RID p_rid) { CanvasLightShadow *cls = canvas_light_shadow_owner.get(p_rid); glDeleteFramebuffers(1, &cls->fbo); - glDeleteRenderbuffers(1, &cls->depth); + glDeleteTextures(1, &cls->depth); glDeleteTextures(1, &cls->distance); canvas_light_shadow_owner.free(p_rid); memdelete(cls); diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index c292897ad0..b13801946f 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -349,7 +349,7 @@ void main() { vec2 uv = uv_interp; #ifdef USE_FORCE_REPEAT //needs to use this to workaround GLES2/WebGL1 forcing tiling that textures that dont support it - uv = mod(uv,vec2(1.0,1.0)); + uv = mod(uv, vec2(1.0, 1.0)); #endif #if !defined(COLOR_USED) diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl index c32aabc4bf..a6902836ed 100644 --- a/drivers/gles2/shaders/cubemap_filter.glsl +++ b/drivers/gles2/shaders/cubemap_filter.glsl @@ -194,7 +194,7 @@ void main() { gl_FragColor = vec4(texturePanorama(source_panorama, N).rgb, 1.0); #else - gl_FragColor = vec4(textureCube(source_cube,N).rgb, 1.0); + gl_FragColor = vec4(textureCube(source_cube, N).rgb, 1.0); #endif //USE_SOURCE_PANORAMA #else diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index fa359125b2..371ea8498a 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -660,7 +660,6 @@ VERTEX_SHADER_CODE #if defined(RENDER_DEPTH) && defined(USE_RGBA_SHADOWS) position_interp = gl_Position; #endif - } /* clang-format off */ @@ -1358,12 +1357,9 @@ LIGHT_SHADER_CODE #endif - #define SAMPLE_SHADOW_TEXEL(p_shadow, p_pos, p_depth) step(p_depth, SHADOW_DEPTH(texture2D(p_shadow, p_pos))) #define SAMPLE_SHADOW_TEXEL_PROJ(p_shadow, p_pos) step(p_pos.z, SHADOW_DEPTH(texture2DProj(p_shadow, p_pos))) - - float sample_shadow(highp sampler2D shadow, highp vec4 spos) { #ifdef SHADOW_MODE_PCF_13 diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 4cf9054bf6..e645e39f3f 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -5053,7 +5053,7 @@ void RasterizerSceneGLES3::initialize() { state.scene_shader.add_custom_define("#define MAX_LIGHT_DATA_STRUCTS " + itos(state.max_ubo_lights) + "\n"); state.scene_shader.add_custom_define("#define MAX_FORWARD_LIGHTS " + itos(state.max_forward_lights_per_object) + "\n"); - state.max_ubo_reflections = MIN(RenderList::MAX_REFLECTIONS, max_ubo_size / sizeof(ReflectionProbeDataUBO)); + state.max_ubo_reflections = MIN((int)RenderList::MAX_REFLECTIONS, max_ubo_size / sizeof(ReflectionProbeDataUBO)); state.reflection_array_tmp = (uint8_t *)memalloc(sizeof(ReflectionProbeDataUBO) * state.max_ubo_reflections); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 39e6df4450..2b9007de04 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -1160,6 +1160,17 @@ void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, in export_presets.insert(p_at_pos, p_preset); } +String EditorExportPlatform::test_etc2() const { + + String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); + bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc"); + + if (driver == "GLES2" && !etc2_supported) { + return TTR("Target platform requires 'ETC' texture compression for GLES2. Enable support in Project Settings."); + } + return String(); +} + int EditorExport::get_export_preset_count() const { return export_presets.size(); diff --git a/editor/editor_export.h b/editor/editor_export.h index c7c2b76327..bd864c528c 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -258,6 +258,7 @@ public: virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { return OK; } virtual Ref<Texture> get_run_icon() const { return get_logo(); } + String test_etc2() const; //generic test for etc2 since most platforms use it virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0; virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const = 0; diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index ea36410cc3..a662c50c04 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -42,6 +42,8 @@ #include "editor_settings.h" EditorFileSystem *EditorFileSystem::singleton = NULL; +//the name is the version, to keep compatibility with different versions of Godot +#define CACHE_FILE_NAME "filesystem_cache5" void EditorFileSystemDirectory::sort_files() { @@ -203,14 +205,30 @@ void EditorFileSystem::_scan_filesystem() { String project = ProjectSettings::get_singleton()->get_resource_path(); - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache4"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME); FileAccess *f = FileAccess::open(fscache, FileAccess::READ); + bool first = true; if (f) { //read the disk cache while (!f->eof_reached()) { String l = f->get_line().strip_edges(); + if (first) { + if (first_scan) { + // only use this on first scan, afterwards it gets ignored + // this is so on first reimport we synchronize versions, then + // we dont care until editor restart. This is for usability mainly so + // your workflow is not killed after changing a setting by forceful reimporting + // everything there is. + filesystem_settings_version_for_import = l.strip_edges(); + if (filesystem_settings_version_for_import != ResourceFormatImporter::get_singleton()->get_import_settings_hash()) { + revalidate_import_files = true; + } + } + first = false; + continue; + } if (l == String()) continue; @@ -291,25 +309,22 @@ void EditorFileSystem::_scan_filesystem() { memdelete(d); - f = FileAccess::open(fscache, FileAccess::WRITE); - if (f == NULL) { - ERR_PRINTS("Error writing fscache: " + fscache); - } else { - _save_filesystem_cache(new_filesystem, f); - f->close(); - memdelete(f); + if (!first_scan) { + //on the first scan this is done from the main thread after re-importing + _save_filesystem_cache(); } scanning = false; } void EditorFileSystem::_save_filesystem_cache() { - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache4"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME); FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE); if (f == NULL) { ERR_PRINTS("Error writing fscache: " + fscache); } else { + f->store_line(filesystem_settings_version_for_import); _save_filesystem_cache(filesystem, f); f->close(); memdelete(f); @@ -334,6 +349,11 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo return true; } + if (!ResourceFormatImporter::get_singleton()->are_import_settings_valid(p_path)) { + //reimport settings are not valid, reimport + return true; + } + VariantParser::StreamFile stream; stream.f = f; @@ -562,6 +582,13 @@ bool EditorFileSystem::_update_scan_actions() { reimport_files(reimports); } + if (first_scan) { + //only on first scan this is valid and updated, then settings changed. + revalidate_import_files = false; + filesystem_settings_version_for_import = ResourceFormatImporter::get_singleton()->get_import_settings_hash(); + _save_filesystem_cache(); + } + if (reloads.size()) { emit_signal("resources_reload", reloads); } @@ -595,7 +622,7 @@ void EditorFileSystem::scan() { emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); _queue_update_script_classes(); - + first_scan = false; } else { ERR_FAIL_COND(thread); @@ -737,11 +764,20 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess fi->deps = fc->deps; fi->modified_time = fc->modification_time; fi->import_modified_time = fc->import_modification_time; + fi->import_valid = fc->import_valid; fi->script_class_name = fc->script_class_name; fi->script_class_extends = fc->script_class_extends; fi->script_class_icon_path = fc->script_class_icon_path; + if (revalidate_import_files && !ResourceFormatImporter::get_singleton()->are_import_settings_valid(path)) { + ItemAction ia; + ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT; + ia.dir = p_dir; + ia.file = E->get(); + scan_actions.push_back(ia); + } + if (fc->type == String()) { fi->type = ResourceLoader::get_resource_type(path); //there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?) @@ -1101,6 +1137,7 @@ void EditorFileSystem::_notification(int p_what) { emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); _queue_update_script_classes(); + first_scan = false; } } else if (!scanning) { @@ -1117,6 +1154,7 @@ void EditorFileSystem::_notification(int p_what) { emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); _queue_update_script_classes(); + first_scan = false; } } } break; @@ -1569,8 +1607,8 @@ void EditorFileSystem::_reimport_file(const String &p_file) { List<String> import_variants; List<String> gen_files; - - Error err = importer->import(p_file, base_path, params, &import_variants, &gen_files); + Variant metadata; + Error err = importer->import(p_file, base_path, params, &import_variants, &gen_files, &metadata); if (err != OK) { ERR_PRINTS("Error importing: " + p_file); @@ -1615,6 +1653,10 @@ void EditorFileSystem::_reimport_file(const String &p_file) { f->store_line("valid=false"); } + if (metadata != Variant()) { + f->store_line("metadata=" + metadata.get_construct_string()); + } + f->store_line(""); f->store_line("[deps]\n"); @@ -1815,6 +1857,8 @@ EditorFileSystem::EditorFileSystem() { scan_total = 0; update_script_classes_queued = false; + first_scan = true; + revalidate_import_files = false; } EditorFileSystem::~EditorFileSystem() { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index bb892baf57..2a9e325454 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -143,7 +143,10 @@ class EditorFileSystem : public Node { bool abort_scan; bool scanning; bool importing; + bool first_scan; float scan_total; + String filesystem_settings_version_for_import; + bool revalidate_import_files; void _scan_filesystem(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e23afec5b8..dcab17041f 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1017,6 +1017,35 @@ bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_nod return false; } +static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Resource> > &edited_resources) { + + if (p_resource->is_edited()) { + edited_resources.insert(p_resource); + return true; + } + + List<PropertyInfo> plist; + + p_resource->get_property_list(&plist); + + for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { + if (E->get().type == Variant::OBJECT && E->get().usage & PROPERTY_USAGE_STORAGE && !(E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)) { + RES res = p_resource->get(E->get().name); + if (res.is_null()) { + continue; + } + if (res->get_path().is_resource_file()) { //not a subresource, continue + continue; + } + if (_find_edited_resources(res, edited_resources)) { + return true; + } + } + } + + return false; +} + void EditorNode::_save_scene(String p_file, int idx) { Node *scene = editor_data.get_edited_scene_root(idx); @@ -1080,16 +1109,28 @@ void EditorNode::_save_scene(String p_file, int idx) { //_save_edited_subresources(scene, processed, flg); { //instead, just find globally unsaved subresources and save them + Set<Ref<Resource> > edited_subresources; + List<Ref<Resource> > cached; ResourceCache::get_cached_resources(&cached); for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { Ref<Resource> res = E->get(); - if (res->is_edited() && res->get_path().is_resource_file()) { + if (!res->get_path().is_resource_file()) + continue; + //not only check if this resourec is edited, check contained subresources too + if (_find_edited_resources(res, edited_subresources)) { ResourceSaver::save(res->get_path(), res, flg); - res->set_edited(false); } } + + // clear later, because user may have put the same subresource in two different resources, + // which will be shared until the next reload + + for (Set<Ref<Resource> >::Element *E = edited_subresources.front(); E; E = E->next()) { + Ref<Resource> res = E->get(); + res->set_edited(false); + } } editor_data.save_editor_external_data(); diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 0851485208..0f6c6349ed 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -418,13 +418,14 @@ void EditorPropertyArray::_length_changed(double p_page) { return; Variant array = object->get_array(); + int previous_size = array.call("size"); + array.call("resize", int(p_page)); - emit_changed(get_edited_property(), array, "", false); if (array.get_type() == Variant::ARRAY) { if (subtype != Variant::NIL) { int size = array.call("size"); - for (int i = 0; i < size; i++) { + for (int i = previous_size; i < size; i++) { if (array.get(i).get_type() == Variant::NIL) { Variant::CallError ce; array.set(i, Variant::construct(subtype, NULL, 0, ce)); @@ -432,7 +433,16 @@ void EditorPropertyArray::_length_changed(double p_page) { } } array = array.call("duplicate"); //dupe, so undo/redo works better + } else { + int size = array.call("size"); + // Pool*Array don't initialize their elements, have to do it manually + for (int i = previous_size; i < size; i++) { + Variant::CallError ce; + array.set(i, Variant::construct(array.get(i).get_type(), NULL, 0, ce)); + } } + + emit_changed(get_edited_property(), array, "", false); object->set_array(array); update_property(); } diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 887a102aa4..06cadca1c0 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -32,6 +32,7 @@ #include "editor_export.h" #include "editor_node.h" +#include "editor_scale.h" void EditorRunNative::_notification(int p_what) { @@ -49,7 +50,7 @@ void EditorRunNative::_notification(int p_what) { im->clear_mipmaps(); if (!im->empty()) { - im->resize(16, 16); + im->resize(16 * EDSCALE, 16 * EDSCALE); Ref<ImageTexture> small_icon; small_icon.instance(); small_icon->create_from_image(im, 0); diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp index e365471733..98f4947c2d 100644 --- a/editor/import/editor_import_plugin.cpp +++ b/editor/import/editor_import_plugin.cpp @@ -130,7 +130,7 @@ bool EditorImportPlugin::get_option_visibility(const String &p_option, const Map return get_script_instance()->call("get_option_visibility", p_option, d); } -Error EditorImportPlugin::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error EditorImportPlugin::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("import")), ERR_UNAVAILABLE); Dictionary options; diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h index 607d99e6e2..d396dd6d5b 100644 --- a/editor/import/editor_import_plugin.h +++ b/editor/import/editor_import_plugin.h @@ -51,7 +51,7 @@ public: virtual int get_import_order() const; virtual void get_import_options(List<ImportOption> *r_options, int p_preset) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata = NULL); }; #endif //EDITOR_IMPORT_PLUGIN_H diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp index b568cbda9b..18e53fc783 100644 --- a/editor/import/resource_importer_bitmask.cpp +++ b/editor/import/resource_importer_bitmask.cpp @@ -78,7 +78,7 @@ void ResourceImporterBitMap::get_import_options(List<ImportOption> *r_options, i r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.5)); } -Error ResourceImporterBitMap::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterBitMap::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { int create_from = p_options["create_from"]; float threshold = p_options["threshold"]; diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h index 7cfb0c4a98..166fa998e4 100644 --- a/editor/import/resource_importer_bitmask.h +++ b/editor/import/resource_importer_bitmask.h @@ -51,7 +51,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterBitMap(); ~ResourceImporterBitMap(); diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index be5ce34c25..b4b3e0e551 100644 --- a/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp @@ -77,7 +77,7 @@ void ResourceImporterCSVTranslation::get_import_options(List<ImportOption> *r_op r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "delimiter", PROPERTY_HINT_ENUM, "Comma,Semicolon,Tab"), 0)); } -Error ResourceImporterCSVTranslation::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterCSVTranslation::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { bool compress = p_options["compress"]; diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h index cf16826535..6785b68d87 100644 --- a/editor/import/resource_importer_csv_translation.h +++ b/editor/import/resource_importer_csv_translation.h @@ -48,7 +48,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterCSVTranslation(); }; diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp index c3421466f2..1259e81be7 100644 --- a/editor/import/resource_importer_image.cpp +++ b/editor/import/resource_importer_image.cpp @@ -74,7 +74,7 @@ String ResourceImporterImage::get_preset_name(int p_idx) const { void ResourceImporterImage::get_import_options(List<ImportOption> *r_options, int p_preset) const { } -Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ); if (!f) { diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h index ffe05bdf58..3d5b99db2c 100644 --- a/editor/import/resource_importer_image.h +++ b/editor/import/resource_importer_image.h @@ -49,7 +49,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterImage(); }; diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index e38265b619..7e3c4cecf4 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -191,7 +191,7 @@ void ResourceImporterLayeredTexture::_save_tex(const Vector<Ref<Image> > &p_imag memdelete(f); } -Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { int compress_mode = p_options["compress/mode"]; int no_bptc_if_rgb = p_options["compress/no_bptc_if_rgb"]; @@ -252,6 +252,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const } String extension = get_save_extension(); + Array formats_imported; if (compress_mode == COMPRESS_VIDEO_RAM) { //must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc). @@ -270,6 +271,8 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const encode_bptc = false; } } + + formats_imported.push_back("bptc"); } if (encode_bptc) { @@ -284,23 +287,27 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const _save_tex(slices, p_save_path + ".s3tc." + extension, compress_mode, Image::COMPRESS_S3TC, mipmaps, tex_flags); r_platform_variants->push_back("s3tc"); ok_on_pc = true; + formats_imported.push_back("s3tc"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, Image::COMPRESS_ETC2, mipmaps, tex_flags); r_platform_variants->push_back("etc2"); + formats_imported.push_back("etc2"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) { _save_tex(slices, p_save_path + ".etc." + extension, compress_mode, Image::COMPRESS_ETC, mipmaps, tex_flags); r_platform_variants->push_back("etc"); + formats_imported.push_back("etc"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { _save_tex(slices, p_save_path + ".pvrtc." + extension, compress_mode, Image::COMPRESS_PVRTC4, mipmaps, tex_flags); r_platform_variants->push_back("pvrtc"); + formats_imported.push_back("pvrtc"); } if (!ok_on_pc) { @@ -311,9 +318,79 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const _save_tex(slices, p_save_path + "." + extension, compress_mode, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags); } + if (r_metadata) { + Dictionary metadata; + metadata["vram_texture"] = compress_mode == COMPRESS_VIDEO_RAM; + if (formats_imported.size()) { + metadata["imported_formats"] = formats_imported; + } + *r_metadata = metadata; + } + return OK; } +const char *ResourceImporterLayeredTexture::compression_formats[] = { + "bptc", + "s3tc", + "etc", + "etc2", + "pvrtc", + NULL +}; +String ResourceImporterLayeredTexture::get_import_settings_string() const { + + String s; + + int index = 0; + while (compression_formats[index]) { + String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + bool test = ProjectSettings::get_singleton()->get(setting_path); + if (test) { + s += String(compression_formats[index]); + } + index++; + } + + return s; +} + +bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_path) const { + + //will become invalid if formats are missing to import + Dictionary metadata = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path); + + if (!metadata.has("vram_texture")) { + return false; + } + + bool vram = metadata["vram_texture"]; + if (!vram) { + return true; //do not care about non vram + } + + Vector<String> formats_imported; + if (metadata.has("imported_formats")) { + formats_imported = metadata["imported_formats"]; + } + + int index = 0; + bool valid = true; + while (compression_formats[index]) { + String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + bool test = ProjectSettings::get_singleton()->get(setting_path); + if (test) { + if (formats_imported.find(compression_formats[index]) == -1) { + valid = false; + break; + } + } + index++; + } + + return valid; +} + ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = NULL; ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() { diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index 6a616e09d6..6b393886b7 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -40,6 +40,7 @@ class ResourceImporterLayeredTexture : public ResourceImporter { GDCLASS(ResourceImporterLayeredTexture, ResourceImporter) bool is_3d; + static const char *compression_formats[]; protected: static void _texture_reimport_srgb(const Ref<StreamTexture> &p_tex); @@ -76,10 +77,13 @@ public: void _save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags); - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); void update_imports(); + virtual bool are_import_settings_valid(const String &p_path) const; + virtual String get_import_settings_string() const; + void set_3d(bool p_3d) { is_3d = p_3d; } ResourceImporterLayeredTexture(); ~ResourceImporterLayeredTexture(); diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 030b54a589..e950421476 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -499,7 +499,7 @@ bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Ma return true; } -Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { List<Ref<Mesh> > meshes; diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h index effc56ad95..b2a53f582c 100644 --- a/editor/import/resource_importer_obj.h +++ b/editor/import/resource_importer_obj.h @@ -61,7 +61,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterOBJ(); }; diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index ad436b2797..76552575da 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1183,7 +1183,7 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito return importer->import_animation(p_path, p_flags, p_bake_fps); } -Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { String src_path = p_source_file; diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 9d06b411d6..99f8b1a8e0 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -153,7 +153,7 @@ public: void _filter_tracks(Node *scene, const String &p_text); void _optimize_animations(Node *scene, float p_max_lin_error, float p_max_ang_error, float p_max_angle); - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); Node *import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps); Ref<Animation> import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps); diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 3e03b697ed..631b2359c5 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -375,7 +375,7 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String memdelete(f); } -Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { int compress_mode = p_options["compress/mode"]; float lossy = p_options["compress/lossy_quality"]; @@ -401,6 +401,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String if (err != OK) return err; + Array formats_imported; + int tex_flags = 0; if (repeat > 0) tex_flags |= Texture::FLAG_REPEAT; @@ -485,6 +487,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String can_bptc = false; } } + + formats_imported.push_back("bptc"); } if (!can_bptc && is_hdr && !force_rgbe) { @@ -495,6 +499,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String if (can_bptc || can_s3tc) { _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, false); r_platform_variants->push_back("s3tc"); + formats_imported.push_back("s3tc"); ok_on_pc = true; } @@ -502,17 +507,20 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, false); r_platform_variants->push_back("etc2"); + formats_imported.push_back("etc2"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) { _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, true); r_platform_variants->push_back("etc"); + formats_imported.push_back("etc"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, true); r_platform_variants->push_back("pvrtc"); + formats_imported.push_back("pvrtc"); } if (!ok_on_pc) { @@ -523,9 +531,78 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, false); } + if (r_metadata) { + Dictionary metadata; + metadata["vram_texture"] = compress_mode == COMPRESS_VIDEO_RAM; + if (formats_imported.size()) { + metadata["imported_formats"] = formats_imported; + } + *r_metadata = metadata; + } return OK; } +const char *ResourceImporterTexture::compression_formats[] = { + "bptc", + "s3tc", + "etc", + "etc2", + "pvrtc", + NULL +}; +String ResourceImporterTexture::get_import_settings_string() const { + + String s; + + int index = 0; + while (compression_formats[index]) { + String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + bool test = ProjectSettings::get_singleton()->get(setting_path); + if (test) { + s += String(compression_formats[index]); + } + index++; + } + + return s; +} + +bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) const { + + //will become invalid if formats are missing to import + Dictionary metadata = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path); + + if (!metadata.has("vram_texture")) { + return false; + } + + bool vram = metadata["vram_texture"]; + if (!vram) { + return true; //do not care about non vram + } + + Vector<String> formats_imported; + if (metadata.has("imported_formats")) { + formats_imported = metadata["imported_formats"]; + } + + int index = 0; + bool valid = true; + while (compression_formats[index]) { + String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + bool test = ProjectSettings::get_singleton()->get(setting_path); + if (test) { + if (formats_imported.find(compression_formats[index]) == -1) { + valid = false; + break; + } + } + index++; + } + + return valid; +} + ResourceImporterTexture *ResourceImporterTexture::singleton = NULL; ResourceImporterTexture::ResourceImporterTexture() { diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 49a8b52b04..ef74e4e41e 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -54,6 +54,7 @@ protected: static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex); static ResourceImporterTexture *singleton; + static const char *compression_formats[]; public: static ResourceImporterTexture *get_singleton() { return singleton; } @@ -85,10 +86,13 @@ public: void _save_stex(const Ref<Image> &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal, bool p_force_po2_for_compressed); - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); void update_imports(); + virtual bool are_import_settings_valid(const String &p_path) const; + virtual String get_import_settings_string() const; + ResourceImporterTexture(); ~ResourceImporterTexture(); }; diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index 76ab7a7037..857d8992fd 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -82,7 +82,7 @@ void ResourceImporterWAV::get_import_options(List<ImportOption> *r_options, int r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Disabled,RAM (Ima-ADPCM)"), 0)); } -Error ResourceImporterWAV::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterWAV::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { /* STEP 1, READ WAVE FILE */ diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h index 755dea3d84..f993f9e7bc 100644 --- a/editor/import/resource_importer_wav.h +++ b/editor/import/resource_importer_wav.h @@ -161,7 +161,7 @@ public: } } - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterWAV(); }; diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 3cf46e5b91..58d7968723 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -92,7 +92,12 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 if (!tex.is_valid()) { return Ref<Texture>(); } + Ref<Image> atlas = tex->get_data(); + if (!atlas.is_valid()) { + return Ref<Texture>(); + } + img = atlas->get_rect(atex->get_region()); } else if (ltex.is_valid()) { img = ltex->to_image(); diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 9fd0a2e8ec..c2b772df85 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -1599,18 +1599,20 @@ bool NativeScriptLanguage::handles_global_class_type(const String &p_type) const } String NativeScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const { - Ref<NativeScript> script = ResourceLoader::load(p_path, "NativeScript"); - if (script.is_valid()) { + if (!p_path.empty()) { + Ref<NativeScript> script = ResourceLoader::load(p_path, "NativeScript"); + if (script.is_valid()) { + if (r_base_type) + *r_base_type = script->get_instance_base_type(); + if (r_icon_path) + *r_icon_path = script->get_script_class_icon_path(); + return script->get_script_class_name(); + } if (r_base_type) - *r_base_type = script->get_instance_base_type(); + *r_base_type = String(); if (r_icon_path) - *r_icon_path = script->get_script_class_icon_path(); - return script->get_script_class_name(); + *r_icon_path = String(); } - if (r_base_type) - *r_base_type = String(); - if (r_icon_path) - *r_icon_path = String(); return String(); } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index adbd7e4e04..5ebf68177d 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -4691,6 +4691,16 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { ConstantNode *cn = static_cast<ConstantNode *>(subexpr); if (cn->value.get_type() != Variant::NIL) { + if (member._export.type != Variant::NIL && cn->value.get_type() != member._export.type) { + if (Variant::can_convert(cn->value.get_type(), member._export.type)) { + Variant::CallError err; + const Variant *args = &cn->value; + cn->value = Variant::construct(member._export.type, &args, 1, err); + } else { + _set_error("Cannot convert the provided value to the export type."); + return; + } + } member.default_value = cn->value; } } diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp index 17e29fba19..5b68810017 100644 --- a/modules/mono/editor/godotsharp_editor.cpp +++ b/modules/mono/editor/godotsharp_editor.cpp @@ -167,9 +167,6 @@ void GodotSharpEditor::_remove_create_sln_menu_option() { menu_popup->remove_item(menu_popup->get_item_index(MENU_CREATE_SLN)); - if (menu_popup->get_item_count() == 0) - menu_button->hide(); - bottom_panel_btn->show(); } @@ -277,43 +274,23 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int // TODO: Use initializer lists once C++11 is allowed - // Try with hint paths - static Vector<String> hint_paths; -#ifdef WINDOWS_ENABLED - if (hint_paths.empty()) { - hint_paths.push_back(OS::get_singleton()->get_environment("ProgramFiles") + "\\Microsoft VS Code\\Code.exe"); - if (sizeof(size_t) == 8) { - hint_paths.push_back(OS::get_singleton()->get_environment("ProgramFiles(x86)") + "\\Microsoft VS Code\\Code.exe"); - } + static Vector<String> vscode_names; + if (vscode_names.empty()) { + vscode_names.push_back("code"); + vscode_names.push_back("code-oss"); + vscode_names.push_back("vscode"); + vscode_names.push_back("vscode-oss"); + vscode_names.push_back("visual-studio-code"); + vscode_names.push_back("visual-studio-code-oss"); } -#endif - for (int i = 0; i < hint_paths.size(); i++) { - vscode_path = hint_paths[i]; - if (FileAccess::exists(vscode_path)) { + for (int i = 0; i < vscode_names.size(); i++) { + vscode_path = path_which(vscode_names[i]); + if (!vscode_path.empty()) { found = true; break; } } - if (!found) { - static Vector<String> vscode_names; - if (vscode_names.empty()) { - vscode_names.push_back("code"); - vscode_names.push_back("code-oss"); - vscode_names.push_back("vscode"); - vscode_names.push_back("vscode-oss"); - vscode_names.push_back("visual-studio-code"); - vscode_names.push_back("visual-studio-code-oss"); - } - for (int i = 0; i < vscode_names.size(); i++) { - vscode_path = path_which(vscode_names[i]); - if (!vscode_path.empty()) { - found = true; - break; - } - } - } - if (!found) vscode_path.clear(); // Not found, clear so next time the empty() check is enough } @@ -433,9 +410,12 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { editor->add_child(memnew(MonoReloadNode)); - menu_button = memnew(MenuButton); - menu_button->set_text(TTR("Mono")); - menu_popup = menu_button->get_popup(); + menu_popup = memnew(PopupMenu); + menu_popup->hide(); + menu_popup->set_as_toplevel(true); + menu_popup->set_pass_on_modal_close_click(false); + + editor->add_tool_submenu_item("Mono", menu_popup); // TODO: Remove or edit this info dialog once Mono support is no longer in alpha { @@ -498,10 +478,12 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { menu_popup->connect("id_pressed", this, "_menu_option_pressed"); - if (menu_popup->get_item_count() == 0) - menu_button->hide(); - - editor->get_menu_hb()->add_child(menu_button); + ToolButton *build_button = memnew(ToolButton); + build_button->set_text("Build"); + build_button->set_tooltip("Build solution"); + build_button->set_focus_mode(Control::FOCUS_NONE); + build_button->connect("pressed", MonoBottomPanel::get_singleton(), "_build_project_pressed"); + editor->get_menu_hb()->add_child(build_button); // External editor settings EditorSettings *ed_settings = EditorSettings::get_singleton(); diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp index cc9822e319..21ce9ca5c4 100644 --- a/modules/mono/editor/mono_bottom_panel.cpp +++ b/modules/mono/editor/mono_bottom_panel.cpp @@ -125,9 +125,14 @@ void MonoBottomPanel::_build_tabs_item_selected(int p_idx) { void MonoBottomPanel::_build_tabs_nothing_selected() { - if (build_tabs->get_tab_count() != 0) // just in case + if (build_tabs->get_tab_count() != 0) { // just in case build_tabs->set_visible(false); + // This callback is called when clicking on the empty space of the list. + // ItemList won't deselect the items automatically, so we must do it ourselves. + build_tabs_list->unselect_all(); + } + warnings_btn->set_visible(false); errors_btn->set_visible(false); view_log_btn->set_visible(false); diff --git a/modules/mono/editor/mono_bottom_panel.h b/modules/mono/editor/mono_bottom_panel.h index d3109592a9..406e46f7ce 100644 --- a/modules/mono/editor/mono_bottom_panel.h +++ b/modules/mono/editor/mono_bottom_panel.h @@ -51,8 +51,8 @@ class MonoBottomPanel : public VBoxContainer { ItemList *build_tabs_list; TabContainer *build_tabs; - Button *warnings_btn; - Button *errors_btn; + ToolButton *warnings_btn; + ToolButton *errors_btn; Button *view_log_btn; void _update_build_tabs_list(); diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp index 6e12bc9bf0..7254f57672 100644 --- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp @@ -76,7 +76,7 @@ void ResourceImporterOGGVorbis::get_import_options(List<ImportOption> *r_options r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "loop_offset"), 0)); } -Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { bool loop = p_options["loop"]; float loop_offset = p_options["loop_offset"]; diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.h b/modules/stb_vorbis/resource_importer_ogg_vorbis.h index f61fc91cda..d3d0574d56 100644 --- a/modules/stb_vorbis/resource_importer_ogg_vorbis.h +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.h @@ -49,7 +49,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterOGGVorbis(); }; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 9d9270bdac..8d9d9c697e 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1453,6 +1453,12 @@ public: err += TTR("Invalid package name:") + " " + pn_err + "\n"; } + String etc_error = test_etc2(); + if (etc_error != String()) { + valid = false; + err += etc_error; + } + r_error = err; return valid; } diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index d234ddac27..09ded63e96 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -1150,6 +1150,12 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset } } + String etc_error = test_etc2(); + if (etc_error != String()) { + valid = false; + err += etc_error; + } + if (!err.empty()) r_error = err; diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 123c6ae645..2da6ea6670 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -167,6 +167,12 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p } } + String etc_error = test_etc2(); + if (etc_error != String()) { + valid = false; + err += etc_error; + } + if (!err.empty()) r_error = err; diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 44899bf9fc..210fbe9f20 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1389,7 +1389,7 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) { if (res->get_path() == local_path) { - ERR_PRINTS("Circular reference to resource being saved found: '"+local_path+"' will be null next time it's loaded."); + ERR_PRINTS("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded."); return; } int index = external_resources.size(); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 430db59e44..08b2a05d43 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -426,6 +426,8 @@ ImageTexture::ImageTexture() { texture = VisualServer::get_singleton()->texture_create(); storage = STORAGE_RAW; lossy_storage_quality = 0.7; + image_stored = false; + format = Image::FORMAT_L8; } ImageTexture::~ImageTexture() { @@ -1514,6 +1516,7 @@ CubeMap::CubeMap() { cubemap = VisualServer::get_singleton()->texture_create(); storage = STORAGE_RAW; lossy_storage_quality = 0.7; + format = Image::FORMAT_BPTC_RGBA; } CubeMap::~CubeMap() { diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 9a0218d5d0..1f9d263354 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -2074,7 +2074,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p bool fail = false; for (int i = 0; i < argcount; i++) { - if (args[i] != builtin_func_defs[idx].args[i]) { + if (get_scalar_type(args[i]) == args[i] && p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[i + 1]), builtin_func_defs[idx].args[i])) { + //all good, but needs implicit conversion later + } else if (args[i] != builtin_func_defs[idx].args[i]) { fail = true; break; } @@ -2119,6 +2121,24 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p outarg_idx++; } + //implicitly convert values if possible + for (int i = 0; i < argcount; i++) { + + if (get_scalar_type(args[i]) != args[i] || args[i] == builtin_func_defs[idx].args[i] || p_func->arguments[i + 1]->type != Node::TYPE_CONSTANT) { + //can't do implicit conversion here + continue; + } + + //this is an implicit conversion + ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[i + 1]); + ConstantNode *conversion = alloc_node<ConstantNode>(); + + conversion->datatype = builtin_func_defs[idx].args[i]; + conversion->values.resize(1); + + convert_constant(constant, builtin_func_defs[idx].args[i], conversion->values.ptrw()); + p_func->arguments.write[i + 1] = conversion; + } if (r_ret_type) *r_ret_type = builtin_func_defs[idx].rettype; @@ -2184,13 +2204,35 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p for (int j = 0; j < args.size(); j++) { - if (args[j] != pfunc->arguments[j].type) { + if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) { + //all good, but it needs implicit conversion later + } else if (args[j] != pfunc->arguments[j].type) { fail = true; break; } } if (!fail) { + + //implicitly convert values if possible + for (int k = 0; k < args.size(); k++) { + + if (get_scalar_type(args[k]) != args[k] || args[k] == pfunc->arguments[k].type || p_func->arguments[k + 1]->type != Node::TYPE_CONSTANT) { + //can't do implicit conversion here + continue; + } + + //this is an implicit conversion + ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[k + 1]); + ConstantNode *conversion = alloc_node<ConstantNode>(); + + conversion->datatype = pfunc->arguments[k].type; + conversion->values.resize(1); + + convert_constant(constant, pfunc->arguments[k].type, conversion->values.ptrw()); + p_func->arguments.write[k + 1] = conversion; + } + if (r_ret_type) *r_ret_type = pfunc->return_type; return true; diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index c61e2b99e2..3dbe516f74 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -2368,11 +2368,11 @@ VisualServer::VisualServer() { //ERR_FAIL_COND(singleton); singleton = this; - GLOBAL_DEF("rendering/vram_compression/import_bptc", false); - GLOBAL_DEF("rendering/vram_compression/import_s3tc", true); - GLOBAL_DEF("rendering/vram_compression/import_etc", false); - GLOBAL_DEF("rendering/vram_compression/import_etc2", true); - GLOBAL_DEF("rendering/vram_compression/import_pvrtc", false); + GLOBAL_DEF_RST("rendering/vram_compression/import_bptc", false); + GLOBAL_DEF_RST("rendering/vram_compression/import_s3tc", true); + GLOBAL_DEF_RST("rendering/vram_compression/import_etc", false); + GLOBAL_DEF_RST("rendering/vram_compression/import_etc2", true); + GLOBAL_DEF_RST("rendering/vram_compression/import_pvrtc", false); GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096); GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048); |