From b19225bfce3dab39f8ce6b1ecf610ea0ba650f99 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Fri, 16 Jun 2017 21:47:28 -0300 Subject: [PATCH] -Fix freezes caused by etccomp2, closes #9183 -Normalmaps are now detected and imported as RGTC, both in S3TC and ETC2, this improves their quality. --- core/global_config.cpp | 8 +-- core/image.cpp | 16 +++-- core/image.h | 15 +++-- core/io/compression.cpp | 4 +- drivers/gles3/rasterizer_scene_gles3.cpp | 8 +++ drivers/gles3/rasterizer_storage_gles3.cpp | 8 +++ drivers/gles3/rasterizer_storage_gles3.h | 6 ++ editor/import/resource_importer_texture.cpp | 71 ++++++++++++++++++--- editor/import/resource_importer_texture.h | 6 +- modules/etc/image_etc.cpp | 32 ++++++++-- modules/squish/image_compress_squish.cpp | 9 ++- modules/squish/image_compress_squish.h | 2 +- scene/gui/color_picker.cpp | 6 +- scene/main/viewport.cpp | 12 ---- scene/main/viewport.h | 3 - scene/resources/texture.cpp | 20 +++++- scene/resources/texture.h | 3 + servers/visual/rasterizer.h | 1 + servers/visual/visual_server_raster.h | 1 + servers/visual/visual_server_wrap_mt.h | 1 + servers/visual_server.cpp | 4 ++ servers/visual_server.h | 1 + 22 files changed, 180 insertions(+), 57 deletions(-) diff --git a/core/global_config.cpp b/core/global_config.cpp index 0729d4c4821..ba0a7f3e31e 100644 --- a/core/global_config.cpp +++ b/core/global_config.cpp @@ -970,10 +970,10 @@ GlobalConfig::GlobalConfig() { GLOBAL_DEF("debug/profiler/max_functions", 16384); - GLOBAL_DEF("compression/zstd_compression_level", 3); - custom_prop_info["compression/zstd_compression_level"] = PropertyInfo(Variant::INT, "compression/zstd_compression_level", PROPERTY_HINT_RANGE, "1,22,1"); - GLOBAL_DEF("compression/zlib_compression_level", Z_DEFAULT_COMPRESSION); - custom_prop_info["compression/zlib_compression_level"] = PropertyInfo(Variant::INT, "compression/zlib_compression_level", PROPERTY_HINT_RANGE, "-1,9,1"); + GLOBAL_DEF("compression/zstd/compression_level", 3); + custom_prop_info["compression/zstd/compression_level"] = PropertyInfo(Variant::INT, "compression/zstd/compression_level", PROPERTY_HINT_RANGE, "1,22,1"); + GLOBAL_DEF("compression/zlib/compression_level", Z_DEFAULT_COMPRESSION); + custom_prop_info["compression/zlib/compression_level"] = PropertyInfo(Variant::INT, "compression/zlib/compression_level", PROPERTY_HINT_RANGE, "-1,9,1"); using_datapack = false; } diff --git a/core/image.cpp b/core/image.cpp index 380b307020b..72d0d3e5547 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -1492,14 +1492,14 @@ Error Image::decompress() { return OK; } -Error Image::compress(CompressMode p_mode, bool p_for_srgb, float p_lossy_quality) { +Error Image::compress(CompressMode p_mode, CompressSource p_source, float p_lossy_quality) { switch (p_mode) { case COMPRESS_S3TC: { ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE); - _image_compress_bc_func(this, p_for_srgb); + _image_compress_bc_func(this, p_source); } break; case COMPRESS_PVRTC2: { @@ -1519,7 +1519,7 @@ Error Image::compress(CompressMode p_mode, bool p_for_srgb, float p_lossy_qualit case COMPRESS_ETC2: { ERR_FAIL_COND_V(!_image_compress_etc2_func, ERR_UNAVAILABLE); - _image_compress_etc2_func(this, p_lossy_quality); + _image_compress_etc2_func(this, p_lossy_quality, p_source); } break; } @@ -1649,11 +1649,11 @@ void Image::blit_rect(const Ref &p_src, const Rect2 &p_src_rect, const Po Ref (*Image::_png_mem_loader_func)(const uint8_t *, int) = NULL; Ref (*Image::_jpg_mem_loader_func)(const uint8_t *, int) = NULL; -void (*Image::_image_compress_bc_func)(Image *, bool) = NULL; +void (*Image::_image_compress_bc_func)(Image *, Image::CompressSource) = NULL; void (*Image::_image_compress_pvrtc2_func)(Image *) = NULL; void (*Image::_image_compress_pvrtc4_func)(Image *) = NULL; void (*Image::_image_compress_etc1_func)(Image *, float) = NULL; -void (*Image::_image_compress_etc2_func)(Image *, float) = NULL; +void (*Image::_image_compress_etc2_func)(Image *, float, Image::CompressSource) = NULL; void (*Image::_image_decompress_pvrtc)(Image *) = NULL; void (*Image::_image_decompress_bc)(Image *) = NULL; void (*Image::_image_decompress_etc1)(Image *) = NULL; @@ -2140,9 +2140,13 @@ void Image::_bind_methods() { BIND_CONSTANT(COMPRESS_PVRTC4); BIND_CONSTANT(COMPRESS_ETC); BIND_CONSTANT(COMPRESS_ETC2); + + BIND_CONSTANT(COMPRESS_SOURCE_GENERIC); + BIND_CONSTANT(COMPRESS_SOURCE_SRGB); + BIND_CONSTANT(COMPRESS_SOURCE_NORMAL); } -void Image::set_compress_bc_func(void (*p_compress_func)(Image *, bool)) { +void Image::set_compress_bc_func(void (*p_compress_func)(Image *, CompressSource)) { _image_compress_bc_func = p_compress_func; } diff --git a/core/image.h b/core/image.h index 790c5de9f6a..1bb81c939f3 100644 --- a/core/image.h +++ b/core/image.h @@ -109,16 +109,22 @@ public: /* INTERPOLATE GAUSS */ }; + enum CompressSource { + COMPRESS_SOURCE_GENERIC, + COMPRESS_SOURCE_SRGB, + COMPRESS_SOURCE_NORMAL + }; + //some functions provided by something else static Ref (*_png_mem_loader_func)(const uint8_t *p_png, int p_size); static Ref (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size); - static void (*_image_compress_bc_func)(Image *, bool p_srgb); + static void (*_image_compress_bc_func)(Image *, CompressSource p_source); static void (*_image_compress_pvrtc2_func)(Image *); static void (*_image_compress_pvrtc4_func)(Image *); static void (*_image_compress_etc1_func)(Image *, float); - static void (*_image_compress_etc2_func)(Image *, float); + static void (*_image_compress_etc2_func)(Image *, float, CompressSource p_source); static void (*_image_decompress_pvrtc)(Image *); static void (*_image_decompress_bc)(Image *); @@ -267,7 +273,7 @@ public: COMPRESS_ETC2, }; - Error compress(CompressMode p_mode = COMPRESS_S3TC, bool p_for_srgb = false, float p_lossy_quality = 0.7); + Error compress(CompressMode p_mode = COMPRESS_S3TC, CompressSource p_source = COMPRESS_SOURCE_GENERIC, float p_lossy_quality = 0.7); Error decompress(); bool is_compressed() const; @@ -281,7 +287,7 @@ public: Rect2 get_used_rect() const; Ref get_rect(const Rect2 &p_area) const; - static void set_compress_bc_func(void (*p_compress_func)(Image *, bool)); + static void set_compress_bc_func(void (*p_compress_func)(Image *, CompressSource)); static String get_format_name(Format p_format); Image(const uint8_t *p_mem_png_jpg, int p_len = -1); @@ -322,6 +328,7 @@ public: VARIANT_ENUM_CAST(Image::Format) VARIANT_ENUM_CAST(Image::Interpolation) VARIANT_ENUM_CAST(Image::CompressMode) +VARIANT_ENUM_CAST(Image::CompressSource) VARIANT_ENUM_CAST(Image::AlphaMode) #endif diff --git a/core/io/compression.cpp b/core/io/compression.cpp index 9ae54c38afa..f806c4da6dc 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -58,7 +58,7 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, strm.zalloc = zipio_alloc; strm.zfree = zipio_free; strm.opaque = Z_NULL; - int level = GLOBAL_GET("compression/zlib_compression_level"); + int level = GLOBAL_GET("compression/zlib/compression_level"); int err = deflateInit(&strm, level); if (err != Z_OK) return -1; @@ -81,7 +81,7 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, case MODE_ZSTD: { int max_dst_size = get_max_compressed_buffer_size(p_src_size, MODE_ZSTD); - int level = GLOBAL_GET("compression/zstd_compression_level"); + int level = GLOBAL_GET("compression/zstd/compression_level"); return ZSTD_compress(p_dst, max_dst_size, p_src, p_src_size, level); } break; } diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index f7253c6b5b1..5447a17dcc9 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1207,6 +1207,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m } break; case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { tex = storage->resources.normal_tex; + } break; default: { tex = storage->resources.white_tex; @@ -1220,6 +1221,13 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m t->detect_3d(t->detect_3d_ud); } #endif + +#ifdef TOOLS_ENABLED + if (t->detect_normal && texture_hints[i] == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL) { + t->detect_normal(t->detect_normal_ud); + } +#endif + if (storage->config.srgb_decode_supported) { //if SRGB decode extension is present, simply switch the texture to whathever is needed bool must_srgb = false; diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index ac2cbcbd54f..0da9e387690 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -1072,6 +1072,14 @@ void RasterizerStorageGLES3::texture_set_detect_srgb_callback(RID p_texture, Vis texture->detect_srgb_ud = p_userdata; } +void RasterizerStorageGLES3::texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) { + Texture *texture = texture_owner.get(p_texture); + ERR_FAIL_COND(!texture); + + texture->detect_normal = p_callback; + texture->detect_normal_ud = p_userdata; +} + RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_resolution) const { Texture *texture = texture_owner.get(p_source); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index e4bde964435..643554e55da 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -270,6 +270,9 @@ public: VisualServer::TextureDetectCallback detect_srgb; void *detect_srgb_ud; + VisualServer::TextureDetectCallback detect_normal; + void *detect_normal_ud; + Texture() { using_srgb = false; @@ -289,6 +292,8 @@ public: detect_3d_ud = NULL; detect_srgb = NULL; detect_srgb_ud = NULL; + detect_normal = NULL; + detect_normal_ud = NULL; } ~Texture() { @@ -329,6 +334,7 @@ public: virtual void texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); + virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); /* SKY API */ diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 1a88c45eac4..41b2353ed33 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -66,6 +66,22 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref &p_t singleton->mutex->unlock(); } +void ResourceImporterTexture::_texture_reimport_normal(const Ref &p_tex) { + + singleton->mutex->lock(); + StringName path = p_tex->get_path(); + + if (!singleton->make_flags.has(path)) { + singleton->make_flags[path] = 0; + } + + singleton->make_flags[path] |= MAKE_NORMAL_FLAG; + + print_line("requesting normalfor " + String(path)); + + singleton->mutex->unlock(); +} + void ResourceImporterTexture::update_imports() { if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) { @@ -96,6 +112,11 @@ void ResourceImporterTexture::update_imports() { changed = true; } + if (E->get() & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) { + cf->set_value("params", "compress/normal_map", 1); + changed = true; + } + if (E->get() & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d"))) { cf->set_value("params", "detect_3d", false); cf->set_value("params", "compress/mode", 2); @@ -174,6 +195,7 @@ void ResourceImporterTexture::get_import_options(List *r_options, r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 2 : 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_mode", PROPERTY_HINT_ENUM, "Compress,Force RGBE"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/normal_map", PROPERTY_HINT_ENUM, "Detect,Enable,Disabled"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirrored"), p_preset == PRESET_3D ? 1 : 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/filter"), p_preset == PRESET_2D_PIXEL ? false : true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/mipmaps"), p_preset == PRESET_3D ? true : false)); @@ -187,8 +209,9 @@ void ResourceImporterTexture::get_import_options(List *r_options, r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "detect_3d"), p_preset == PRESET_DETECT)); } -void ResourceImporterTexture::_save_stex(const Ref &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) { +void ResourceImporterTexture::_save_stex(const Ref &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) { + print_line("saving: " + p_to_path); FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE); f->store_8('G'); f->store_8('D'); @@ -209,6 +232,8 @@ void ResourceImporterTexture::_save_stex(const Ref &p_image, const String format |= StreamTexture::FORMAT_BIT_DETECT_3D; if (p_detect_srgb) format |= StreamTexture::FORMAT_BIT_DETECT_SRGB; + if (p_detect_normal) + format |= StreamTexture::FORMAT_BIT_DETECT_NORMAL; if ((p_compress_mode == COMPRESS_LOSSLESS || p_compress_mode == COMPRESS_LOSSY) && p_image->get_format() > Image::FORMAT_RGBA8) { p_compress_mode == COMPRESS_UNCOMPRESSED; //these can't go as lossy @@ -281,7 +306,14 @@ void ResourceImporterTexture::_save_stex(const Ref &p_image, const String if (p_force_rgbe && image->get_format() >= Image::FORMAT_R8 && image->get_format() <= Image::FORMAT_RGBE9995) { image->convert(Image::FORMAT_RGBE9995); } else { - image->compress(p_vram_compression, p_texture_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR, p_lossy_quality); + Image::CompressSource csource = Image::COMPRESS_SOURCE_GENERIC; + if (p_force_normal) { + csource = Image::COMPRESS_SOURCE_NORMAL; + } else if (p_texture_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { + csource = Image::COMPRESS_SOURCE_SRGB; + } + + image->compress(p_vram_compression, csource, p_lossy_quality); } format |= image->get_format(); @@ -292,7 +324,6 @@ void ResourceImporterTexture::_save_stex(const Ref &p_image, const String int dl = data.size(); PoolVector::Read r = data.read(); f->store_buffer(r.ptr(), dl); - } break; case COMPRESS_UNCOMPRESSED: { @@ -333,6 +364,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String int size_limit = p_options["size_limit"]; bool force_rgbe = int(p_options["compress/hdr_mode"]) == 1; bool hdr_as_srgb = p_options["process/HDR_as_SRGB"]; + int normal = p_options["compress/normal_map"]; Ref image; image.instance(); @@ -380,20 +412,38 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String bool detect_3d = p_options["detect_3d"]; bool detect_srgb = srgb == 2; + bool detect_normal = normal == 0; + bool force_normal = normal == 1; if (compress_mode == COMPRESS_VIDEO_RAM) { //must import in all formats //Android, GLES 2.x - _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe); - r_platform_variants->push_back("etc"); - _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe); - r_platform_variants->push_back("etc2"); - _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe); - r_platform_variants->push_back("s3tc"); + if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_s3tc")) { + + _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); + r_platform_variants->push_back("s3tc"); + } + + if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_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); + r_platform_variants->push_back("etc"); + } + + if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_etc2")) { + + _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); + r_platform_variants->push_back("etc2"); + } + + if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_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); + r_platform_variants->push_back("pvrtc"); + } } else { //import normally - _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); + _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); } return OK; @@ -406,6 +456,7 @@ ResourceImporterTexture::ResourceImporterTexture() { singleton = this; StreamTexture::request_3d_callback = _texture_reimport_3d; StreamTexture::request_srgb_callback = _texture_reimport_srgb; + StreamTexture::request_normal_callback = _texture_reimport_normal; mutex = Mutex::create(); } diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 4998ed7657c..31bd0f29b04 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -41,7 +41,8 @@ class ResourceImporterTexture : public ResourceImporter { protected: enum { MAKE_3D_FLAG = 1, - MAKE_SRGB_FLAG = 2 + MAKE_SRGB_FLAG = 2, + MAKE_NORMAL_FLAG = 4 }; Mutex *mutex; @@ -49,6 +50,7 @@ protected: static void _texture_reimport_srgb(const Ref &p_tex); static void _texture_reimport_3d(const Ref &p_tex); + static void _texture_reimport_normal(const Ref &p_tex); static ResourceImporterTexture *singleton; @@ -80,7 +82,7 @@ public: virtual void get_import_options(List *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map &p_options) const; - void _save_stex(const Ref &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); + void _save_stex(const Ref &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); virtual Error import(const String &p_source_file, const String &p_save_path, const Map &p_options, List *r_platform_variants, List *r_gen_files = NULL); diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp index 4ccd5c8d89f..948f50b7821 100644 --- a/modules/etc/image_etc.cpp +++ b/modules/etc/image_etc.cpp @@ -94,10 +94,20 @@ static void _decompress_etc2(Image *p_img) { // not implemented, to be removed } -static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_format) { +static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_format, Image::CompressSource p_source) { Image::Format img_format = p_img->get_format(); Image::DetectChannels detected_channels = p_img->get_detected_channels(); + if (p_source == Image::COMPRESS_SOURCE_SRGB && (detected_channels == Image::DETECTED_R || detected_channels == Image::DETECTED_RG)) { + //R and RG do not support SRGB + detected_channels = Image::DETECTED_RGB; + } + + if (p_source == Image::COMPRESS_SOURCE_NORMAL) { + //use RG channels only for normal + detected_channels = Image::DETECTED_RG; + } + if (img_format >= Image::FORMAT_DXT1) { return; //do not compress, already compressed } @@ -128,10 +138,18 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f PoolVector::Write w = dst_data.write(); // prepare parameters to be passed to etc2comp - int num_cpus = OS::get_singleton()->get_processor_count(); + int num_cpus = OS::get_singleton()->get_processor_count() * 2; //generally some cpus have 2 threads int encoding_time = 0; - float effort = CLAMP(p_lossy_quality * 100, 0, 100); - Etc::ErrorMetric error_metric = Etc::ErrorMetric::BT709; // NOTE: we can experiment with other error metrics + float effort = 0.0; //default, reasonable time + + if (p_lossy_quality > 0.75) + effort = 0.4; + else if (p_lossy_quality > 0.85) + effort = 0.6; + else if (p_lossy_quality > 0.95) + effort = 0.8; + + Etc::ErrorMetric error_metric = Etc::ErrorMetric::RGBX; // NOTE: we can experiment with other error metrics Etc::Image::Format etc2comp_etc_format = _image_format_to_etc2comp_format(etc_format); int wofs = 0; @@ -164,11 +182,11 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f } static void _compress_etc1(Image *p_img, float p_lossy_quality) { - _compress_etc(p_img, p_lossy_quality, true); + _compress_etc(p_img, p_lossy_quality, true, Image::COMPRESS_SOURCE_GENERIC); } -static void _compress_etc2(Image *p_img, float p_lossy_quality) { - _compress_etc(p_img, p_lossy_quality, false); +static void _compress_etc2(Image *p_img, float p_lossy_quality, Image::CompressSource p_source) { + _compress_etc(p_img, p_lossy_quality, false, p_source); } void _register_etc_compress_func() { diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp index 32772e0cd26..efce76c8053 100644 --- a/modules/squish/image_compress_squish.cpp +++ b/modules/squish/image_compress_squish.cpp @@ -80,7 +80,7 @@ void image_decompress_squish(Image *p_image) { p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); } -void image_compress_squish(Image *p_image, bool p_srgb) { +void image_compress_squish(Image *p_image, Image::CompressSource p_source) { if (p_image->get_format() >= Image::FORMAT_DXT1) return; //do not compress, already compressed @@ -97,11 +97,16 @@ void image_compress_squish(Image *p_image, bool p_srgb) { p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert - if (p_srgb && (dc == Image::DETECTED_R || dc == Image::DETECTED_RG)) { + if (p_source == Image::COMPRESS_SOURCE_SRGB && (dc == Image::DETECTED_R || dc == Image::DETECTED_RG)) { //R and RG do not support SRGB dc = Image::DETECTED_RGB; } + if (p_source == Image::COMPRESS_SOURCE_NORMAL) { + //R and RG do not support SRGB + dc = Image::DETECTED_RG; + } + switch (dc) { case Image::DETECTED_L: { diff --git a/modules/squish/image_compress_squish.h b/modules/squish/image_compress_squish.h index 8d859b8e0b8..68aaeefc30f 100644 --- a/modules/squish/image_compress_squish.h +++ b/modules/squish/image_compress_squish.h @@ -32,7 +32,7 @@ #include "image.h" -void image_compress_squish(Image *p_image, bool p_srgb); +void image_compress_squish(Image *p_image, Image::CompressSource p_source); void image_decompress_squish(Image *p_image); #endif // IMAGE_COMPRESS_SQUISH_H diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index d3bdc401abc..bc1b16bea81 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -427,10 +427,10 @@ void ColorPicker::_screen_input(const Ref &ev) { Viewport *r = get_tree()->get_root(); if (!r->get_visible_rect().has_point(Point2(mev->get_global_position().x, mev->get_global_position().y))) return; - Ref img = r->get_screen_capture(); + Ref img; //= r->get_screen_capture(); if (!img.is_null()) { last_capture = img; - r->queue_screen_capture(); + //r->queue_screen_capture(); } if (last_capture.is_valid() && !last_capture->empty()) { int pw = last_capture->get_format() == Image::FORMAT_RGBA8 ? 4 : 3; @@ -460,7 +460,7 @@ void ColorPicker::_screen_pick_pressed() { } screen->raise(); screen->show_modal(); - r->queue_screen_capture(); + // r->queue_screen_capture(); } void ColorPicker::_bind_methods() { diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index d8ec8b99917..714327c5b7b 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1233,16 +1233,6 @@ Viewport::UpdateMode Viewport::get_update_mode() const { } //RID get_texture() const; -void Viewport::queue_screen_capture() { - - //VS::get_singleton()->viewport_queue_screen_capture(viewport); -} -Ref Viewport::get_screen_capture() const { - - //return VS::get_singleton()->viewport_get_screen_capture(viewport); - return Ref(); -} - Ref Viewport::get_texture() const { return default_texture; @@ -2581,8 +2571,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("is_size_override_enabled"), &Viewport::is_size_override_enabled); ClassDB::bind_method(D_METHOD("set_size_override_stretch", "enabled"), &Viewport::set_size_override_stretch); ClassDB::bind_method(D_METHOD("is_size_override_stretch_enabled"), &Viewport::is_size_override_stretch_enabled); - ClassDB::bind_method(D_METHOD("queue_screen_capture"), &Viewport::queue_screen_capture); - ClassDB::bind_method(D_METHOD("get_screen_capture"), &Viewport::get_screen_capture); ClassDB::bind_method(D_METHOD("set_vflip", "enable"), &Viewport::set_vflip); ClassDB::bind_method(D_METHOD("get_vflip"), &Viewport::get_vflip); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 378055bef5a..bd9747d8781 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -413,9 +413,6 @@ public: Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const; Vector2 get_camera_rect_size() const; - void queue_screen_capture(); - Ref get_screen_capture() const; - void set_use_own_world(bool p_world); bool is_using_own_world() const; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 0b8ad5536ce..b819dc13b3f 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -390,8 +390,17 @@ void StreamTexture::_requested_srgb(void *p_ud) { request_srgb_callback(stex); } +void StreamTexture::_requested_normal(void *p_ud) { + + StreamTexture *st = (StreamTexture *)p_ud; + Ref stex(st); + ERR_FAIL_COND(!request_normal_callback); + request_normal_callback(stex); +} + StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = NULL; StreamTexture::TextureFormatRequestCallback StreamTexture::request_srgb_callback = NULL; +StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = NULL; uint32_t StreamTexture::get_flags() const { @@ -421,12 +430,13 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla flags = f->get_32(); //texture flags! uint32_t df = f->get_32(); //data format - /* +/* print_line("width: " + itos(tw)); print_line("height: " + itos(th)); print_line("flags: " + itos(flags)); print_line("df: " + itos(df)); */ +#ifdef TOOLS_ENABLED if (request_3d_callback && df & FORMAT_BIT_DETECT_3D) { //print_line("request detect 3D at " + p_path); @@ -444,6 +454,14 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla VS::get_singleton()->texture_set_detect_srgb_callback(texture, NULL, NULL); } + if (request_srgb_callback && df & FORMAT_BIT_DETECT_NORMAL) { + //print_line("request detect srgb at " + p_path); + VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this); + } else { + //print_line("not requesting detect normal at " + p_path); + VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL); + } +#endif if (!(df & FORMAT_BIT_STREAM)) { p_size_limit = 0; } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 3a0f466b4f4..662614e0e5f 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -167,6 +167,7 @@ public: FORMAT_BIT_HAS_MIPMAPS = 1 << 23, FORMAT_BIT_DETECT_3D = 1 << 24, FORMAT_BIT_DETECT_SRGB = 1 << 25, + FORMAT_BIT_DETECT_NORMAL = 1 << 26, }; private: @@ -181,6 +182,7 @@ private: static void _requested_3d(void *p_ud); static void _requested_srgb(void *p_ud); + static void _requested_normal(void *p_ud); protected: static void _bind_methods(); @@ -190,6 +192,7 @@ public: static TextureFormatRequestCallback request_3d_callback; static TextureFormatRequestCallback request_srgb_callback; + static TextureFormatRequestCallback request_normal_callback; uint32_t get_flags() const; Image::Format get_format() const; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 35b9d0284d8..44cfbf74cee 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -189,6 +189,7 @@ public: virtual void texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) = 0; virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) = 0; + virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) = 0; virtual void textures_keep_original(bool p_enable) = 0; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 887933f7fc0..ee08c74a717 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -646,6 +646,7 @@ public: BIND3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *) BIND3(texture_set_detect_srgb_callback, RID, TextureDetectCallback, void *) + BIND3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *) BIND2(texture_set_path, RID, const String &) BIND1RC(String, texture_get_path, RID) diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 8df46b6babb..7df9c39eb29 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -92,6 +92,7 @@ public: FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *) FUNC3(texture_set_detect_srgb_callback, RID, TextureDetectCallback, void *) + FUNC3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *) FUNC2(texture_set_path, RID, const String &) FUNC1RC(String, texture_get_path, RID) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index b2dda455e96..caaef46d245 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1564,6 +1564,10 @@ VisualServer::VisualServer() { //ERR_FAIL_COND(singleton); singleton = this; + GLOBAL_DEF("rendering/vram_formats/use_s3tc", true); + GLOBAL_DEF("rendering/vram_formats/use_etc", false); + GLOBAL_DEF("rendering/vram_formats/use_etc2", true); + GLOBAL_DEF("rendering/vram_formats/use_pvrtc", false); } VisualServer::~VisualServer() { diff --git a/servers/visual_server.h b/servers/visual_server.h index c41f134bcc6..4940438daf3 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -128,6 +128,7 @@ public: virtual void texture_set_detect_3d_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0; virtual void texture_set_detect_srgb_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0; + virtual void texture_set_detect_normal_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0; struct TextureInfo { RID texture;