Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/editor/import/resource_importer_layered_texture.cpp
9903 views
1
/**************************************************************************/
2
/* resource_importer_layered_texture.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
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_layered_texture.h"
32
33
#include "core/config/project_settings.h"
34
#include "core/error/error_macros.h"
35
#include "core/io/image_loader.h"
36
#include "core/object/ref_counted.h"
37
#include "editor/file_system/editor_file_system.h"
38
#include "editor/import/resource_importer_texture.h"
39
#include "editor/import/resource_importer_texture_settings.h"
40
#include "scene/resources/compressed_texture.h"
41
42
String ResourceImporterLayeredTexture::get_importer_name() const {
43
switch (mode) {
44
case MODE_CUBEMAP: {
45
return "cubemap_texture";
46
} break;
47
case MODE_2D_ARRAY: {
48
return "2d_array_texture";
49
} break;
50
case MODE_CUBEMAP_ARRAY: {
51
return "cubemap_array_texture";
52
} break;
53
case MODE_3D: {
54
return "3d_texture";
55
} break;
56
}
57
58
ERR_FAIL_V("");
59
}
60
61
String ResourceImporterLayeredTexture::get_visible_name() const {
62
switch (mode) {
63
case MODE_CUBEMAP: {
64
return "Cubemap";
65
} break;
66
case MODE_2D_ARRAY: {
67
return "Texture2DArray";
68
} break;
69
case MODE_CUBEMAP_ARRAY: {
70
return "CubemapArray";
71
} break;
72
case MODE_3D: {
73
return "Texture3D";
74
} break;
75
}
76
77
ERR_FAIL_V("");
78
}
79
80
void ResourceImporterLayeredTexture::get_recognized_extensions(List<String> *p_extensions) const {
81
ImageLoader::get_recognized_extensions(p_extensions);
82
}
83
84
String ResourceImporterLayeredTexture::get_save_extension() const {
85
switch (mode) {
86
case MODE_CUBEMAP: {
87
return "ccube";
88
} break;
89
case MODE_2D_ARRAY: {
90
return "ctexarray";
91
} break;
92
case MODE_CUBEMAP_ARRAY: {
93
return "ccubearray";
94
} break;
95
case MODE_3D: {
96
return "ctex3d";
97
} break;
98
}
99
100
ERR_FAIL_V(String());
101
}
102
103
String ResourceImporterLayeredTexture::get_resource_type() const {
104
switch (mode) {
105
case MODE_CUBEMAP: {
106
return "CompressedCubemap";
107
} break;
108
case MODE_2D_ARRAY: {
109
return "CompressedTexture2DArray";
110
} break;
111
case MODE_CUBEMAP_ARRAY: {
112
return "CompressedCubemapArray";
113
} break;
114
case MODE_3D: {
115
return "CompressedTexture3D";
116
} break;
117
}
118
ERR_FAIL_V(String());
119
}
120
121
bool ResourceImporterLayeredTexture::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
122
if (p_option == "compress/lossy_quality" && p_options.has("compress/mode")) {
123
return int(p_options["compress/mode"]) == COMPRESS_LOSSY;
124
}
125
if ((p_option == "compress/high_quality" || p_option == "compress/hdr_compression") && p_options.has("compress/mode")) {
126
return int(p_options["compress/mode"]) == COMPRESS_VRAM_COMPRESSED;
127
}
128
if (p_option == "compress/uastc_level" || p_option == "compress/rdo_quality_loss") {
129
return int(p_options["compress/mode"]) == COMPRESS_BASIS_UNIVERSAL;
130
}
131
132
return true;
133
}
134
135
int ResourceImporterLayeredTexture::get_preset_count() const {
136
return 0;
137
}
138
139
String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const {
140
return "";
141
}
142
143
void ResourceImporterLayeredTexture::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
144
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,VRAM Compressed,VRAM Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
145
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress/high_quality"), false));
146
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
147
148
Image::BasisUniversalPackerParams basisu_params;
149
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/uastc_level", PROPERTY_HINT_ENUM, "Fastest,Faster,Medium,Slower,Slowest"), basisu_params.uastc_level));
150
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/rdo_quality_loss", PROPERTY_HINT_RANGE, "0,10,0.001,or_greater"), basisu_params.rdo_quality_loss));
151
152
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1));
153
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/channel_pack", PROPERTY_HINT_ENUM, "sRGB Friendly,Optimized,Normal Map (RG Channels)"), 0));
154
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "mipmaps/generate"), true));
155
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mipmaps/limit", PROPERTY_HINT_RANGE, "-1,256"), -1));
156
157
if (mode == MODE_2D_ARRAY || mode == MODE_3D) {
158
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/horizontal", PROPERTY_HINT_RANGE, "1,256,1"), 8));
159
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/vertical", PROPERTY_HINT_RANGE, "1,256,1"), 8));
160
}
161
if (mode == MODE_CUBEMAP || mode == MODE_CUBEMAP_ARRAY) {
162
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/arrangement", PROPERTY_HINT_ENUM, "1x6,2x3,3x2,6x1"), 1));
163
if (mode == MODE_CUBEMAP_ARRAY) {
164
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/layout", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1));
165
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/amount", PROPERTY_HINT_RANGE, "1,1024,1,or_greater"), 1));
166
}
167
}
168
}
169
170
void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, const Image::BasisUniversalPackerParams &p_basisu_params, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2) {
171
Vector<Ref<Image>> mipmap_images; //for 3D
172
173
if (mode == MODE_3D) {
174
//3D saves in its own way
175
176
for (int i = 0; i < p_images.size(); i++) {
177
if (p_images.write[i]->has_mipmaps()) {
178
p_images.write[i]->clear_mipmaps();
179
}
180
181
if (p_force_po2) {
182
p_images.write[i]->resize_to_po2();
183
}
184
}
185
186
if (p_mipmaps) {
187
Vector<Ref<Image>> parent_images = p_images;
188
//create 3D mipmaps, this is horrible, though not used very often
189
int w = p_images[0]->get_width();
190
int h = p_images[0]->get_height();
191
int d = p_images.size();
192
193
while (w > 1 || h > 1 || d > 1) {
194
Vector<Ref<Image>> mipmaps;
195
int mm_w = MAX(1, w >> 1);
196
int mm_h = MAX(1, h >> 1);
197
int mm_d = MAX(1, d >> 1);
198
199
for (int i = 0; i < mm_d; i++) {
200
Ref<Image> mm = Image::create_empty(mm_w, mm_h, false, p_images[0]->get_format());
201
Vector3 pos;
202
pos.z = float(i) * float(d) / float(mm_d) + 0.5;
203
for (int x = 0; x < mm_w; x++) {
204
for (int y = 0; y < mm_h; y++) {
205
pos.x = float(x) * float(w) / float(mm_w) + 0.5;
206
pos.y = float(y) * float(h) / float(mm_h) + 0.5;
207
208
Vector3i posi = Vector3i(pos);
209
Vector3 fract = pos - Vector3(posi);
210
Vector3i posi_n = posi;
211
if (posi_n.x < w - 1) {
212
posi_n.x++;
213
}
214
if (posi_n.y < h - 1) {
215
posi_n.y++;
216
}
217
if (posi_n.z < d - 1) {
218
posi_n.z++;
219
}
220
221
Color c000 = parent_images[posi.z]->get_pixel(posi.x, posi.y);
222
Color c100 = parent_images[posi.z]->get_pixel(posi_n.x, posi.y);
223
Color c010 = parent_images[posi.z]->get_pixel(posi.x, posi_n.y);
224
Color c110 = parent_images[posi.z]->get_pixel(posi_n.x, posi_n.y);
225
Color c001 = parent_images[posi_n.z]->get_pixel(posi.x, posi.y);
226
Color c101 = parent_images[posi_n.z]->get_pixel(posi_n.x, posi.y);
227
Color c011 = parent_images[posi_n.z]->get_pixel(posi.x, posi_n.y);
228
Color c111 = parent_images[posi_n.z]->get_pixel(posi_n.x, posi_n.y);
229
230
Color cx00 = c000.lerp(c100, fract.x);
231
Color cx01 = c001.lerp(c101, fract.x);
232
Color cx10 = c010.lerp(c110, fract.x);
233
Color cx11 = c011.lerp(c111, fract.x);
234
235
Color cy0 = cx00.lerp(cx10, fract.y);
236
Color cy1 = cx01.lerp(cx11, fract.y);
237
238
Color cz = cy0.lerp(cy1, fract.z);
239
240
mm->set_pixel(x, y, cz);
241
}
242
}
243
244
mipmaps.push_back(mm);
245
}
246
247
w = mm_w;
248
h = mm_h;
249
d = mm_d;
250
251
mipmap_images.append_array(mipmaps);
252
parent_images = mipmaps;
253
}
254
}
255
} else {
256
for (int i = 0; i < p_images.size(); i++) {
257
if (p_force_po2) {
258
p_images.write[i]->resize_to_po2();
259
}
260
261
if (p_mipmaps) {
262
p_images.write[i]->generate_mipmaps(p_csource == Image::COMPRESS_SOURCE_NORMAL);
263
} else {
264
p_images.write[i]->clear_mipmaps();
265
}
266
}
267
}
268
269
Ref<FileAccess> f = FileAccess::open(p_to_path, FileAccess::WRITE);
270
f->store_8('G');
271
f->store_8('S');
272
f->store_8('T');
273
f->store_8('L');
274
275
f->store_32(CompressedTextureLayered::FORMAT_VERSION);
276
f->store_32(p_images.size()); // For 2d layers or 3d depth.
277
f->store_32(mode);
278
f->store_32(0);
279
280
f->store_32(0);
281
f->store_32(mipmap_images.size()); // Adjust the amount of mipmaps.
282
f->store_32(0);
283
f->store_32(0);
284
285
if ((p_compress_mode == COMPRESS_LOSSLESS || p_compress_mode == COMPRESS_LOSSY) && p_images[0]->get_format() >= Image::FORMAT_RF) {
286
p_compress_mode = COMPRESS_VRAM_UNCOMPRESSED; // These can't go as lossy.
287
}
288
289
for (int i = 0; i < p_images.size(); i++) {
290
ResourceImporterTexture::save_to_ctex_format(f, p_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy, p_basisu_params);
291
}
292
293
for (int i = 0; i < mipmap_images.size(); i++) {
294
ResourceImporterTexture::save_to_ctex_format(f, mipmap_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy, p_basisu_params);
295
}
296
}
297
298
Error ResourceImporterLayeredTexture::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
299
int compress_mode = p_options["compress/mode"];
300
float lossy = p_options["compress/lossy_quality"];
301
bool high_quality = p_options["compress/high_quality"];
302
int hdr_compression = p_options["compress/hdr_compression"];
303
bool mipmaps = p_options["mipmaps/generate"];
304
305
int channel_pack = p_options["compress/channel_pack"];
306
int hslices = (p_options.has("slices/horizontal")) ? int(p_options["slices/horizontal"]) : 0;
307
int vslices = (p_options.has("slices/vertical")) ? int(p_options["slices/vertical"]) : 0;
308
int arrangement = (p_options.has("slices/arrangement")) ? int(p_options["slices/arrangement"]) : 0;
309
int layout = (p_options.has("slices/layout")) ? int(p_options["slices/layout"]) : 0;
310
int amount = (p_options.has("slices/amount")) ? int(p_options["slices/amount"]) : 0;
311
312
if (mode == MODE_CUBEMAP || mode == MODE_CUBEMAP_ARRAY) {
313
switch (arrangement) {
314
case CUBEMAP_FORMAT_1X6: {
315
hslices = 1;
316
vslices = 6;
317
} break;
318
case CUBEMAP_FORMAT_2X3: {
319
hslices = 2;
320
vslices = 3;
321
} break;
322
case CUBEMAP_FORMAT_3X2: {
323
hslices = 3;
324
vslices = 2;
325
} break;
326
case CUBEMAP_FORMAT_6X1: {
327
hslices = 6;
328
vslices = 1;
329
} break;
330
}
331
332
if (mode == MODE_CUBEMAP_ARRAY) {
333
if (layout == 0) {
334
hslices *= amount;
335
} else {
336
vslices *= amount;
337
}
338
}
339
}
340
341
Ref<Image> image;
342
image.instantiate();
343
Error err = ImageLoader::load_image(p_source_file, image);
344
if (err != OK) {
345
return err;
346
}
347
348
if (compress_mode == COMPRESS_VRAM_COMPRESSED) {
349
//if using video ram, optimize
350
if (channel_pack == 0) {
351
//remove alpha if not needed, so compression is more efficient
352
if (image->get_format() == Image::FORMAT_RGBA8 && image->detect_alpha() == Image::ALPHA_NONE) {
353
image->convert(Image::FORMAT_RGB8);
354
}
355
} else if (image->get_format() < Image::FORMAT_RGBA8) {
356
image->optimize_channels();
357
}
358
}
359
360
Image::CompressSource csource = Image::COMPRESS_SOURCE_GENERIC;
361
if (channel_pack == 0) {
362
csource = Image::COMPRESS_SOURCE_SRGB;
363
} else if (channel_pack == 2) {
364
// force normal
365
csource = Image::COMPRESS_SOURCE_NORMAL;
366
}
367
368
Image::UsedChannels used_channels = image->detect_used_channels(csource);
369
370
Vector<Ref<Image>> slices;
371
372
int slice_w = image->get_width() / hslices;
373
int slice_h = image->get_height() / vslices;
374
375
for (int i = 0; i < vslices; i++) {
376
for (int j = 0; j < hslices; j++) {
377
int x = slice_w * j;
378
int y = slice_h * i;
379
Ref<Image> slice = image->get_region(Rect2i(x, y, slice_w, slice_h));
380
ERR_CONTINUE(slice.is_null() || slice->is_empty());
381
if (slice->get_width() != slice_w || slice->get_height() != slice_h) {
382
slice->resize(slice_w, slice_h);
383
}
384
slices.push_back(slice);
385
}
386
}
387
388
const Image::BasisUniversalPackerParams basisu_params = {
389
p_options["compress/uastc_level"],
390
p_options["compress/rdo_quality_loss"],
391
};
392
393
Array formats_imported;
394
Ref<LayeredTextureImport> texture_import;
395
texture_import.instantiate();
396
texture_import->csource = &csource;
397
texture_import->save_path = p_save_path;
398
texture_import->options = p_options;
399
texture_import->platform_variants = r_platform_variants;
400
texture_import->image = image;
401
texture_import->formats_imported = formats_imported;
402
texture_import->slices = &slices;
403
texture_import->compress_mode = compress_mode;
404
texture_import->lossy = lossy;
405
texture_import->hdr_compression = hdr_compression;
406
texture_import->mipmaps = mipmaps;
407
texture_import->used_channels = used_channels;
408
texture_import->high_quality = high_quality;
409
410
texture_import->basisu_params = basisu_params;
411
412
_check_compress_ctex(p_source_file, texture_import);
413
if (r_metadata) {
414
Dictionary meta;
415
meta["vram_texture"] = compress_mode == COMPRESS_VRAM_COMPRESSED;
416
if (formats_imported.size()) {
417
meta["imported_formats"] = formats_imported;
418
}
419
*r_metadata = meta;
420
}
421
422
return OK;
423
}
424
425
const char *ResourceImporterLayeredTexture::compression_formats[] = {
426
"s3tc_bptc",
427
"etc2_astc",
428
nullptr
429
};
430
431
String ResourceImporterLayeredTexture::get_import_settings_string() const {
432
String s;
433
434
int index = 0;
435
while (compression_formats[index]) {
436
String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
437
bool test = GLOBAL_GET(setting_path);
438
if (test) {
439
s += String(compression_formats[index]);
440
}
441
index++;
442
}
443
444
return s;
445
}
446
447
bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_path, const Dictionary &p_meta) const {
448
//will become invalid if formats are missing to import
449
if (!p_meta.has("vram_texture")) {
450
return false;
451
}
452
453
bool vram = p_meta["vram_texture"];
454
if (!vram) {
455
return true; //do not care about non vram
456
}
457
458
Vector<String> formats_imported;
459
if (p_meta.has("imported_formats")) {
460
formats_imported = p_meta["imported_formats"];
461
}
462
463
int index = 0;
464
bool valid = true;
465
while (compression_formats[index]) {
466
String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
467
if (ProjectSettings::get_singleton()->has_setting(setting_path)) {
468
bool test = GLOBAL_GET(setting_path);
469
if (test) {
470
if (!formats_imported.has(compression_formats[index])) {
471
valid = false;
472
break;
473
}
474
}
475
} else {
476
WARN_PRINT("Setting for imported format not found: " + setting_path);
477
}
478
index++;
479
}
480
481
return valid;
482
}
483
484
ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = nullptr;
485
486
ResourceImporterLayeredTexture::ResourceImporterLayeredTexture(bool p_singleton) {
487
// This should only be set through the EditorNode.
488
if (p_singleton) {
489
singleton = this;
490
}
491
492
mode = MODE_CUBEMAP;
493
}
494
495
ResourceImporterLayeredTexture::~ResourceImporterLayeredTexture() {
496
if (singleton == this) {
497
singleton = nullptr;
498
}
499
}
500
501
void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source_file, Ref<LayeredTextureImport> r_texture_import) {
502
String extension = get_save_extension();
503
ERR_FAIL_NULL(r_texture_import->csource);
504
if (r_texture_import->compress_mode != COMPRESS_VRAM_COMPRESSED) {
505
// Import normally.
506
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, r_texture_import->basisu_params,
507
Image::COMPRESS_S3TC /* IGNORED */, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, false);
508
return;
509
}
510
// Must import in all formats, in order of priority (so platform chooses the best supported one. IE, etc2 over etc).
511
// Android, GLES 2.x
512
513
const bool can_s3tc_bptc = ResourceImporterTextureSettings::should_import_s3tc_bptc();
514
const bool can_etc2_astc = ResourceImporterTextureSettings::should_import_etc2_astc();
515
516
// Add list of formats imported
517
if (can_s3tc_bptc) {
518
r_texture_import->formats_imported.push_back("s3tc_bptc");
519
}
520
if (can_etc2_astc) {
521
r_texture_import->formats_imported.push_back("etc2_astc");
522
}
523
524
bool can_compress_hdr = r_texture_import->hdr_compression > 0;
525
ERR_FAIL_COND(r_texture_import->image.is_null());
526
bool is_hdr = (r_texture_import->image->get_format() >= Image::FORMAT_RF && r_texture_import->image->get_format() <= Image::FORMAT_RGBE9995);
527
ERR_FAIL_NULL(r_texture_import->slices);
528
// Can compress hdr, but hdr with alpha is not compressible.
529
bool use_uncompressed = false;
530
531
if (is_hdr) {
532
if (r_texture_import->used_channels == Image::USED_CHANNELS_LA || r_texture_import->used_channels == Image::USED_CHANNELS_RGBA) {
533
if (r_texture_import->hdr_compression == 2) {
534
// The user selected to compress hdr anyway, so force an alpha-less format.
535
if (r_texture_import->image->get_format() == Image::FORMAT_RGBAF) {
536
for (int i = 0; i < r_texture_import->slices->size(); i++) {
537
r_texture_import->slices->write[i]->convert(Image::FORMAT_RGBF);
538
}
539
540
} else if (r_texture_import->image->get_format() == Image::FORMAT_RGBAH) {
541
for (int i = 0; i < r_texture_import->slices->size(); i++) {
542
r_texture_import->slices->write[i]->convert(Image::FORMAT_RGBH);
543
}
544
}
545
} else {
546
can_compress_hdr = false;
547
}
548
}
549
550
if (!can_compress_hdr) {
551
//default to rgbe
552
if (r_texture_import->image->get_format() != Image::FORMAT_RGBE9995) {
553
for (int i = 0; i < r_texture_import->slices->size(); i++) {
554
r_texture_import->slices->write[i]->convert(Image::FORMAT_RGBE9995);
555
}
556
}
557
use_uncompressed = true;
558
}
559
}
560
561
if (use_uncompressed) {
562
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + extension, COMPRESS_VRAM_UNCOMPRESSED, r_texture_import->lossy, r_texture_import->basisu_params,
563
Image::COMPRESS_S3TC /* IGNORED */, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, false);
564
} else {
565
if (can_s3tc_bptc) {
566
Image::CompressMode image_compress_mode;
567
String image_compress_format;
568
if (r_texture_import->high_quality || is_hdr) {
569
image_compress_mode = Image::COMPRESS_BPTC;
570
image_compress_format = "bptc";
571
} else {
572
image_compress_mode = Image::COMPRESS_S3TC;
573
image_compress_format = "s3tc";
574
}
575
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + image_compress_format + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, r_texture_import->basisu_params, image_compress_mode, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true);
576
r_texture_import->platform_variants->push_back(image_compress_format);
577
}
578
579
if (can_etc2_astc) {
580
Image::CompressMode image_compress_mode;
581
String image_compress_format;
582
if (r_texture_import->high_quality || is_hdr) {
583
image_compress_mode = Image::COMPRESS_ASTC;
584
image_compress_format = "astc";
585
} else {
586
image_compress_mode = Image::COMPRESS_ETC2;
587
image_compress_format = "etc2";
588
}
589
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + image_compress_format + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, r_texture_import->basisu_params, image_compress_mode, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true);
590
r_texture_import->platform_variants->push_back(image_compress_format);
591
}
592
}
593
}
594
595