Created
January 26, 2021 18:44
-
-
Save Frooxius/ced29bc9f326161841cd915c4194278f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.IO; | |
using BaseX; | |
namespace CodeX | |
{ | |
public static class TextureVariantGenerator | |
{ | |
public static List<ComputedVariantResult> GenerateVariants(string file, Texture2DVariantDescriptor variantDescriptor, int maxThreads = -1, | |
VariantGeneratedHandler variantGenerated = null, Predicate<string> variantFilter = null) | |
{ | |
var results = new List<ComputedVariantResult>(); | |
// generate chain | |
var variants = variantDescriptor.GenerateCloudChain(); | |
var bitmap = Bitmap2D.Load(file, false, false); | |
switch(variantDescriptor.TextureCompression) | |
{ | |
case TextureCompression.RawRGBA: | |
if (bitmap.Format != TextureFormat.RGBA32 && bitmap.Format != TextureFormat.RGB24 && bitmap.Format != TextureFormat.ARGB32) | |
bitmap = bitmap.ConvertTo(TextureFormat.RGBA32); | |
break; | |
case TextureCompression.BC3nm_Crunched: | |
case TextureCompression.BC3nm_LZMA: | |
if (!bitmap.Format.SupportsAlpha()) | |
bitmap = bitmap.ConvertTo(TextureFormat.RGBA32); | |
bitmap.PackNormalMap(); | |
break; | |
} | |
var bitmaps = new List<Bitmap2D>(); | |
foreach (var v in variants) | |
{ | |
bitmap = bitmap.GetRescaled(new int2(v.Width, v.Height), v.MipMaps, false, v.Filtering); | |
bitmaps.Add(bitmap); | |
} | |
// generate bitmap variants from the end (smallest mipmap), since this is the order in which they're loaded as well | |
for (int i = variants.Count - 1; i >= 0; i--) | |
{ | |
var v = variants[i]; | |
var b = bitmaps[i]; | |
if (variantFilter != null && !variantFilter(v.VariantIdentifier)) | |
continue; | |
// use GUID for the filename, the actual temp filenames have problem on Android with Unity | |
string generatedFile = Path.Combine(AssetVariantHelper.TempFolder ?? Path.GetTempPath(), Guid.NewGuid().ToString()); | |
switch (v.TextureCompression) | |
{ | |
case TextureCompression.BC1_Crunched: | |
if (!b.CrunchCompress(generatedFile, TextureFormat.BC1, false, maxThreads)) | |
throw new Exception($"Could not compress with BC1. Bitmap: {b.ToString()}"); | |
break; | |
case TextureCompression.BC3_Crunched: | |
if(!b.CrunchCompress(generatedFile, TextureFormat.BC3, false, maxThreads)) | |
throw new Exception($"Could not compress with BC3. Bitmap: {b.ToString()}"); | |
break; | |
case TextureCompression.BC3nm_Crunched: | |
if (!b.CrunchCompress(generatedFile, TextureFormat.BC3, true, maxThreads)) | |
throw new Exception($"Could not compress with BC3. Bitmap: {b.ToString()}"); | |
break; | |
case TextureCompression.ETC2_RGB_Crunched: | |
if(!b.CrunchCompress(generatedFile, TextureFormat.ETC2_RGB, false, maxThreads)) | |
throw new Exception($"Could not compress with ETC2_RGB. Bitmap: {b.ToString()}"); | |
break; | |
case TextureCompression.ETC2_RGBA8_Crunched: | |
if(!b.CrunchCompress(generatedFile, TextureFormat.ETC2_RGBA8, false, maxThreads)) | |
throw new Exception($"Could not compress with ETC2_RGBA8. Bitmap: {b.ToString()}"); | |
break; | |
case TextureCompression.BC1_LZMA: | |
case TextureCompression.BC3_LZMA: | |
case TextureCompression.BC3nm_LZMA: | |
case TextureCompression.ETC2_RGB_LZMA: | |
case TextureCompression.ETC2_RGBA8_LZMA: | |
case TextureCompression.BC4_LZMA: | |
case TextureCompression.BC6H_LZMA: | |
case TextureCompression.BC7_LZMA: | |
case TextureCompression.ASTC_4x4_LZMA: | |
case TextureCompression.ASTC_5x5_LZMA: | |
case TextureCompression.ASTC_6x6_LZMA: | |
case TextureCompression.ASTC_8x8_LZMA: | |
case TextureCompression.ASTC_10x10_LZMA: | |
case TextureCompression.ASTC_12x12_LZMA: | |
var targetFormat = v.TextureCompression.ToFormat(); | |
if(Bitmap2D.SupportsBlockCompression(targetFormat)) | |
{ | |
var compressed = b.BlockCompress(targetFormat, v.CompressionQuality * 0.01f, maxThreads); | |
compressed.SaveRaw(generatedFile); | |
} | |
else | |
generatedFile = null; | |
break; | |
case TextureCompression.RawRGBA: | |
generatedFile += ".webp"; | |
b.Save(generatedFile, 200); | |
break; | |
default: | |
throw new Exception("Invalid texture compression: " + v.TextureCompression); | |
} | |
var result = new ComputedVariantResult(v.VariantIdentifier, generatedFile); | |
// null it immediatelly, allowing GC to free it up if possible | |
bitmaps[i] = null; | |
results.Add(result); | |
// raise event for the generated variant immediatelly so any process listening to this can use it up immediatelly | |
// while others are being generated | |
variantGenerated?.Invoke(result); | |
} | |
return results; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment