public static EFormat GetEformatFromCompression(Enums.ETextureCompression compression) { switch (compression) { case Enums.ETextureCompression.TCM_QualityR: case Enums.ETextureCompression.TCM_QualityRG: return(EFormat.BC5_UNORM); case Enums.ETextureCompression.TCM_QualityColor: return(EFormat.BC7_UNORM); case Enums.ETextureCompression.TCM_DXTNoAlpha: case Enums.ETextureCompression.TCM_Normalmap: case Enums.ETextureCompression.TCM_Normals_DEPRECATED: return(EFormat.BC1_UNORM); case Enums.ETextureCompression.TCM_DXTAlphaLinear: case Enums.ETextureCompression.TCM_DXTAlpha: return(EFormat.BC3_UNORM); case Enums.ETextureCompression.TCM_None: return(EFormat.R8G8B8A8_UNORM); case Enums.ETextureCompression.TCM_RGBE: case Enums.ETextureCompression.TCM_Normals: case Enums.ETextureCompression.TCM_NormalsHigh_DEPRECATED: case Enums.ETextureCompression.TCM_NormalsHigh: case Enums.ETextureCompression.TCM_NormalsGloss_DEPRECATED: case Enums.ETextureCompression.TCM_NormalsGloss: case Enums.ETextureCompression.TCM_TileMap: case Enums.ETextureCompression.TCM_HalfHDR_Unsigned: case Enums.ETextureCompression.TCM_HalfHDR: case Enums.ETextureCompression.TCM_HalfHDR_Signed: case Enums.ETextureCompression.TCM_Max: throw new NotImplementedException(); default: throw new ArgumentOutOfRangeException(nameof(compression), compression, null); } }
/// <summary> /// Gets the redengine texture format from the compression method /// Used when creating a dds from an xbm /// TODO: TEST THIS!!! /// </summary> /// <param name="compression"></param> /// <returns></returns> public static EFormat GetEFormatFromCompression(Enums.ETextureCompression compression) { switch (compression) { // missing: 0xFD // missing: 0x0 //EFormat.R8G8B8A8_UNORM case Enums.ETextureCompression.TCM_None: return(EFormat.R8G8B8A8_UNORM); //0x07 // exception: characters\models\animals\goose\model\t_01__goose_d01.xbm has 0x07 but TCM_DXTAlpha case Enums.ETextureCompression.TCM_DXTNoAlpha: case Enums.ETextureCompression.TCM_Normals: return(EFormat.BC1_UNORM); //0x08 // exception: characters\models\animals\goose\model\t_01__goose_d01.xbm has 0x07 but TCM_DXTAlpha case Enums.ETextureCompression.TCM_DXTAlpha: case Enums.ETextureCompression.TCM_NormalsHigh: case Enums.ETextureCompression.TCM_NormalsGloss: return(EFormat.BC3_UNORM); case Enums.ETextureCompression.TCM_QualityColor: return(EFormat.BC7_UNORM); //0x0A // missing: 0x0D //EFormat.BC2_UNORM // used for not imported dds files in texturecache therefore will never come up here case Enums.ETextureCompression.TCM_QualityR: return(EFormat.BC4_UNORM); //0x0E case Enums.ETextureCompression.TCM_QualityRG: return(EFormat.BC5_UNORM); //0x0F case Enums.ETextureCompression.TCM_DXTAlphaLinear: // unused case Enums.ETextureCompression.TCM_RGBE: // unused default: throw new NotImplementedException(); } }
/// <summary> /// Generate DDSMetadata from a Redengine CBitmapTexture /// </summary> /// <param name="xbm"></param> /// <returns></returns> private static DDSMetadata GetDDSMetadata(CBitmapTexture xbm) { int residentMipIndex = xbm.ResidentMipIndex?.val ?? 0; int mipcount = xbm.Mipdata.elements.Count - residentMipIndex; uint width = xbm.Mipdata.elements[residentMipIndex].Width.val; uint height = xbm.Mipdata.elements[residentMipIndex].Height.val; Enums.ETextureCompression compression = xbm.Compression.WrappedEnum; var ddsformat = ImageUtility.GetEFormatFromCompression(compression); // TODO: TEST THIS if (ddsformat == EFormat.R8G8B8A8_UNORM) { Enums.ETextureRawFormat format = xbm.Format.WrappedEnum; switch (format) { case Enums.ETextureRawFormat.TRF_Grayscale: // only this is ever used break; case Enums.ETextureRawFormat.TRF_TrueColor: // this is set if format is NULL case Enums.ETextureRawFormat.TRF_HDR: case Enums.ETextureRawFormat.TRF_AlphaGrayscale: case Enums.ETextureRawFormat.TRF_HDRGrayscale: default: ddsformat = EFormat.R8G8B8A8_UNORM; //throw new Exception("Invalid texture format type! [" + format + "]"); break; } } return(new DDSMetadata(width, height, (uint)mipcount, ddsformat)); }
public static EFormat GetDXGIFormatFromXBM(Enums.ETextureCompression compression, Enums.ETextureRawFormat rawFormat) { switch (compression) { //TRF_Invalid, //TRF_TrueColor, // 24-bit Color, likely R8G8B8(A8) //TRF_DeepColor, // 30-bit Color, likely R10G10B10A2 //TRF_Grayscale, // Used alongside TCM_QualityColor etc. to indicate the texture is packed grayscale images? //TRF_HDRFloat, // 32-bit floating point, likely R32G32B32A32_FLOAT or R32G32B32_FLOAT //TRF_HDRHalf, // 16-bit floating point, likely R16G16B16A16_FLOAT //TRF_HDRFloatGrayscale, // Probably R16_FLOAT //TRF_Grayscale_Font, // ??? //TRF_R8G8, // Probably R8G8_UNORM or R8G8_UINT, try SNORM/SINT otherwise //TRF_R32UI, // Probably R32_UINT //TRF_AlphaGrayscale // Possibly A8_UNORM case Enums.ETextureCompression.TCM_QualityR: return(EFormat.BC4_UNORM); case Enums.ETextureCompression.TCM_QualityRG: case Enums.ETextureCompression.TCM_Normalmap: return(EFormat.BC5_UNORM); case Enums.ETextureCompression.TCM_QualityColor: return(EFormat.BC7_UNORM); case Enums.ETextureCompression.TCM_DXTNoAlpha: case Enums.ETextureCompression.TCM_Normals_DEPRECATED: return(EFormat.BC1_UNORM); case Enums.ETextureCompression.TCM_DXTAlphaLinear: case Enums.ETextureCompression.TCM_DXTAlpha: return(EFormat.BC3_UNORM); case Enums.ETextureCompression.TCM_None: { switch (rawFormat) { case Enums.ETextureRawFormat.TRF_Invalid: return(EFormat.R8G8B8A8_UNORM); case Enums.ETextureRawFormat.TRF_Grayscale_Font: throw new NotImplementedException(); case Enums.ETextureRawFormat.TRF_R32UI: //return EFormat.R32_UINT; throw new NotImplementedException(); case Enums.ETextureRawFormat.TRF_DeepColor: return(EFormat.R10G10B10A2_UNORM); case Enums.ETextureRawFormat.TRF_TrueColor: return(EFormat.R8G8B8A8_UNORM); case Enums.ETextureRawFormat.TRF_HDRFloat: return(EFormat.R32G32B32A32_FLOAT); case Enums.ETextureRawFormat.TRF_HDRHalf: return(EFormat.R16G16B16A16_FLOAT); case Enums.ETextureRawFormat.TRF_HDRFloatGrayscale: return(EFormat.R16_FLOAT); case Enums.ETextureRawFormat.TRF_R8G8: return(EFormat.R8G8_UNORM); case Enums.ETextureRawFormat.TRF_Grayscale: return(EFormat.R8_UINT); case Enums.ETextureRawFormat.TRF_AlphaGrayscale: return(EFormat.A8_UNORM); default: throw new ArgumentOutOfRangeException(nameof(rawFormat), rawFormat, null); } } case Enums.ETextureCompression.TCM_RGBE: case Enums.ETextureCompression.TCM_Normals: case Enums.ETextureCompression.TCM_NormalsHigh_DEPRECATED: case Enums.ETextureCompression.TCM_NormalsHigh: case Enums.ETextureCompression.TCM_NormalsGloss_DEPRECATED: case Enums.ETextureCompression.TCM_NormalsGloss: case Enums.ETextureCompression.TCM_TileMap: case Enums.ETextureCompression.TCM_HalfHDR_Unsigned: case Enums.ETextureCompression.TCM_HalfHDR: case Enums.ETextureCompression.TCM_HalfHDR_Signed: case Enums.ETextureCompression.TCM_Max: throw new NotImplementedException(); default: throw new ArgumentOutOfRangeException(nameof(compression), compression, null); } }
public static EFormat GetDXGIFormatFromXBM(Enums.ETextureCompression compression, Enums.ETextureRawFormat rawFormat) { switch (compression) { case Enums.ETextureCompression.TCM_QualityR: return(EFormat.BC4_UNORM); case Enums.ETextureCompression.TCM_QualityRG: case Enums.ETextureCompression.TCM_Normalmap: return(EFormat.BC5_UNORM); case Enums.ETextureCompression.TCM_QualityColor: return(EFormat.BC7_UNORM); case Enums.ETextureCompression.TCM_DXTNoAlpha: case Enums.ETextureCompression.TCM_Normals_DEPRECATED: return(EFormat.BC1_UNORM); case Enums.ETextureCompression.TCM_DXTAlphaLinear: case Enums.ETextureCompression.TCM_DXTAlpha: return(EFormat.BC3_UNORM); case Enums.ETextureCompression.TCM_None: { switch (rawFormat) { case Enums.ETextureRawFormat.TRF_Invalid: return(EFormat.R8G8B8A8_UNORM); case Enums.ETextureRawFormat.TRF_Grayscale_Font: throw new NotImplementedException(); case Enums.ETextureRawFormat.TRF_R32UI: //return EFormat.R32_UINT; throw new NotImplementedException(); case Enums.ETextureRawFormat.TRF_DeepColor: return(EFormat.R10G10B10A2_UNORM); case Enums.ETextureRawFormat.TRF_TrueColor: return(EFormat.R8G8B8A8_UNORM); case Enums.ETextureRawFormat.TRF_HDRFloat: return(EFormat.R32G32B32A32_FLOAT); case Enums.ETextureRawFormat.TRF_HDRHalf: return(EFormat.R16G16B16A16_FLOAT); case Enums.ETextureRawFormat.TRF_HDRFloatGrayscale: return(EFormat.R16_FLOAT); case Enums.ETextureRawFormat.TRF_R8G8: return(EFormat.R8G8_UNORM); case Enums.ETextureRawFormat.TRF_Grayscale: return(EFormat.R8_UINT); case Enums.ETextureRawFormat.TRF_AlphaGrayscale: return(EFormat.A8_UNORM); default: throw new ArgumentOutOfRangeException(nameof(rawFormat), rawFormat, null); } } case Enums.ETextureCompression.TCM_RGBE: case Enums.ETextureCompression.TCM_Normals: case Enums.ETextureCompression.TCM_NormalsHigh_DEPRECATED: case Enums.ETextureCompression.TCM_NormalsHigh: case Enums.ETextureCompression.TCM_NormalsGloss_DEPRECATED: case Enums.ETextureCompression.TCM_NormalsGloss: case Enums.ETextureCompression.TCM_TileMap: case Enums.ETextureCompression.TCM_HalfHDR_Unsigned: case Enums.ETextureCompression.TCM_HalfHDR: case Enums.ETextureCompression.TCM_HalfHDR_Signed: case Enums.ETextureCompression.TCM_Max: throw new NotImplementedException(); default: throw new ArgumentOutOfRangeException(nameof(compression), compression, null); } }
private int UncookSingleInner(MemoryMappedFile mmf, ulong hash, DirectoryInfo outDir, EUncookExtension uncookext = EUncookExtension.tga) { var uncooksuccess = false; var(file, buffers) = GetFileData(hash, mmf); if (!Files.ContainsKey(hash)) { return(-1); } string name = Files[hash].NameStr; // checks var outfile = new FileInfo(Path.Combine(outDir.FullName, $"{name}")); if (outfile.Directory == null) { return(-1); } if (buffers.Count > 1) { return(-1); //TODO: can that happen? } var cr2w = new CR2WFile(); using var ms = new MemoryStream(file); using var br = new BinaryReader(ms); cr2w.ReadImportsAndBuffers(br); if (cr2w.StringDictionary[1] != "CBitmapTexture") { return(-1); } br.BaseStream.Seek(0, SeekOrigin.Begin); var result = cr2w.Read(br); if (result != EFileReadErrorCodes.NoError) { return(-1); } if (!(cr2w.Chunks.FirstOrDefault()?.data is CBitmapTexture xbm) || !(cr2w.Chunks[1]?.data is rendRenderTextureBlobPC blob)) { return(-1); } // write buffers foreach (var b in buffers) { #region textures // create dds header var newpath = Path.ChangeExtension(outfile.FullName, "dds"); try { var width = blob.Header.SizeInfo.Width.val; var height = blob.Header.SizeInfo.Height.val; var mips = blob.Header.TextureInfo.MipCount.val; var slicecount = blob.Header.TextureInfo.SliceCount.val; var alignment = blob.Header.TextureInfo.DataAlignment.val; Enums.ETextureRawFormat rawfmt = Enums.ETextureRawFormat.TRF_Invalid; if (xbm.Setup.RawFormat?.WrappedEnum != null) { rawfmt = xbm.Setup.RawFormat.WrappedEnum; } else { } Enums.ETextureCompression compression = Enums.ETextureCompression.TCM_None; if (xbm.Setup.Compression?.WrappedEnum != null) { compression = xbm.Setup.Compression.WrappedEnum; } else { } var texformat = CommonFunctions.GetDXGIFormatFromXBM(compression, rawfmt); Directory.CreateDirectory(outfile.Directory.FullName); using (var stream = new FileStream($"{newpath}", FileMode.Create, FileAccess.Write)) { DDSUtils.GenerateAndWriteHeader(stream, new DDSMetadata(width, height, mips, texformat, alignment, false, slicecount, true)); var buffer = b; stream.Write(buffer); } // success uncooksuccess = true; } catch { uncooksuccess = false; continue; } // convert to texture if (uncookext != EUncookExtension.dds) { try { var di = new FileInfo(outfile.FullName).Directory; TexconvWrapper.Convert(di.FullName, $"{newpath}", uncookext); } catch (Exception e) { // silent } } #endregion } return(uncooksuccess ? 1 : 0); }