1 /*************************************************************************/
2 /* resource_importer_texture.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30
31 #include "resource_importer_texture.h"
32
33 #include "core/io/config_file.h"
34 #include "core/io/image_loader.h"
35 #include "editor/editor_file_system.h"
36 #include "editor/editor_node.h"
37 #include "scene/resources/texture.h"
38
_texture_reimport_srgb(const Ref<StreamTexture> & p_tex)39 void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture> &p_tex) {
40
41 singleton->mutex->lock();
42 StringName path = p_tex->get_path();
43
44 if (!singleton->make_flags.has(path)) {
45 singleton->make_flags[path] = 0;
46 }
47
48 singleton->make_flags[path] |= MAKE_SRGB_FLAG;
49
50 singleton->mutex->unlock();
51 }
52
_texture_reimport_3d(const Ref<StreamTexture> & p_tex)53 void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_tex) {
54
55 singleton->mutex->lock();
56 StringName path = p_tex->get_path();
57
58 if (!singleton->make_flags.has(path)) {
59 singleton->make_flags[path] = 0;
60 }
61
62 singleton->make_flags[path] |= MAKE_3D_FLAG;
63
64 singleton->mutex->unlock();
65 }
66
_texture_reimport_normal(const Ref<StreamTexture> & p_tex)67 void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture> &p_tex) {
68
69 singleton->mutex->lock();
70 StringName path = p_tex->get_path();
71
72 if (!singleton->make_flags.has(path)) {
73 singleton->make_flags[path] = 0;
74 }
75
76 singleton->make_flags[path] |= MAKE_NORMAL_FLAG;
77
78 singleton->mutex->unlock();
79 }
80
update_imports()81 void ResourceImporterTexture::update_imports() {
82
83 if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) {
84 return; // do nothing for now
85 }
86 mutex->lock();
87
88 if (make_flags.empty()) {
89 mutex->unlock();
90 return;
91 }
92
93 Vector<String> to_reimport;
94 for (Map<StringName, int>::Element *E = make_flags.front(); E; E = E->next()) {
95
96 Ref<ConfigFile> cf;
97 cf.instance();
98 String src_path = String(E->key()) + ".import";
99
100 Error err = cf->load(src_path);
101 ERR_CONTINUE(err != OK);
102
103 bool changed = false;
104 if (E->get() & MAKE_SRGB_FLAG && int(cf->get_value("params", "flags/srgb")) == 2) {
105 cf->set_value("params", "flags/srgb", 1);
106 changed = true;
107 }
108
109 if (E->get() & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) {
110 cf->set_value("params", "compress/normal_map", 1);
111 changed = true;
112 }
113
114 if (E->get() & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d"))) {
115 cf->set_value("params", "detect_3d", false);
116 cf->set_value("params", "compress/mode", 2);
117 cf->set_value("params", "flags/repeat", true);
118 cf->set_value("params", "flags/filter", true);
119 cf->set_value("params", "flags/mipmaps", true);
120 changed = true;
121 }
122
123 if (changed) {
124 cf->save(src_path);
125 to_reimport.push_back(E->key());
126 }
127 }
128
129 make_flags.clear();
130
131 mutex->unlock();
132
133 if (to_reimport.size()) {
134 EditorFileSystem::get_singleton()->reimport_files(to_reimport);
135 }
136 }
137
get_importer_name() const138 String ResourceImporterTexture::get_importer_name() const {
139
140 return "texture";
141 }
142
get_visible_name() const143 String ResourceImporterTexture::get_visible_name() const {
144
145 return "Texture";
146 }
get_recognized_extensions(List<String> * p_extensions) const147 void ResourceImporterTexture::get_recognized_extensions(List<String> *p_extensions) const {
148
149 ImageLoader::get_recognized_extensions(p_extensions);
150 }
get_save_extension() const151 String ResourceImporterTexture::get_save_extension() const {
152 return "stex";
153 }
154
get_resource_type() const155 String ResourceImporterTexture::get_resource_type() const {
156
157 return "StreamTexture";
158 }
159
get_option_visibility(const String & p_option,const Map<StringName,Variant> & p_options) const160 bool ResourceImporterTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
161
162 if (p_option == "compress/lossy_quality") {
163 int compress_mode = int(p_options["compress/mode"]);
164 if (compress_mode != COMPRESS_LOSSY && compress_mode != COMPRESS_VIDEO_RAM) {
165 return false;
166 }
167 } else if (p_option == "compress/hdr_mode") {
168 int compress_mode = int(p_options["compress/mode"]);
169 if (compress_mode != COMPRESS_VIDEO_RAM) {
170 return false;
171 }
172 } else if (p_option == "compress/bptc_ldr") {
173 int compress_mode = int(p_options["compress/mode"]);
174 if (compress_mode != COMPRESS_VIDEO_RAM) {
175 return false;
176 }
177 if (!ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc")) {
178 return false;
179 }
180 }
181
182 return true;
183 }
184
get_preset_count() const185 int ResourceImporterTexture::get_preset_count() const {
186 return 4;
187 }
get_preset_name(int p_idx) const188 String ResourceImporterTexture::get_preset_name(int p_idx) const {
189
190 static const char *preset_names[] = {
191 "2D, Detect 3D",
192 "2D",
193 "2D Pixel",
194 "3D"
195 };
196
197 return preset_names[p_idx];
198 }
199
get_import_options(List<ImportOption> * r_options,int p_preset) const200 void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const {
201
202 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));
203 r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
204 r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_mode", PROPERTY_HINT_ENUM, "Enabled,Force RGBE"), 0));
205 r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Enabled,RGBA Only"), 0));
206 r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/normal_map", PROPERTY_HINT_ENUM, "Detect,Enable,Disabled"), 0));
207 r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirrored"), p_preset == PRESET_3D ? 1 : 0));
208 r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/filter"), p_preset != PRESET_2D_PIXEL));
209 r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/mipmaps"), p_preset == PRESET_3D));
210 r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/anisotropic"), false));
211 r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/srgb", PROPERTY_HINT_ENUM, "Disable,Enable,Detect"), 2));
212 r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/fix_alpha_border"), p_preset != PRESET_3D));
213 r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false));
214 r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/HDR_as_SRGB"), false));
215 r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/invert_color"), false));
216 r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "stream"), false));
217 r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
218 r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "detect_3d"), p_preset == PRESET_DETECT));
219 r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0));
220 }
221
_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)222 void ResourceImporterTexture::_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) {
223
224 FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE);
225 f->store_8('G');
226 f->store_8('D');
227 f->store_8('S');
228 f->store_8('T'); //godot streamable texture
229
230 bool resize_to_po2 = false;
231
232 if (p_compress_mode == COMPRESS_VIDEO_RAM && p_force_po2_for_compressed && (p_mipmaps || p_texture_flags & Texture::FLAG_REPEAT)) {
233 resize_to_po2 = true;
234 f->store_16(next_power_of_2(p_image->get_width()));
235 f->store_16(p_image->get_width());
236 f->store_16(next_power_of_2(p_image->get_height()));
237 f->store_16(p_image->get_height());
238 } else {
239 f->store_16(p_image->get_width());
240 f->store_16(0);
241 f->store_16(p_image->get_height());
242 f->store_16(0);
243 }
244 f->store_32(p_texture_flags);
245
246 uint32_t format = 0;
247
248 if (p_streamable)
249 format |= StreamTexture::FORMAT_BIT_STREAM;
250 if (p_mipmaps)
251 format |= StreamTexture::FORMAT_BIT_HAS_MIPMAPS; //mipmaps bit
252 if (p_detect_3d)
253 format |= StreamTexture::FORMAT_BIT_DETECT_3D;
254 if (p_detect_srgb)
255 format |= StreamTexture::FORMAT_BIT_DETECT_SRGB;
256 if (p_detect_normal)
257 format |= StreamTexture::FORMAT_BIT_DETECT_NORMAL;
258
259 if ((p_compress_mode == COMPRESS_LOSSLESS || p_compress_mode == COMPRESS_LOSSY) && p_image->get_format() > Image::FORMAT_RGBA8) {
260 p_compress_mode = COMPRESS_UNCOMPRESSED; //these can't go as lossy
261 }
262
263 switch (p_compress_mode) {
264 case COMPRESS_LOSSLESS: {
265
266 Ref<Image> image = p_image->duplicate();
267 if (p_mipmaps) {
268 image->generate_mipmaps();
269 } else {
270 image->clear_mipmaps();
271 }
272
273 int mmc = image->get_mipmap_count() + 1;
274
275 format |= StreamTexture::FORMAT_BIT_LOSSLESS;
276 f->store_32(format);
277 f->store_32(mmc);
278
279 for (int i = 0; i < mmc; i++) {
280
281 if (i > 0) {
282 image->shrink_x2();
283 }
284
285 PoolVector<uint8_t> data = Image::lossless_packer(image);
286 int data_len = data.size();
287 f->store_32(data_len);
288
289 PoolVector<uint8_t>::Read r = data.read();
290 f->store_buffer(r.ptr(), data_len);
291 }
292
293 } break;
294 case COMPRESS_LOSSY: {
295 Ref<Image> image = p_image->duplicate();
296 if (p_mipmaps) {
297 image->generate_mipmaps();
298 } else {
299 image->clear_mipmaps();
300 }
301
302 int mmc = image->get_mipmap_count() + 1;
303
304 format |= StreamTexture::FORMAT_BIT_LOSSY;
305 f->store_32(format);
306 f->store_32(mmc);
307
308 for (int i = 0; i < mmc; i++) {
309
310 if (i > 0) {
311 image->shrink_x2();
312 }
313
314 PoolVector<uint8_t> data = Image::lossy_packer(image, p_lossy_quality);
315 int data_len = data.size();
316 f->store_32(data_len);
317
318 PoolVector<uint8_t>::Read r = data.read();
319 f->store_buffer(r.ptr(), data_len);
320 }
321 } break;
322 case COMPRESS_VIDEO_RAM: {
323
324 Ref<Image> image = p_image->duplicate();
325 if (resize_to_po2) {
326 image->resize_to_po2();
327 }
328 if (p_mipmaps) {
329 image->generate_mipmaps(p_force_normal);
330 }
331
332 if (p_force_rgbe && image->get_format() >= Image::FORMAT_R8 && image->get_format() <= Image::FORMAT_RGBE9995) {
333 image->convert(Image::FORMAT_RGBE9995);
334 } else {
335 Image::CompressSource csource = Image::COMPRESS_SOURCE_GENERIC;
336 if (p_force_normal) {
337 csource = Image::COMPRESS_SOURCE_NORMAL;
338 } else if (p_texture_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
339 csource = Image::COMPRESS_SOURCE_SRGB;
340 }
341
342 image->compress(p_vram_compression, csource, p_lossy_quality);
343 }
344
345 format |= image->get_format();
346
347 f->store_32(format);
348
349 PoolVector<uint8_t> data = image->get_data();
350 int dl = data.size();
351 PoolVector<uint8_t>::Read r = data.read();
352 f->store_buffer(r.ptr(), dl);
353 } break;
354 case COMPRESS_UNCOMPRESSED: {
355
356 Ref<Image> image = p_image->duplicate();
357 if (p_mipmaps) {
358 image->generate_mipmaps();
359 } else {
360 image->clear_mipmaps();
361 }
362
363 format |= image->get_format();
364 f->store_32(format);
365
366 PoolVector<uint8_t> data = image->get_data();
367 int dl = data.size();
368 PoolVector<uint8_t>::Read r = data.read();
369
370 f->store_buffer(r.ptr(), dl);
371
372 } break;
373 }
374
375 memdelete(f);
376 }
377
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)378 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) {
379
380 int compress_mode = p_options["compress/mode"];
381 float lossy = p_options["compress/lossy_quality"];
382 int repeat = p_options["flags/repeat"];
383 bool filter = p_options["flags/filter"];
384 bool mipmaps = p_options["flags/mipmaps"];
385 bool anisotropic = p_options["flags/anisotropic"];
386 int srgb = p_options["flags/srgb"];
387 bool fix_alpha_border = p_options["process/fix_alpha_border"];
388 bool premult_alpha = p_options["process/premult_alpha"];
389 bool invert_color = p_options["process/invert_color"];
390 bool stream = p_options["stream"];
391 int size_limit = p_options["size_limit"];
392 bool hdr_as_srgb = p_options["process/HDR_as_SRGB"];
393 int normal = p_options["compress/normal_map"];
394 float scale = p_options["svg/scale"];
395 bool force_rgbe = p_options["compress/hdr_mode"];
396 int bptc_ldr = p_options["compress/bptc_ldr"];
397
398 Ref<Image> image;
399 image.instance();
400 Error err = ImageLoader::load_image(p_source_file, image, NULL, hdr_as_srgb, scale);
401 if (err != OK)
402 return err;
403
404 Array formats_imported;
405
406 int tex_flags = 0;
407 if (repeat > 0)
408 tex_flags |= Texture::FLAG_REPEAT;
409 if (repeat == 2)
410 tex_flags |= Texture::FLAG_MIRRORED_REPEAT;
411 if (filter)
412 tex_flags |= Texture::FLAG_FILTER;
413 if (mipmaps || compress_mode == COMPRESS_VIDEO_RAM)
414 tex_flags |= Texture::FLAG_MIPMAPS;
415 if (anisotropic)
416 tex_flags |= Texture::FLAG_ANISOTROPIC_FILTER;
417 if (srgb == 1)
418 tex_flags |= Texture::FLAG_CONVERT_TO_LINEAR;
419
420 if (size_limit > 0 && (image->get_width() > size_limit || image->get_height() > size_limit)) {
421 //limit size
422 if (image->get_width() >= image->get_height()) {
423 int new_width = size_limit;
424 int new_height = image->get_height() * new_width / image->get_width();
425
426 image->resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
427 } else {
428
429 int new_height = size_limit;
430 int new_width = image->get_width() * new_height / image->get_height();
431
432 image->resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
433 }
434
435 if (normal == 1) {
436 image->normalize();
437 }
438 }
439
440 if (fix_alpha_border) {
441 image->fix_alpha_edges();
442 }
443
444 if (premult_alpha) {
445 image->premultiply_alpha();
446 }
447
448 if (invert_color) {
449 int height = image->get_height();
450 int width = image->get_width();
451
452 image->lock();
453 for (int i = 0; i < width; i++) {
454 for (int j = 0; j < height; j++) {
455 image->set_pixel(i, j, image->get_pixel(i, j).inverted());
456 }
457 }
458 image->unlock();
459 }
460
461 bool detect_3d = p_options["detect_3d"];
462 bool detect_srgb = srgb == 2;
463 bool detect_normal = normal == 0;
464 bool force_normal = normal == 1;
465
466 if (compress_mode == COMPRESS_VIDEO_RAM) {
467 //must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
468 //Android, GLES 2.x
469
470 bool ok_on_pc = false;
471 bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995);
472 bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGBA5551);
473 bool can_bptc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc");
474 bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc");
475
476 if (can_bptc) {
477 Image::DetectChannels channels = image->get_detected_channels();
478 if (is_hdr) {
479
480 if (channels == Image::DETECTED_LA || channels == Image::DETECTED_RGBA) {
481 can_bptc = false;
482 }
483 } else if (is_ldr) {
484
485 //handle "RGBA Only" setting
486 if (bptc_ldr == 1 && channels != Image::DETECTED_LA && channels != Image::DETECTED_RGBA) {
487 can_bptc = false;
488 }
489 }
490
491 formats_imported.push_back("bptc");
492 }
493
494 if (!can_bptc && is_hdr && !force_rgbe) {
495 //convert to ldr if this can't be stored hdr
496 image->convert(Image::FORMAT_RGBA8);
497 }
498
499 if (can_bptc || can_s3tc) {
500 _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);
501 r_platform_variants->push_back("s3tc");
502 formats_imported.push_back("s3tc");
503 ok_on_pc = true;
504 }
505
506 if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
507
508 _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, true);
509 r_platform_variants->push_back("etc2");
510 formats_imported.push_back("etc2");
511 }
512
513 if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) {
514 _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);
515 r_platform_variants->push_back("etc");
516 formats_imported.push_back("etc");
517 }
518
519 if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
520
521 _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);
522 r_platform_variants->push_back("pvrtc");
523 formats_imported.push_back("pvrtc");
524 }
525
526 if (!ok_on_pc) {
527 EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correctly on PC.");
528 }
529 } else {
530 //import normally
531 _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);
532 }
533
534 if (r_metadata) {
535 Dictionary metadata;
536 metadata["vram_texture"] = compress_mode == COMPRESS_VIDEO_RAM;
537 if (formats_imported.size()) {
538 metadata["imported_formats"] = formats_imported;
539 }
540 *r_metadata = metadata;
541 }
542 return OK;
543 }
544
545 const char *ResourceImporterTexture::compression_formats[] = {
546 "bptc",
547 "s3tc",
548 "etc",
549 "etc2",
550 "pvrtc",
551 NULL
552 };
get_import_settings_string() const553 String ResourceImporterTexture::get_import_settings_string() const {
554
555 String s;
556
557 int index = 0;
558 while (compression_formats[index]) {
559 String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]);
560 bool test = ProjectSettings::get_singleton()->get(setting_path);
561 if (test) {
562 s += String(compression_formats[index]);
563 }
564 index++;
565 }
566
567 return s;
568 }
569
are_import_settings_valid(const String & p_path) const570 bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) const {
571
572 //will become invalid if formats are missing to import
573 Dictionary metadata = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path);
574
575 if (!metadata.has("vram_texture")) {
576 return false;
577 }
578
579 bool vram = metadata["vram_texture"];
580 if (!vram) {
581 return true; //do not care about non vram
582 }
583
584 Vector<String> formats_imported;
585 if (metadata.has("imported_formats")) {
586 formats_imported = metadata["imported_formats"];
587 }
588
589 int index = 0;
590 bool valid = true;
591 while (compression_formats[index]) {
592 String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]);
593 bool test = ProjectSettings::get_singleton()->get(setting_path);
594 if (test) {
595 if (formats_imported.find(compression_formats[index]) == -1) {
596 valid = false;
597 break;
598 }
599 }
600 index++;
601 }
602
603 return valid;
604 }
605
606 ResourceImporterTexture *ResourceImporterTexture::singleton = NULL;
607
ResourceImporterTexture()608 ResourceImporterTexture::ResourceImporterTexture() {
609
610 singleton = this;
611 StreamTexture::request_3d_callback = _texture_reimport_3d;
612 StreamTexture::request_srgb_callback = _texture_reimport_srgb;
613 StreamTexture::request_normal_callback = _texture_reimport_normal;
614 mutex = Mutex::create();
615 }
616
~ResourceImporterTexture()617 ResourceImporterTexture::~ResourceImporterTexture() {
618
619 memdelete(mutex);
620 }
621